【问题标题】:Passing values from initContainers to container spec将值从 initContainers 传递到容器规范
【发布时间】:2020-04-17 12:51:53
【问题描述】:

我有一个通过 helm 3 安装的具有以下规范的 kubernetes 部署。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gatekeeper
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: gatekeeper
          image: my-gatekeeper-image:some-sha
          args:
            - --listen=0.0.0.0:80
            - --client-id=gk-client
            - --discovery-url={{ .Values.discoveryUrl }}

我需要将 discoveryUrl 值作为 helm 值传递,这是我通过不同的 helm 图表部署的 nginx-ingress pod 的公共 IP 地址。我安装上述部署如下:

helm3 install my-nginx-ingress-chart
INGRESS_IP=$(kubectl get svc -lapp=nginx-ingress -o=jsonpath='{.items[].status.loadBalancer.ingress[].ip}')
helm3 install my-gatekeeper-chart --set discovery_url=${INGRESS_IP}

这很好用,但是,现在我想要一个单独的 helm3 安装,而不是这两个 helm3 install,应该在其中创建 nginx-ingress 和网关守卫部署。

我知道在my-gatekeeper-imageinitContainer 中,我们可以获得 nginx-ingress ip 地址,但我无法理解如何将其设置为环境变量或传递给容器规范。

有一些 stackoverflow 问题提到我们可以创建一个持久卷或密钥来实现这一点,但我不确定如果我们必须删除它们会如何工作。我不想创建任何额外的对象并维护它们的生命周期。

【问题讨论】:

    标签: kubernetes kubernetes-helm


    【解决方案1】:

    如果不安装持久卷,则无法执行此操作。但是持久卷的创建可以仅由内存存储支持,而不是块存储设备。这样,我们就不必进行任何额外的生命周期管理。实现的方法是:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: gatekeeper
    data:
      gatekeeper.sh: |-
        #!/usr/bin/env bash
        set -e
    
        INGRESS_IP=$(kubectl get svc -lapp=nginx-ingress -o=jsonpath='{.items[].status.loadBalancer.ingress[].name}')
        # Do other validations/cleanup
        echo $INGRESS_IP > /opt/gkconf/discovery_url;
        exit 0
    
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: gatekeeper
      labels:
        app: gatekeeper
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: gatekeeper
      template:
        metadata:
          name: gatekeeper
          labels:
            app: gatekeeper
        spec:
          initContainers:
            - name: gkinit
              command: [ "/opt/gk-init.sh" ]
              image: 'bitnami/kubectl:1.12'
              volumeMounts:
                - mountPath: /opt/gkconf
                  name: gkconf
                - mountPath: /opt/gk-init.sh
                  name: gatekeeper
                  subPath: gatekeeper.sh
                  readOnly: false
          containers:
            - name: gatekeeper
              image: my-gatekeeper-image:some-sha
              # ENTRYPOINT of above image should read the
              # file /opt/gkconf/discovery_url and then launch
              # the actual gatekeeper binary
              imagePullPolicy: Always
              ports:
                - containerPort: 80
                  protocol: TCP
              volumeMounts:
                - mountPath: /opt/gkconf
                  name: gkconf
          volumes:
            - name: gkconf
              emptyDir:
                medium: Memory
            - name: gatekeeper
              configMap:
                name: gatekeeper
                defaultMode: 0555
    

    【讨论】:

      【解决方案2】:

      使用 init 容器确实是一种有效的解决方案,但您需要注意这样做会增加部署的复杂性。

      这是因为您还需要创建具有权限的服务帐户才能从 init 容器内部读取服务对象。然后,当拥有 IP 时,您不能只为网守容器设置 env 变量而不重新创建 pod,因此您需要保存 IP,例如共享文件并在启动 Gatekeeper 时从中读取。

      或者,如果您的云提供支持此功能,您可以保留 IP 地址并在部署 nginx 服务时使用此静态 IP:

      apiVersion: v1
      kind: Service
      [...]
        type: LoadBalancer
        loadBalancerIP: "YOUR.IP.ADDRESS.HERE"
      

      如果您有任何问题或需要澄清,请告诉我。

      【讨论】:

      • 没有。由于各种原因,无法使用静态 IP。此外,除了 IP 地址之外,我还有其他一些东西要配置。
      猜你喜欢
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-06
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      相关资源
      最近更新 更多