ConfigMap и Secret: выносим конфигурацию

Рейтинг: 52.3% · 11 голосов
Kubernetes для разработчиков: поды, деплойменты, сервисы, ingress, конфиги и отладка. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
anton_k8s
Сообщения: 26
Зарегистрирован: 12 май 2026, 03:23

ConfigMap и Secret: выносим конфигурацию

Сообщение anton_k8s »

АкадемияKubernetes на практикеГлава 6 из 19
Оглавление курса (19)
  1. Зачем нужен Kubernetes и из чего состоит кластер
  2. Поднимаем локальный кластер: minikube и kind
  3. Поды: базовая единица запуска
  4. Deployment и ReplicaSet: управляем репликами
  5. Service: сетевой доступ к подам
  6. ConfigMap и Secret: выносим конфигурацию (вы здесь)
  7. Ingress: пускаем трафик снаружи
  8. Хранилище: Volumes и PersistentVolumeClaim
  9. Namespaces, requests и limits
  10. Health checks: liveness и readiness пробы
  11. Отладка: почему под не стартует
  12. Helm: пакетный менеджер для Kubernetes
  13. Базовая безопасность: RBAC и доступы
  14. Job и CronJob: разовые и периодические задачи
  15. StatefulSet и DaemonSet: stateful-нагрузки и системные агенты
  16. Стратегии обновления и планирование: rollout и rollback, graceful shutdown, nodeSelector, affinity, taints
  17. Автомасштабирование: HPA по метрикам, обзор VPA и Cluster Autoscaler
  18. Наблюдаемость: логи, метрики, events, обзор Prometheus и Grafana
  19. Безопасность глубже: securityContext, Pod Security Standards, NetworkPolicy, шифрование секретов
В четвертой главе мы собрали Deployment, в пятой открыли к нему доступ через Service. Но адрес базы и уровень логирования до сих пор зашиты прямо в образ. Эта глава про то, как вынести настройки наружу, чтобы один и тот же образ без пересборки ехал и в dev, и в prod.

Зачем выносить конфигурацию:

Образ собирается один раз. Все, что отличается между окружениями (хост базы, флаги, токены), должно приходить снаружи. В Kubernetes для этого два объекта: ConfigMap для обычных настроек и Secret для всего, что нельзя светить в логах и в git.

ConfigMap:

ConfigMap это просто набор пар ключ-значение, никакой магии:

Код: Выделить всё

# backend-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: backend-config
data:
  APP_ENV: "production"
  LOG_LEVEL: "info"
  DB_HOST: "postgres.default.svc.cluster.local"
  DB_PORT: "5432"
Применяем обычным kubectl apply. Можно создать и императивно: kubectl create configmap с флагом --from-literal для отдельных пар или --from-file, когда нужно затащить целый файл, например nginx.conf. Тогда имя файла станет ключом, а содержимое значением.

Все значения тут строки. Даже порт 5432 пишем в кавычках, иначе apply упадет на валидации. И ConfigMap не резиновый: лимит 1 МиБ, большие файлы туда пихать не надо.

Подключаем к Deployment:

Контейнер получает данные двумя способами: через переменные окружения или через файлы из volume. Если приложение читает env, хватит envFrom:

Код: Выделить всё

spec:
  containers:
  - name: backend
    image: cr.yandex/myteam/backend:1.4.2
    envFrom:
    - configMapRef:
        name: backend-config
    volumeMounts:
    - name: nginx-conf
      mountPath: /etc/nginx/conf.d
      readOnly: true
  volumes:
  - name: nginx-conf
    configMap:
      name: nginx-conf
envFrom закидывает в контейнер все ключи разом. Если нужен один конкретный ключ, есть env с valueFrom и configMapKeyRef, но на старте envFrom проще. При монтировании как volume каждый ключ становится файлом в каталоге: ключ nginx.conf превратится в /etc/nginx/conf.d/nginx.conf.

Secret:

Secret устроен почти так же, но значения в поле data хранятся в base64. Чтобы не кодировать руками, пишите в stringData, при сохранении Kubernetes сам переложит все в data в закодированном виде:

Код: Выделить всё

apiVersion: v1
kind: Secret
metadata:
  name: backend-secrets
type: Opaque
stringData:
  DB_PASSWORD: "Xk29!vLm"
  API_TOKEN: "tok-7f3a9c"
Подключается к поду так же, как ConfigMap: envFrom с secretRef вместо configMapRef, либо volume.

Ключевой момент: base64 это не шифрование, а кодирование. Любой, у кого есть права читать секреты, достанет значение одной командой:

