ConfigMap и Secret
Что нужно знать перед уроком
- M1.03 — Service и порты — нужен namespace/Service из предыдущего урока для проверки конфигурации
Что нужно знать перед уроком
M1 урок 1 — контейнер, его окружение и volumes на уровне понятий. В этом уроке разбираем, как передавать конфигурацию и секреты в контейнер без пересборки образа.
Теория
Зачем разделять код и конфигурацию
Образ контейнера — неизменяемый артефакт: одна и та же собранная версия myapp:1.4.0 должна работать одинаково и в тестовом, и в продакшен-окружении, отличаясь только конфигурацией (адрес БД, включённые фичи, секретные ключи). Если «зашивать» конфигурацию в образ — потребуется пересборка на каждое изменение окружения, что нарушает принцип «один артефакт — много окружений». ConfigMap и Secret — объекты Kubernetes для внешней передачи конфигурации в контейнер без изменения образа.
Два способа потребления: переменные окружения vs volume
Через переменные окружения — значение подставляется в env контейнера один раз при старте:
| |
Критичный момент: если ConfigMap изменится после старта контейнера — переменная окружения не обновится без пересоздания Pod’а (env читается только при запуске процесса, ОС не уведомляет процесс об изменении переменных на лету).
Через volume mount — ConfigMap/Secret монтируется как файл(ы) в файловую систему контейнера:
| |
В этом случае kubelet действительно обновляет файлы на диске при изменении ConfigMap (с задержкой синхронизации, обычно до минуты) — но приложение должно само уметь перечитывать файл (через inotify или периодический опрос), Kubernetes не заставляет процесс перезапуститься автоматически.
subPath — монтирование одного конкретного ключа ConfigMap как отдельного файла, без замещения всей директории:
| |
subPath файл не обновляется при изменении ConfigMap (в отличие от монтирования целой директории) — это осознанный trade-off Kubernetes ради предсказуемости при частичном монтировании.Secret — это не шифрование
Ключевое заблуждение новичков: Secret не защищает данные шифрованием. Значения в Secret хранятся в кодировке base64 (это просто представление, не шифрование — декодировать может кто угодно, у кого есть доступ к чтению объекта). Реальная защита Secret — не в самом объекте, а в (а) более строгой RBAC-политике по умолчанию на чтение Secret по сравнению с ConfigMap, и (б) шифровании данных at rest в etcd на уровне кластера (EncryptionConfiguration, настраивается администратором кластера, не гарантировано «из коробки» на всех дистрибутивах).
| |
Типизированные Secret
Помимо обычного Opaque (произвольные ключи-значения), Kubernetes определяет специализированные типы с зарезервированными полями, которые понимают отдельные компоненты платформы:
kubernetes.io/tls— сертификат + приватный ключ (tls.crt,tls.key), используется Ingress/Gateway API для TLS-терминации.kubernetes.io/dockerconfigjson— креды для приватного registry, единственный ключ.dockerconfigjson.
| |
Такой Secret указывается в imagePullSecrets Pod’а/ServiceAccount, чтобы kubelet мог скачать образ из приватного registry — это станет актуально начиная с M3, когда мы начнём публиковать собственные образы не в публичный registry.
immutable: true
Начиная с определённой версии Kubernetes и ConfigMap, и Secret поддерживают флаг immutable: true:
| |
Эффект двойной: (1) защита от случайных правок «на живую» (попытка kubectl edit вернёт ошибку — нужно явно удалить и создать новый объект), (2) снижение нагрузки на kube-apiserver, потому что для иммутабельных объектов не нужно поддерживать watch на изменения — компоненты, которые их читают, могут кэшировать значение бессрочно. Побочный эффект: если конфигурация должна меняться без пересоздания Pod’а (как в примере с volume mount выше) — immutable: true этому противоречит, нужно выбирать одно из двух осознанно.
Частые ошибки и подводные камни
- Ожидать, что изменение ConfigMap мгновенно обновит переменную окружения запущенного контейнера. Не обновит никогда, без пересоздания Pod’а — переменные окружения читаются только при старте процесса.
- Хранить пароли в ConfigMap «для простоты». Даже без шифрования, Secret имеет более строгий RBAC по умолчанию — использование ConfigMap для чувствительных данных фактически снижает уровень защиты.
- Путать
subPathс обычным монтированием директории — приsubPathтеряется автообновление файла при изменении ConfigMap, о чём легко забыть. - Считать Secret «безопасным просто по факту существования объекта такого типа» — без включённого шифрования etcd at rest и грамотного RBAC, Secret в base64 практически равносилен ConfigMap по уровню защищённости данных на диске etcd.
Практика в кластере
Vaultwarden — неофициальный, но широко используемый self-hosted сервер, совместимый с клиентами Bitwarden (менеджер паролей), написан на Rust. Конфигурация почти целиком через переменные окружения и файлы — идеальный пример для этого урока.
| |
- Проверьте, что переменные окружения реально попали в контейнер:
| |
- Измените ConfigMap и убедитесь, что переменная окружения в уже запущенном контейнере не поменялась:
| |
- Убедитесь, что значение Secret — просто base64, не шифрование:
| |
- Попробуйте отредактировать Secret «на живую» после того, как сделаете его immutable:
| |
Практика разработки
Используется официальный образ vaultwarden/server; собственная сборка появится в M3.
Шпаргалка команд урока
| |
Вопросы для самопроверки
env.valueFrom.configMapKeyRef подставляется единожды при старте контейнера; последующие изменения ConfigMap не отражаются без пересоздания Pod'а.
Источник: Kubernetes — configmap
base64 — не шифрование; защита Secret строится на более строгом RBAC по умолчанию и опциональном шифровании etcd at rest, настраиваемом администратором.
Источник: Kubernetes — secret
subPath — известный trade-off Kubernetes: точечное монтирование одного файла отключает механизм автообновления содержимого при изменении источника.
Источник: Kubernetes — configmap
Единственное поле .dockerconfigjson содержит креды registry, на которые ссылается imagePullSecrets Pod'а/ServiceAccount для скачивания приватных образов.
Источник: Kubernetes — secret
Иммутабельные ConfigMap/Secret позволяют компонентам кэшировать значение бессрочно без подписки на изменения, что снижает нагрузку на kube-apiserver в больших кластерах.
Источник: Kubernetes — configmap
Рекомендуемая литература
Официальная документация
Статьи и блоги
- Kubernetes для начинающих: что такое Pod и как с ним работать — Flant на Habr.
- Основные концепции сетевой архитектуры Kubernetes — Habr.
- Миграция с ingress-nginx: выбор нового контроллера — Habr.
Книги
- Marko Lukša. Kubernetes in Action. 2nd ed., 2022. ISBN 978-1617297618.
- Kelsey Hightower, Brendan Burns, Joe Beda. Kubernetes: Up and Running. 3rd ed., 2022. ISBN 978-1098110201.
- Michael Hausenblas, Stefan Schimanski. Programming Kubernetes. 2019. ISBN 978-1492047107.
Связанные материалы
- Предыдущий урок: M1.03 — Service и порты.
- Следующий урок: M1.05 — Namespace, labels, selectors.
- Глоссарий: ConfigMap / Secret.
✓ Урок пройден — все вопросы самопроверки отвечены верно