Передать уникальную конфигурацию в контейнер без дистрибутива

Я запускаю StatefulSet, где каждая реплика требует своей уникальной конфигурации. Для этого я сейчас использую конфигурацию с двумя контейнерами на под:

  1. АнinitContainerподготавливает конфигурацию и сохраняет ее на общий том
  2. Основной контейнер использует конфигурацию, выводя содержимое общего тома и передавая его программе в виде флагов CLI.
      apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-app
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels: 
      app.kubernetes.io/name: my-app
  serviceName: my-app
  template:
    metadata:
      labels:
        app.kubernetes.io/name: my-app
    spec:
      initContainers:
        - name: generate-config
          image: myjqimage:latest
          command: [ "/bin/sh" ]
          args:
            - -c
            - |
              set -eu -o pipefail
              POD_INDEX="${HOSTNAME##*-}"
              # A configuration is stored as a JSON array in a Secret
              # E.g., [{"param1":"string1","param2":"string2"}]
              echo "$MY_APP_CONFIG" | jq -rc --arg i "$POD_INDEX" '.[$i|tonumber-1].param1' > /config/param1
              echo "$MY_APP_CONFIG" | jq -rc --arg i "$POD_INDEX" '.[$i|tonumber-1].param2' > /config/param2
          env:
            - name: MY_APP_CONFIG
              valueFrom:
                secretKeyRef:
                  name: my-app
                  key: config
          volumeMounts:
          - name: configs
            mountPath: "/config"
      containers:
        - name: my-app
          image: myapp:latest
          command:
            - /bin/sh
          args:
            - -c
            - |
              /myapp --param1 $(cat /config/param1) --param2 $(cat /config/param2)
          volumeMounts:
          - name: configs
            mountPath: "/config"
      volumes:
      - name: configs
        emptyDir:
          medium: "Memory"
---
apiVersion: v1
kind: Secret
metadata:
  name: my-app
  namespace: default
  labels:
    app.kubernetes.io/name: my-app
type: Opaque
data:
  config: W3sicGFyYW0xIjoic3RyaW5nMSIsInBhcmFtMiI6InN0cmluZzIifV0=

Теперь я хочу переключиться на distroless для своего основного контейнера. Образы Distroless содержат только необходимые зависимости для запуска программы (в моем случае это glibc). И отсутствует оболочка. Итак, если раньше я мог выполнитьcatи вывести содержимое файла. Теперь я немного застрял.

Теперь вместо того, чтобы читать содержимое из файла, я должен передать флаги CLI, определенные как переменные среды. Что-то вроде этого:

      containers:
  - name: my-app
    image: myapp:latest
    command: ["/myapp", "--param1", "$(PARAM1)", "--param2", "$(PARAM2)"]
    env:
    - name: PARAM1
      value: somevalue1
    - name: PARAM2
      value: somevalue2

Опять же, каждый Pod в StatefulSet должен иметь уникальную конфигурацию. то есть,PARAM1иPARAM2должен быть уникальным для всех подов в StatefulSet. Как мне этого добиться?

Варианты, которые я рассматривал:

  • Использование контейнеров отладки -- новая функция K8s. Каким-то образом используйте его для редактирования конфигурации работающего контейнера во время выполнения и внедрения необходимых переменных. Но эта функция только что стала бета-версией версии 1.23. И я не хочу изменять свой StatefulSet во время выполнения, поскольку я использую подход GitOps для хранения конфигурации в Git. Это, вероятно, вызовет непрерывный дрейф конфигурации
  • Использование задания для изменения конфигурации во время выполнения. Опять же, выглядит очень некрасиво и нарушает принцип GitOps
  • С использованиемshareProcessNamespace. Не уверен, что это может помочь, но, возможно, я смогу каким-то образом ввести переменные среды из initContainer.

Ограничения:

  • Приложение поддерживает только конфигурацию, предоставленную с помощью флагов CLI. Нет переменных окружения, нет загрузки конфига из файла

0 ответов

Другие вопросы по тегам