Модуль 6 / 19
ConfigMap и Secret
Содержание
1. Цели модуля
После модуля вы сможете отделять конфигурацию от image, выбирать ConfigMap или Secret, передавать значения как environment variables и files, прогнозировать обновление данных и диагностировать CreateContainerConfigError.
- ConfigMap для несекретной конфигурации
- Secret для чувствительных данных
- env и projected volume
- безопасность, обновление и immutable resources
2. Теория: ConfigMap
ConfigMap хранит несекретные пары ключ-значение в data и бинарные значения в binaryData. Pod может использовать их как environment variables, аргументы команды или files в volume.
ConfigMap не предназначен для паролей и токенов. Конфигурация становится частью контракта приложения: имена ключей, формат файлов, обязательность и значения по умолчанию должны быть документированы.
3. Теория: Secret и модель угроз
Secret отделяет чувствительные данные от PodSpec и image, но base64 является кодированием, а не шифрованием. По умолчанию данные Secret могут храниться в etcd без шифрования.
Для production включайте encryption at rest, ограничивайте get/list/watch через RBAC, предоставляйте Secret только нужному контейнеру, исключайте значения из Git и логов, рассматривайте внешний secret store и ротацию.
4. Теория: env, volume и обновления
Environment variable считывается при запуске контейнера и не обновляется в работающем процессе. Изменение ConfigMap или Secret требует пересоздания Pod, если приложение получает значение через env.
Файлы обычного ConfigMap/Secret volume обновляются eventual-consistently после синхронизации kubelet. Приложение должно перечитать файл. Mount через subPath автоматических обновлений не получает. immutable объект нельзя изменить — создайте новый объект и обновите ссылку.
5. Методические указания
- Не храните реальные секреты в manifest или Git, даже в base64
- Используйте stringData только как удобный ввод, а не как защиту
- Перед rollout проверяйте наличие объекта и обязательных keys
- Предпочитайте file mount для секретов, если приложение это поддерживает
- Не печатайте secret values в CI, logs или диагностический вывод
- Для управляемого обновления используйте versioned names или checksum annotation
6. Лабораторная работа: конфигурация приложения
Сохраните манифест как config-lab.yaml. Учебный Secret содержит несекретное демонстрационное значение; не копируйте этот подход с реальными credentials.
apiVersion: v1
kind: Namespace
metadata:
name: lab-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: lab-config
data:
APP_COLOR: blue
app.conf: |
color=blue
log_level=info
---
apiVersion: v1
kind: Secret
metadata:
name: app-secret
namespace: lab-config
type: Opaque
stringData:
API_TOKEN: training-token
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
namespace: lab-config
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: config-demo
template:
metadata:
labels:
app.kubernetes.io/name: config-demo
spec:
automountServiceAccountToken: false
containers:
- name: app
image: busybox:1.37.0
command: ["sh", "-c", "sleep 3600"]
env:
- name: APP_COLOR
valueFrom:
configMapKeyRef:
name: app-config
key: APP_COLOR
- name: API_TOKEN
valueFrom:
secretKeyRef:
name: app-secret
key: API_TOKEN
volumeMounts:
- name: config
mountPath: /etc/app
readOnly: true
- name: secret
mountPath: /var/run/secrets/course
readOnly: true
volumes:
- name: config
configMap:
name: app-config
- name: secret
secret:
secretName: app-secret
defaultMode: 04007. Лабораторная работа: env и files
Примените объекты и проверьте ConfigMap через env и volume, а Secret — только по наличию защищённого файла, не выводя его содержимое.
kubectl apply -f config-lab.yaml
kubectl rollout status deployment/app -n lab-config --timeout=120s
kubectl get configmap app-config -n lab-config -o yaml
kubectl get secret app-secret -n lab-config -o jsonpath='{.type}{" keys="}{.data.API_TOKEN}{"\n"}'
kubectl exec -n lab-config deployment/app -- printenv APP_COLOR
kubectl exec -n lab-config deployment/app -- cat /etc/app/app.conf
kubectl exec -n lab-config deployment/app -- ls -l /var/run/secrets/course
kubectl get pods -n lab-configКритерий: два Ready Pod, APP_COLOR=blue, /etc/app/app.conf содержит ожидаемые строки, secret file имеет ограниченный mode.
8. Лабораторная работа: обновление
Обновите ConfigMap. Mounted file изменится не мгновенно, а environment variable останется прежней до создания нового Pod. Затем выполните rollout restart.
kubectl patch configmap app-config -n lab-config --type=merge -p '{"data":{"APP_COLOR":"green","app.conf":"color=green\nlog_level=debug\n"}}'
kubectl get configmap app-config -n lab-config -o jsonpath='{.metadata.resourceVersion}{"\n"}'
kubectl exec -n lab-config deployment/app -- cat /etc/app/app.conf
kubectl exec -n lab-config deployment/app -- printenv APP_COLOR
kubectl rollout restart deployment/app -n lab-config
kubectl rollout status deployment/app -n lab-config --timeout=120s
kubectl exec -n lab-config deployment/app -- printenv APP_COLORКритерий: до restart файл содержит green, а env ещё blue; после restart новый Pod получает APP_COLOR=green.
9. Диагностика: отсутствующий ключ Secret
Намеренно замените secretKeyRef.key на отсутствующий. Новые Pods не смогут создать контейнер и получат CreateContainerConfigError; старые Pods могут сохраняться стратегией Deployment.
kubectl patch deployment app -n lab-config --type=json -p='[{"op":"replace","path":"/spec/template/spec/containers/0/env/1/valueFrom/secretKeyRef/key","value":"missing"}]'
kubectl rollout status deployment/app -n lab-config --timeout=30s
kubectl get deployment,replicaset,pod -n lab-config
kubectl get pods -n lab-config -o jsonpath='{range .items[*]}{.metadata.name}{" phase="}{.status.phase}{" waiting="}{.status.containerStatuses[0].state.waiting.reason}{"\n"}{end}'
kubectl describe pods -n lab-config -l app.kubernetes.io/name=config-demo
kubectl events -n lab-config --types=Warning
kubectl patch deployment app -n lab-config --type=json -p='[{"op":"replace","path":"/spec/template/spec/containers/0/env/1/valueFrom/secretKeyRef/key","value":"API_TOKEN"}]'
kubectl rollout status deployment/app -n lab-config --timeout=120s
kubectl delete namespace lab-configАлгоритм: Deployment Conditions → новый ReplicaSet → waiting.reason → Pod Events → проверка object name и key → минимальное исправление ссылки. Логи контейнера отсутствуют, потому что процесс ещё не был запущен.
10. Контроль и шпаргалка
- Почему base64 не защищает Secret?
- Чем обновление env отличается от mounted file?
- Почему subPath не получает обновление?
- Какие права RBAC особенно опасны для Secrets?
- Почему CreateContainerConfigError нельзя диагностировать через application logs?
Модуль освоен, если вы безопасно подключаете конфигурацию, объясняете момент появления обновлений и восстанавливаете rollout с отсутствующим key по Events без раскрытия Secret.
PDF для работы офлайн
Скачайте оформленную версию модуля для чтения без подключения к сети.