← К программе курса

Модуль 6 / 19

ConfigMap и Secret

KUBERNETES

Содержание
01

1. Цели модуля

После модуля вы сможете отделять конфигурацию от image, выбирать ConfigMap или Secret, передавать значения как environment variables и files, прогнозировать обновление данных и диагностировать CreateContainerConfigError.

  • ConfigMap для несекретной конфигурации
  • Secret для чувствительных данных
  • env и projected volume
  • безопасность, обновление и immutable resources
02

2. Теория: ConfigMap

ConfigMap хранит несекретные пары ключ-значение в data и бинарные значения в binaryData. Pod может использовать их как environment variables, аргументы команды или files в volume.

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

03

3. Теория: Secret и модель угроз

Secret отделяет чувствительные данные от PodSpec и image, но base64 является кодированием, а не шифрованием. По умолчанию данные Secret могут храниться в etcd без шифрования.

Для production включайте encryption at rest, ограничивайте get/list/watch через RBAC, предоставляйте Secret только нужному контейнеру, исключайте значения из Git и логов, рассматривайте внешний secret store и ротацию.

04

4. Теория: env, volume и обновления

Environment variable считывается при запуске контейнера и не обновляется в работающем процессе. Изменение ConfigMap или Secret требует пересоздания Pod, если приложение получает значение через env.

Файлы обычного ConfigMap/Secret volume обновляются eventual-consistently после синхронизации kubelet. Приложение должно перечитать файл. Mount через subPath автоматических обновлений не получает. immutable объект нельзя изменить — создайте новый объект и обновите ссылку.

05

5. Методические указания

  • Не храните реальные секреты в manifest или Git, даже в base64
  • Используйте stringData только как удобный ввод, а не как защиту
  • Перед rollout проверяйте наличие объекта и обязательных keys
  • Предпочитайте file mount для секретов, если приложение это поддерживает
  • Не печатайте secret values в CI, logs или диагностический вывод
  • Для управляемого обновления используйте versioned names или checksum annotation
06

6. Лабораторная работа: конфигурация приложения

Сохраните манифест как config-lab.yaml. Учебный Secret содержит несекретное демонстрационное значение; не копируйте этот подход с реальными credentials.

terminal
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: 0400
07

7. Лабораторная работа: env и files

Примените объекты и проверьте ConfigMap через env и volume, а Secret — только по наличию защищённого файла, не выводя его содержимое.

terminal
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.

08

8. Лабораторная работа: обновление

Обновите ConfigMap. Mounted file изменится не мгновенно, а environment variable останется прежней до создания нового Pod. Затем выполните rollout restart.

terminal
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.

09

9. Диагностика: отсутствующий ключ Secret

Намеренно замените secretKeyRef.key на отсутствующий. Новые Pods не смогут создать контейнер и получат CreateContainerConfigError; старые Pods могут сохраняться стратегией Deployment.

terminal
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

10. Контроль и шпаргалка

  • Почему base64 не защищает Secret?
  • Чем обновление env отличается от mounted file?
  • Почему subPath не получает обновление?
  • Какие права RBAC особенно опасны для Secrets?
  • Почему CreateContainerConfigError нельзя диагностировать через application logs?

Модуль освоен, если вы безопасно подключаете конфигурацию, объясняете момент появления обновлений и восстанавливаете rollout с отсутствующим key по Events без раскрытия Secret.

PDF для работы офлайн

Скачайте оформленную версию модуля для чтения без подключения к сети.

Скачать PDFPDF