Питання 16 · Розділ 14

В чому різниця між ConfigMap та Secret?

Для звичайних налаштувань:

Мовні версії: English Russian Ukrainian

Junior рівень

Просте пояснення

ConfigMap та Secret — це об’єкти Kubernetes для зберігання налаштувань додатку окремо від коду. Різниця в тому, що ConfigMap для звичайних налаштувань, а Secret — для паролів та чутливих даних.

Проста аналогія

  • ConfigMap — як стікер на моніторі з налаштуваннями (адреса сервера, порт)
  • Secret — як сейф з паролями та ключами

ConfigMap

Для звичайних налаштувань:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DB_HOST: "postgres.default.svc.cluster.local"
  DB_PORT: "5432"
  APP_ENV: "production"

Secret

Для паролів та ключів:

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  DB_PASSWORD: cGFzc3dvcmQxMjM=    # base64 від "password123"
  API_KEY: c2VjcmV0LWtleQ==        # base64 від "secret-key"

Важливо: base64 — це не шифрування! Це просто кодування. Будь-хто може декодувати.

Як використовувати в Pod’і?

Як змінні оточення:

containers:
- name: app
  image: myapp
  env:
  - name: DB_HOST
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: DB_HOST
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: app-secret
        key: DB_PASSWORD

Як файли (volume):

volumes:
- name: config-volume
  configMap:
    name: app-config
- name: secret-volume
  secret:
    secretName: app-secret

Порівняння

  ConfigMap Secret
Дані Звичайний текст Base64
Для чого Налаштування Паролі, ключі
Безпека Низька Середня (потрібен RBAC)

Що запам’ятати Junior-розробнику

  • ConfigMap — для звичайних налаштувань, Secret — для паролів
  • Secret зберігається в base64 (це не шифрування!)
  • Обидва можна використовувати як змінні або як файли
  • Файли з ConfigMap/Secret оновлюються без перезапуску Pod’а
  • Не зберігайте секрети в git — використовуйте external secrets

Коли НЕ використовувати ConfigMap/Secret

НЕ зберігайте в ConfigMap: великі файли (>1MB ліміт), бінарні файли. НЕ зберігайте в Secret: секрети зовнішніх систем (API-ключі третіх сторін) – краще Vault.


Middle рівень

Зберігання даних

ConfigMap:

  • Дані у відкритому текстовому вигляді в etcd
  • Ліміт розміру: 1 МБ (обмеження etcd)

Secret:

  • Дані в base64 (НЕ шифрування! base64 легко декодується). Для шифрування потрібен EncryptionConfiguration або зовнішнє рішення (Vault, Sealed Secrets).
  • Secrets зберігаються в etcd у відкритому вигляді (якщо не увімкнено EncryptionConfiguration). Доступ до etcd = доступ до всіх Secret’ів.
  • Для реального захисту потрібно увімкнути Encryption at Rest в etcd

Два способи використання

1. Environment Variables

env:
- name: DB_HOST
  valueFrom:
    configMapKeyRef:
      name: app-config
      key: DB_HOST

Плюс: просто Мінус: не оновлюються “на льоту” без перезапуску Pod’а

2. Volumes (монтування файлами)

volumeMounts:
- name: config-volume
  mountPath: /etc/config
  readOnly: true

Плюс: оновлюються автоматично (Kubelet оновлює файли) Мінус: додаток має вміти перечитувати конфіг

Immutable ConfigMap/Secret

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: "production"
immutable: true    # Не можна змінити після створення

Переваги:

  • Захист від випадкових змін
  • Знижує навантаження на kube-apiserver
  • Kubelet не моніторить зміни

External Secrets

Для великих проектів використовуйте External Secrets Operator:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: db-credentials-secret
  data:
  - secretKey: DB_PASSWORD
    remoteRef:
      key: prod/db/password

Синхронізує секрети з HashiCorp Vault, AWS Secrets Manager, Azure Key Vault.

Що запам’ятати Middle-розробнику

  • Secret в base64 ≠ шифрування. Потрібне додаткове налаштування.
  • Env vars не оновлюються, volumes — оновлюються автоматично
  • Immutable об’єкти захищають від випадкових змін
  • External Secrets Operator — стандарт для production
  • RBAC: обмежуйте доступ до Secrets

Senior рівень

Архітектура зберігання секретів

Без Encryption at Rest:

etcd зберігає: DB_PASSWORD: cGFzc3dvcmQxMjM=
Будь-хто з доступом до etcd може декодувати.

З Encryption at Rest:

# kube-apiserver configuration
encryption-provider-config:
  kind: EncryptionConfiguration
  resources:
  - resources: ["secrets"]
    providers:
    - aescbc:
        keys:
        - name: key1
          secret: <base64-encoded-key>
    - identity: {}

