Импортируйте данные в конфигурационную карту из секрета kubernetes

Я использую kubernetes ConfigMap, который содержит конфигурации базы данных для приложения, и есть секрет, который имеет пароль базы данных. Мне нужно использовать этот секрет в ConfigMap, поэтому, когда я пытаюсь добавить переменную среды в ConfigMap и указать значение в развертывании модуля из секрета, я не могу подключиться к mysql с паролем, так как значения в ConfigMap заняли точная строка переменной.

apiVersion: v1
kind: ConfigMap
metadata:
  name: config
data:
  APP_CONFIG: |
    port: 8080
    databases:
      default:
        connector: mysql
        host: "mysql"
        port: "3306"
        user: "root"
        password: "$DB_PASSWORD"

и развертывание.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
  labels:
    app: backend
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: app
        image: simple-app-image
        ports:
          - name: "8080"
            containerPort: 8080
        env:
          - name: APP_CONFIG
            valueFrom:
              configMapKeyRef:
                name: config
                key: APP_CONFIG
          - name: DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: "mysql-secret"
                key: "mysql-root-password"

Примечание: секрет существует, и я могу получить значение "mysql-root-password" и использовать для входа в базу данных

4 ответа

Kubernetes не может сделать эту замену для вас, вы должны сделать это с shell в точке входа контейнера.

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

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
  labels:
    app: backend
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: app
        image: simple-app-image
        command:
          - /bin/bash
          - -c
        args:
          - "NEW_APP_CONFIG=$(echo $APP_CONFIG | envsubst) && echo $NEW_APP_CONFIG && <INSERT IMAGE ENTRYPOINT HERE>"
        ports:
          - name: "app"
            containerPort: 8080
        env:
          - name: APP_CONFIG
            valueFrom:
              configMapKeyRef:
                name: config
                key: APP_CONFIG
          - name: DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: "mysql-secret"
                key: "mysql-root-password"

Вы можете сделать что-то подобное в HELM:

      {{- define "getValueFromSecret" }}
{{- $len := (default 16 .Length) | int -}}
{{- $obj := (lookup "v1" "Secret" .Namespace .Name).data -}}
{{- if $obj }}
{{- index $obj .Key | b64dec -}}
{{- else -}}
{{- randAlphaNum $len -}}
{{- end -}}
{{- end }}

Затем вы можете сделать что-то вроде этого в configmap:

      {{- include "getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" "<secret_name>" "Length" 10 "Key" "<key>")  -}}

Секрет должен уже присутствовать при развертывании; или вы можете контролировать порядок развертывания с помощью https://github.com/vmware-tanzu/carvel-kapp-controller

У меня сработало что-то вроде этого (для простоты я поделился только соответствующим фрагментом примера) :

пример-configmap

      data:
  example.yaml: |
    user: ${USER}

пример-секрет

      data:
  user: <some base64 encoded value>

пример развертывания

      containers:
  - name: example-container
    image: example-image
    env:
      - name: USER
        valueFrom:
          secretKeyRef:
            key: user
            name: example-secret
    volumeMounts:
      - mountPath: /some/path/in/container
        name: config
        readOnly: true
volumes:  
  - name: config
    configMap:
      name: example-configmap

Пояснение: В приведенном выше примере, скажем,
мне нужно подставить в конфигурационную карту декодированное значение ключа из секрета.
Затем, как это было сделано выше, в определении развертывания/модуля мне нужно:

  • смонтируйте конфигурационную карту как том (volumes.configMap) подvolumeMountsв контейнере и
  • раскрыть секретное значение как переменную среды (env.valueFrom.secretKeyRef) в контейнере.

Результат :${USER}в карте конфигурации будет заменено декодированным значениемuser:ключ от секрета.

Причина: Это связано с тем, что карта конфигурации теперь смонтирована как файл по адресуmountPathвнутри контейнера и, таким образом, может получить доступ к любой переменной env, открытой внутри контейнера.

Примечание. Пространство имен для развертывания/модуля, карты конфигурации и секрета должно быть одинаковым.

Я бы изменил весь configMap в secret и разверните пароль базы данных прямо там. Затем вы можете смонтировать секрет как файл на том и использовать его как обычный файл конфигурации в контейнере.

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