Код: Выделить всё

kubectl get secret backend-secrets -o jsonpath='{.data.DB_PASSWORD}' | base64 -d
Поэтому YAML секретов в репозиторий не коммитим, даже во внутренний. Для хранения в git есть sealed-secrets и SOPS, в серьезных инсталляциях значения приезжают из внешнего хранилища вроде Vault. Помните и про то, что в etcd секреты по умолчанию лежат в открытом виде, шифрование at rest включается отдельно. А кто вообще имеет право их читать, разберем в главе 13 про RBAC.

Типичные грабли:

Самая частая беда связана с обновлением. Поменяли ConfigMap, сделали apply, а под живет со старыми значениями. Переменные окружения читаются один раз при старте контейнера и не обновляются никогда. Файлы из volume kubelet обновит сам, обычно в течение минуты-другой, но приложение должно уметь перечитывать их без рестарта, а это умеют далеко не все. Рабочее решение для env: после изменения конфига дергать kubectl rollout restart для деплоймента. В Helm (глава 12) это автоматизируют аннотацией с хэшем конфига.

Вторая ловушка: если монтируете ключ через subPath, файл не обновится вообще, даже через час.

Третья: путаница data и stringData. Положили в data незакодированное значение, получили ошибку про illegal base64 data. Или наоборот, закодировали уже закодированное и потом полчаса дебажите неверный пароль. Правило простое: руками пишем только в stringData.

Итог:

Конфигурация теперь живет отдельно от образа: обычные настройки в ConfigMap, чувствительные в Secret, в контейнер они попадают через env или файлы. Образ один, окружений сколько угодно. В следующей главе пустим трафик снаружи через Ingress, и там Secret снова пригодится: именно в нем хранят TLS-сертификаты.
👍3 ❤️2 🔥2 😄 🤔3
✔ Лучший ответ сформирован автоматически — VaultNerd
anton_k8s писал(а):Переменные окружения читаются один раз при старте контейнера и не обновляются никогда а как тогда народ в проде катает конфиг без ручных рестартов? видел у соседней команды stakater reloader, он сам делает rollout при изменении configmap. это нормальная практика или костыль поверх костыля?
Перейти к ответу →
Аватара пользователя
VaultNerd
Сообщения: 1
Зарегистрирован: 18 май 2026, 16:26

Re: ConfigMap и Secret: выносим конфигурацию

Сообщение VaultNerd »

✔ Лучший ответ — сформирован автоматически
anton_k8s писал(а):Переменные окружения читаются один раз при старте контейнера и не обновляются никогда
а как тогда народ в проде катает конфиг без ручных рестартов? видел у соседней команды stakater reloader, он сам делает rollout при изменении configmap. это нормальная практика или костыль поверх костыля?
👍2 ❤️2 🔥 😄 🤔
Аватара пользователя
juniordaemon
Сообщения: 2
Зарегистрирован: 16 май 2026, 03:11

Re: ConfigMap и Secret: выносим конфигурацию

Сообщение juniordaemon »

спасибо за stringData, реально боль снял. раньше кодировал руками через echo и однажды забыл флаг -n, echo дописал перевод строки в конец пароля. база отвечала access denied, а пароль в секрете "вроде правильный". два вечера убил, пока не догадался прогнать значение через base64 -d | xxd и увидеть лишний 0a в конце
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
acesup
Сообщения: 2
Зарегистрирован: 20 май 2026, 09:52

Re: ConfigMap и Secret: выносим конфигурацию

Сообщение acesup »

anton_k8s писал(а):если монтируете ключ через subPath, файл не обновится вообще
подтверждаю, у нас так nginx месяц крутился с протухшим конфигом, все были уверены что изменения приехали. с тех пор subPath только там, где без него совсем никак, и на каждое изменение принудительный rollout restart
👍 ❤️1 🔥1 😄 🤔
Аватара пользователя
larrywm
Сообщения: 3
Зарегистрирован: 18 май 2026, 05:22

Re: ConfigMap и Secret: выносим конфигурацию

Сообщение larrywm »

а если сервисов штук 15 и у половины общие настройки, типа адреса кафки? делать один общий configmap на всех или каждому свой? с общим страшно, что любое изменение заденет всех разом
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Service: сетевой доступ к подам
Следующая глава →
Ingress: пускаем трафик снаружи

Все главы курса «Kubernetes на практике»

Поделиться темой: ✈ Telegram VK

Вернуться в «Kubernetes на практике»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость