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

flo*_*olu 3 kubernetes kubectl kubernetes-ingress configmap nginx-ingress

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

apiVersion: v1
kind: ConfigMap
metadata:
  name: config
data:
  MY_DOMAIN: mydomain.com
Run Code Online (Sandbox Code Playgroud)

我的目标是使用MY_DOMAINIngress 配置中的变量

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

Run Code Online (Sandbox Code Playgroud)

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

TJ *_*man 5

configMapRefsecretMapRefenvFromvalueFrom功能仅适用于环境变量,这意味着它们不能在此上下文中使用。自 1.18.0 起,所需的功能在 vanilla Kubernetes 中不可用。

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

实现这一目标的另一种方法是为什么 Kustomize。这是我个人推荐的。Kustomize 就像 Helm 一样,它处理从通用清单生成定制清单,但它不是通过模板来实现的。Kustomize 的独特之处在于它在运行时在YAMLJSON文件之间执行合并补丁。这些补丁被称为覆盖,因此它通常被称为覆盖引擎,以区别于传统的模板引擎。原因是 Kustomize 可以与基础覆盖的递归目录树一起使用. 这使得它对于可能需要从样板通用示例生成数十、数百或数千个清单的环境更具可扩展性。

那么我们如何做到这一点呢?好吧,使用 Kustomize,您将首先定义一个kustomization.yml文件。您将在其中定义您的资源。在这种情况下,myingress

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
    - myingress.yml
Run Code Online (Sandbox Code Playgroud)

因此,创建一个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
Run Code Online (Sandbox Code Playgroud)

现在我们需要定义我们的第一个叠加层。我们将创建两个不同的域配置来提供覆盖如何工作的示例。首先创建一个./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'
Run Code Online (Sandbox Code Playgroud)

此时我们已经在这个文件中定义了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
Run Code Online (Sandbox Code Playgroud)

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

  • Kubectl 构建: kubectl kustomize ./example/overlays/domain_a
  • 自定义构建: kustomize build ./example/overlays/domain_a

运行上述构建命令之一并查看终端中生成的 STDOUT。请注意它如何包含两个文件,myingress以及config? 并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
Run Code Online (Sandbox Code Playgroud)

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

kustomize build ./example/overlays/domain_a
kustomize build ./example/overlays/domain_b
Run Code Online (Sandbox Code Playgroud)

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

kubectl apply -k ./example/overlays/domain_a
kubectl apply -k ./example/overlays/domain_b
Run Code Online (Sandbox Code Playgroud)

这真的只是 Kustomize 的开始。正如您在查看文件中每个叠加层的configMapGenerator字段后可能已经猜到的那样kustomization.yml,Kustomize 具有很多功能。它可以为您的所有资源添加标签,它可以覆盖它们的命名空间或容器图像信息等。

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