← До програми курсу

Модуль 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 не призначений для паролів і токенів. Конфігурація є частиною контракту застосунку: імена keys, формат files, обов’язковість і типові значення слід документувати.

03

3. Теорія: Secret і модель загроз

Secret відокремлює чутливі дані від PodSpec та image, але base64 є кодуванням, а не шифруванням. Типово дані Secret можуть зберігатися в etcd без шифрування.

Для production увімкніть encryption at rest, обмежте get/list/watch через RBAC, надавайте Secret лише потрібному контейнеру, виключайте значення з Git і logs, розгляньте зовнішній 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 → мінімальне виправлення посилання. Logs контейнера відсутні, бо процес ще не запускався.

10

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

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

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

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

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

Завантажити PDFPDF