Kubernetes NGINX Ingress 控制器中不同yml定义如何添加规则

88次阅读
没有评论

问题描述

在使用 Kubernetes 集群时,我正在尝试实现一个使用 NGINX Ingress 的扇出模式的方案,该方案可以将流量路由到多个不同的主机和路径上的不同微服务。每个微服务的代码都托管在它们自己的 Git 仓库中,包括部署该服务的 pods(Deployment)和相应的服务(Service)的 Kubernetes 定义 yml 文件。

考虑到将会有一个单一的 Ingress 将流量路由到所有不同的服务上,根据(约定或行业标准),规则定义文件应该存储在哪里?我希望将与单个微服务相关的 Ingress 规则存储在与代码一起的 Git 仓库中。我并不特别想为 Ingress 单独创建一个 Git 仓库。

是否可以仅在文件中定义 Ingress 的规则的子集,然后将其“追加”到规则列表中,而不是覆盖它们?

例如,我能否有以下两个不同的定义,创建一个具有两个规则的单个 Ingress(基于具有相同名称的规则):

foo-ingress-rules.yml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  tls:
    - hosts:
      - foo.bar.com
      secretName: tls-secret
  rules:
    - host: foo.bar.com
      http:
        paths:
          - path: /
            backend:
              serviceName: foo-web-svc
              servicePort: 80
          - path: /api
            backend:
              serviceName: foo-rest-svc
              servicePort: 80

baz-ingress-rules.yml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  tls:
    - hosts:
      - baz.bar.com
      secretName: tls-secret
  rules:
    - host: baz.bar.com
      http:
        paths:
          - path: /
            backend:
              serviceName: baz-web-svc
              servicePort: 80
          - path: /api
            backend:
              serviceName: baz-rest-svc
              servicePort: 80

解决方案

合并规则到单个 Ingress 文件

您可以通过将这两个规则定义文件转换为 JSON,然后使用工具(如 jq)将它们合并成单个 Ingress 文件。

foo.json

{
  "apiVersion": "extensions/v1beta1",
  "kind": "Ingress",
  "metadata": {
    "name": "nginx-ingress"
  },
  "spec": {
    "tls": [
      {
        "hosts": ["foo.bar.com"],
        "secretName": "tls-secret"
      }
    ],
    "rules": [
      {
        "host": "foo.bar.com",
        "http": {
          "paths": [
            {
              "path": "/",
              "backend": {
                "serviceName": "foo-web-svc",
                "servicePort": 80
              }
            },
            {
              "path": "/api",
              "backend": {
                "serviceName": "foo-rest-svc",
                "servicePort": 80
              }
            }
          ]
        }
      }
    ]
  }
}

baz.json

{
  "apiVersion": "extensions/v1beta1",
  "kind": "Ingress",
  "metadata": {
    "name": "nginx-ingress"
  },
  "spec": {
    "tls": [
      {
        "hosts": ["baz.bar.com"],
        "secretName": "tls-secret"
      }
    ],
    "rules": [
      {
        "host": "baz.bar.com",
        "http": {
          "paths": [
            {
              "path": "/",
              "backend": {
                "serviceName": "baz-web-svc",
                "servicePort": 80
              }
            },
            {
              "path": "/api",
              "backend": {
                "serviceName": "baz-rest-svc",
                "servicePort": 80
              }
            }
          ]
        }
      }
    ]
  }
}

然后,您可以使用 jq 来合并这些规则到单个 Ingress 文件:

jq 'reduce inputs as $i (.; .spec.rules += $i.spec.rules)' foo.json baz.json > combined-ingress.json

这将生成一个名为 combined-ingress.json 的文件,其中包含了这两个规则的组合。

注意事项

请注意,尽管 YAML 更为常见,但 JSON 完全适用于 Kubernetes API。合并规则时要确保规则名称和其他相关信息不会发生冲突。

总之,您可以使用工具来合并规则,并将这个组合后的规则文件应用于 Kubernetes 集群,以实现您所需的 Ingress 规则。

希望这个解决方案对您有所帮助!如果您对此有更多疑问,请随时提问。

正文完