Тепер секрети шифруються в etcd.

Безпека: глибокий аналіз

Рівень Захист Опис
Base64 only Ні Будь-хто з доступом до etcd/API читає
RBAC Частковий Обмежує доступ до API
Encryption at Rest Хороший Шифрує дані в etcd
External KMS Найкращий Ключі шифрування поза кластером

RBAC для Secrets

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]
  resourceNames: ["app-secret"]  # тільки конкретний secret

Порівняння підходів: Env vs Volume

Аспект Env Vars Volumes
Оновлення Вимагає restart Pod Автоматичне
Розмір Підходить для простих значень Підходить для файлів
Безпека Видно в kubectl describe pod Тільки через exec в контейнер
Hot reload Ні Так (додаток має перечитати)

Spring Boot + ConfigMap/Secret

ConfigMap як application.properties:

apiVersion: v1
kind: ConfigMap
metadata:
  name: spring-config
data:
  application.properties: |
    spring.datasource.url=jdbc:postgresql://db:5432/mydb
    spring.jpa.hibernate.ddl-auto=validate
volumeMounts:
- name: config
  mountPath: /config
  readOnly: true
env:
- name: SPRING_CONFIG_LOCATION
  value: "file:/config/application.properties"

Secret Management: еволюція

Level 0: Секрети в git (anti-pattern)
Level 1: Kubernetes Secrets (base64)
Level 2: Secrets + Encryption at Rest
Level 3: External Secrets Operator + Vault/KMS
Level 4: Service Mesh (mTLS) + SPIFFE/SPIRE (identity)

Immutable об’єкти: коли використовувати

immutable: true

Використовуйте, коли:

  • Конфігурація не змінюється між деплоями
  • Хочете додатковий захист від змін
  • Зниження навантаження на API server (великі ConfigMap)

Не використовуйте, коли:

  • Налаштування змінюються динамічно
  • A/B testing з різними конфігами

Troubleshooting

Secret не монтується:

kubectl describe pod myapp
# Warning: Couldn't find secret app-secret in namespace default

Причини:

  1. Secret не створений
  2. Secret в іншому namespace
  3. Помилка в імені

ConfigMap оновився, але Pod не бачить змін:

  • Volume update delay: Kubelet оновлює файли з затримкою (syncPeriod, за замовчуванням 1 хв)
  • Додаток не перечитує файл — потрібен hot reload mechanism

Підсумок для Senior

  • ConfigMap для конфігів, Secret — для паролів.
  • Secret за замовчуванням не безпечний без Encryption at Rest або зовнішнього KMS.
  • Віддавайте перевагу монтуванню файлами для hot reload.
  • External Secrets Operator + Vault/KMS — production стандарт.
  • RBAC: обмежуйте доступ до Secrets за принципом найменших привілеїв.
  • Immutable об’єкти: захист від змін + зниження навантаження на API.
  • Spring Boot: монтуйте ConfigMap як application.properties для динамічної конфігурації.

🎯 Шпаргалка для інтерв’ю

Обов’язково знати:

  • ConfigMap — звичайні налаштування (текст), Secret — чутливі дані (base64)
  • Base64 ≠ шифрування! Будь-хто може декодувати; потрібна Encryption at Rest
  • Обидва можна використовувати як env vars (не оновлюються без restart) або volumes (auto-update)
  • Ліміт розміру: 1 МБ (обмеження etcd)
  • Immutable ConfigMap/Secret — захист від змін + зниження навантаження на API server
  • External Secrets Operator + Vault/KMS — production стандарт
  • RBAC: обмежуйте доступ до Secrets за принципом least privilege

Часті уточнюючі запитання:

  • «Secret безпечно зберігає паролі?» — За замовчуванням ні (base64 в etcd); потрібна EncryptionConfiguration
  • «Env vars vs volumes?» — Volumes оновлюються автоматично, env vars вимагають restart Pod
  • «Що таке External Secrets Operator?» — Синхронізує секрети з Vault, AWS Secrets Manager, Azure Key Vault
  • «Коли використовувати immutable?» — Коли конфіг не змінюється між деплоями (захист + performance)

Червоні прапорці (НЕ говорити):

  • «Secrets зашифровані в K8s» (тільки base64; потрібно увімкнути Encryption at Rest)
  • «Зберігаю секрети в git в base64» (це не шифрування, будь-хто декодує)
  • «ConfigMap для паролів» (використовуйте Secret)
  • «Env vars оновлюються без restart» (тільки volumes auto-update)

Пов’язані теми:

  • [[Що таке Kubernetes і навіщо він потрібен]] — об’єкти K8s
  • [[Що таке Ingress в Kubernetes]] — TLS secrets
  • [[Як моніторити додатки в Kubernetes]] — моніторинг конфігурації