Kubectl - 如何从配置变量中读取入口主机?

Kubectl - How to Read Ingress Hosts from Config Variables?

我有一个 ConfigMap,我的域有一个变量:

apiVersion: v1
kind: ConfigMap
metadata:
  name: config
data:
  MY_DOMAIN: mydomain.com

我的目标是在 Ingress 配置中使用 MY_DOMAIN 变量

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myingress
spec:
  tls:
    - hosts:
⮕       - config.MY_DOMAIN
      secretName: mytls
  rules:
⮕   - host: config.MY_DOMAIN
      http:
        paths:
          - backend:
              serviceName: myservice
              servicePort: 3000

但显然上面的配置是无效的。那么如何实现呢?

envFrom and valueFrom 函数的 configMapRefsecretMapRef 仅适用于环境变量,这意味着它们不能在此上下文中使用。从 1.18.0 开始,所需的功能在 vanilla Kubernetes 中不可用。

不过,这是可以做到的。 Helm and Kustomize 可能是实现此目的的两种最佳方法,但也可以使用 sedawk 来完成。 Helm 是 Kubernetes 清单的模板引擎。意思是,您创建通用清单,通过变量模板化您想要的清单与通用清单之间的增量,然后提供一个变量文件。然后,在运行时,变量文件中的变量会自动为您注入到模板中。

实现此目的的另一种方法是 Kustomize。这是我个人推荐的。 Kustomize 与 Helm 类似,它处理从通用清单生成自定义清单,但它不是通过模板来实现的。 Kustomize 的独特之处在于它在 YAML or JSON files at runtime. These patches are referred to as Overlays so it is often referred to as an overlay engine to differentiate itself from traditional templating engines. Reason being Kustomize can be used with recursive directory trees of bases and overlays 之间执行合并补丁。这使得它对于可能需要从样板通用示例生成数十、数百或数千个清单的环境更具可扩展性。

那么我们该怎么做呢?那么,使用 Kustomize,您首先要定义一个 kustomization.yml 文件。您将在其中定义您的资源。在这种情况下,myingress:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
    - myingress.yml

因此创建一个example 目录并在其中创建一个名为base 的子目录。创建 ./example/base/kustomization.yml 并使用上面的 kustomization 填充它。现在创建一个 ./example/base/myingress.yml 文件并用上面给出的示例 myingress 文件填充它。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myingress
spec:
  tls:
    - hosts:
      - config.MY_DOMAIN
      secretName: mytls
  rules:
     - host: config.MY_DOMAIN
        http:
          paths:
            - backend:
                serviceName: myservice
                servicePort: 3000

现在我们需要定义第一个叠加层。我们将创建两个不同的域配置,以提供覆盖如何工作的示例。首先创建一个./example/overlays/domain-a目录,并在其中创建一个kustomization.yml文件,内容如下:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
    - ../../../base/

patchesStrategicMerge:
    - ing_patch.yml

configMapGenerator:
    - name: config_a
      literals:
        - MY_DOMAIN='domain_a'

此时我们已经在这个文件中定义了ing_patch.ymlconfig_aing_patch.yml 将作为我们的入口补丁,config_a 将作为我们的 configMap。但是,在这种情况下,我们将利用称为 configMapGenerator 的 Kustomize 功能,而不是为单个文字 key:value 对手动创建 configMap 文件。

现在我们已经完成了这个,我们必须真正制作我们的第一个补丁!由于入口中的增量非常小,因此并不难。创建 ./example/overlays/domain_a/ing_patch.yml 并填充它:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myingress
spec:
  tls:
    - hosts:
      - domain.a.com
  rules:
     - host: domain.a.com

完美,您已经创建了第一个叠加层。现在您可以使用 kubectlkustomize 生成结果清单以应用于 Kubernetes API 服务器。

  • Kubectl 构建: kubectl kustomize ./example/overlays/domain_a
  • Kustomize 构建: kustomize build ./example/overlays/domain_a

运行 以上构建命令之一,并查看在您的终端中生成的 STDOUT。注意它是如何包含两个文件的,myingressconfig?并且 myingress 包含覆盖补丁中存在的域配置?

所以,此时您可能会问。如果 Kubectl 默认支持这些功能,为什么会存在 Kustomize?好吧,Kustomize 最初是作为一个外部项目开始的,而且 Kustomize 二进制文件通常 运行 比 Kubectl 中可用的版本更新。

下一步是创建第二个叠加层。所以继续 cp 你的第一个叠加层:cp -r ./example/overlays/domain_a ./example/overlays/domain_b.

既然你已经完成了,请在文本编辑器中打开 ./example/overlays/domain_b/ing_patch.yml 并将内容更改为如下所示:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myingress
spec:
  tls:
    - hosts:
      - domain.b.com
  rules:
     - host: domain.b.com

保存文件,然后构建两个单独的叠加层:

kustomize build ./example/overlays/domain_a
kustomize build ./example/overlays/domain_b

注意到每个生成的 STDOUT 流如何根据 Overlay 目录中存在的补丁而变化吗?您可以通过使您的基础成为其他基础的叠加层来继续抽象此模式。或者通过使您的叠加层成为其他叠加层的基础。这样做可以让您以极其强大和高效的方式扩展该项目。如果您愿意,将它们应用到您的 API 服务器:

kubectl apply -k ./example/overlays/domain_a
kubectl apply -k ./example/overlays/domain_b

这真的只是 Kustomize 的开始。正如您在看到每个叠加层的 kustomization.yml 文件中的 configMapGenerator 字段后可能已经猜到的那样,Kustomize 内置了很多功能。它可以添加 labels to all of your resources, it can override their namespaces or container image 信息等

希望对您有所帮助。如果您有任何其他问题,请告诉我。