Передача значений из initContainers в спецификацию контейнера

У меня есть развертывание 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 }}

Мне нужно передать значение discoveryUrl в качестве значения руля, которое является общедоступным IP-адресом модуля nginx-ingress, который я развертываю с помощью другой диаграммы руля. Я устанавливаю вышеуказанное развертывание, как показано ниже:

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 install я хочу иметь одну установку helm3, в которой должны быть созданы как развертывание nginx-ingress, так и развертывание привратника.

Я понимаю, что в initContainer из my-gatekeeper-image мы можем получить IP-адрес nginx-ingress, но я не могу понять, как установить его в качестве переменной среды или передать в спецификацию контейнера.

Есть несколько вопросов о stackoverflow, в которых упоминается, что мы можем создать постоянный том или секрет для достижения этой цели, но я не уверен, как это будет работать, если нам придется их удалить. Я не хочу создавать никаких дополнительных объектов и поддерживать их жизненный цикл.


person Sankar    schedule 08.04.2020    source источник


Ответы (2)


Это невозможно сделать без монтирования постоянного тома. Но создание постоянного тома может поддерживаться только хранилищем в памяти, а не блочным устройством хранения. Таким образом, нам не нужно заниматься дополнительным управлением жизненным циклом. Способ добиться этого:

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
person Sankar    schedule 17.04.2020

Использование контейнеров инициализации действительно является допустимым решением, но вы должны знать, что, поступая таким образом, вы усложняете свое развертывание.

Это связано с тем, что вам также потребуется создать учетную запись службы с разрешениями, чтобы иметь возможность читать объекты службы изнутри контейнера инициализации. Затем, имея IP-адрес, вы не можете просто установить переменную env для контейнера-привратника без воссоздания модуля, поэтому вам нужно будет сохранить IP, например. в общий файл и читать его при запуске гейткипера.

В качестве альтернативы вы можете зарезервировать IP-адрес, если предоставленное вами облако поддерживает эту функцию, и использовать этот статический IP-адрес при развертывании службы nginx:

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

Дайте мне знать, если у вас возникнут вопросы или что-то нуждается в разъяснении.

person Matt    schedule 08.04.2020
comment
Нет. Использование статического IP невозможно по разным причинам. Кроме того, помимо IP-адреса мне нужно настроить еще несколько вещей. - person Sankar; 08.04.2020