Вопрос 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 ≠ шифрование. Нужна additional настройка.
  • 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]] — мониторинг конфигурации