Как добавить переменные окружения в pod?

Есть несколько способов передать переменные окружения в контейнеры Pod'а — от простого env в манифесте до привязки ConfigMap/Secret, Downward API и динамических значений. Ниже — подробное руководство с примерами, поведением при обновлении и рекомендациями по безопасности.

1) Явная запись в env (literal)

env:
\- name: LOG_LEVEL
value: "info"
\- name: GREETING
value: "hello"

Плюсы: просто. Минусы: значения хардкодятся в манифесте (небезопасно для секретов).

2) valueFrom: secretKeyRef — достать из Secret

Создание секрета:

kubectl create secret generic db-secret --from-literal=DB_PASS='s3cr3t'

Использование в Pod:

env:
\- name: DB_PASS
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASS

Secret хранятся в etcd (base64) — включайте шифрование at-rest и ограничивайте RBAC.

3) valueFrom: configMapKeyRef — достать из ConfigMap

Создать:

kubectl create configmap app-config --from-literal=LOG_LEVEL=debug

Использовать:

env:
\- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL  

4) envFrom — импорт всех ключей из ConfigMap/Secret

envFrom:
\- configMapRef:
name: app-config
\- secretRef:
name: db-secret

Также можно добавить префикс:

\- secretRef:
name: db-secret
prefix: "DB_"

5) Downward API / fieldRef — метаданные Pod'а

Получить имя pod, namespace, IP и т.п.:

env:
\- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
\- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
\- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP

6) resourceFieldRef — значения ресурсов контейнера (requests/limits)

env:
\- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: mycontainer
resource: requests.cpu

Полезно для передачи квот/лимитов внутрь приложения.

7) Mount как файл + чтение при старте (CSI/Downward API volume)

Для больших секретов или чтобы иметь возможность динамической ротации, монтируйте Secret как volume и читайте файл в entrypoint:

volumes:
\- name: secret-vol
secret:
secretName: db-secret
containers:
\- name: app
volumeMounts:
\- name: secret-vol
mountPath: /etc/secrets

В command можно читать /etc/secrets/DB_PASS и экспортировать в env при старте. Это позволяет ротацию (volume обновляется) без пересоздания Pod (env в процессе не обновится, но файл изменится).

8) Динамическая ротация и безопасные подходы

  • Env переменные фиксируются при старте контейнера. Обновление ConfigMap/Secret НЕ обновит env в уже запущенном контейнере — нужен рестарт Pod.

  • Для реальной ротации используйте:

    • CSI Secrets Store (монтирует секреты в виде файлов, поддерживает rotation);

    • Vault Agent / sidecar с автопулом/реневом и монтированием в файл;

    • ExternalSecrets operator (синхронизация секретов в k8s Secret с безопасной ротацией).

  • Не храните секреты в Git. Используйте SealedSecrets / SOPS / инструмент для шифрования.

9) Обновление env из CI / kubectl

  • Через kubectl set env:
kubectl set env deploy/my-deploy DB_HOST=db.example.com -n prod

Это создаёт новый ReplicaSet и перезапускает Pod'ы (Deployment управляет rollout). Для ConfigMap/Secret изменение требует пересоздания Pod если env берётся напрямую из них.

10) Безопасность и рекомендации

  • Не логируйте env-значения, особенно секреты.

  • Ограничьте доступ к Secret через RBAC.

  • Включите шифрование etcd.

  • Для минимизации риска: предпочитайте mount-as-file + CSI/Vault для чувствительных данных; отключайте automountServiceAccountToken если не нужно.

  • Используйте immutable: true для Secret/ConfigMap, когда не хотите непреднамеренных изменений.

Пример полного контейнера

containers:
\- name: web
image: myapp:1.0
env:
\- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
\- name: DB_PASS
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASS
\- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
envFrom:
\- configMapRef:
name: common-config

Эти подходы покрывают большинство сценариев: простые константы, конфигурация per-environment (ConfigMap), секреты (Secret), метаданные (Downward API) и безопасная динамическая ротация (CSI/Vault). Помните: env читаются на старте контейнера — для живой ротации нужно использовать файловые монтирования и агенты.