将值从 initContainers 传递到容器规范

San*_*kar 4 kubernetes kubernetes-helm

我有一个 kubernetes 部署,其规范如下,通过 helm 3 安装。

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 }}
Run Code Online (Sandbox Code Playgroud)

我需要将该discoveryUrl值作为 helm 值传递,它是nginx-ingress我通过不同 helm 图表部署的 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}
Run Code Online (Sandbox Code Playgroud)

然而,这工作正常,现在而不是这两个helm3 install不过,这工作正常,现在我想要安装一个 helm3,而

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

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

San*_*kar 5

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

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
Run Code Online (Sandbox Code Playgroud)