Конфигурация и секреты
Что это такое
Образ контейнера должен быть одинаковым в любой среде, поэтому всё, что различается — эндпоинт, флаг функции, пароль базы данных, — поставляет кластер во время выполнения. Kubernetes разделяет это на конфигурацию, хранимую как данные ключ-значение, и секреты, хранимые как закодированный объект с дополнительным контролем доступа. И то и другое pod потребляет как значения среды или как примонтированные файлы.
Почему это важно
Альтернатива — отдельный образ на каждую среду, а значит протестированный артефакт не тот, что выпущен, и ошибку конфигурации, которая проявляется только в эксплуатации, нельзя воспроизвести локально. Перенос различий в кластер делает их ещё и обозримыми: конфигурация живёт в системе контроля версий рядом с манифестом, и её изменение — это diff, а не правка на работающей машине. Секреты расширяют ту же идею с важной поправкой: кодирование — не шифрование, и доступом надо управлять осознанно.
Ключевые идеи
Конфигурация — это данные, и её можно монтировать или внедрять
Объект конфигурации хранит обычные пары ключ-значение, которые pod читает как значения среды или как файлы в томе. Примонтированный файл можно обновить на месте, тогда как значение среды фиксировано на всё время жизни контейнера — и это различие решает, нужен ли для изменения перезапуск.
config map -> значение среды (фиксировано на старте) -> для смены нужен перезапуск
-> примонтированный файл (обновляется) -> перезагрузка силами приложения
Секрет — отдельный вид не просто так
Секрет хранится отдельно, чтобы доступ к нему можно было выдать сам по себе и чтобы его содержимое реже попадало в логи и манифесты. Содержимое закодировано base64, а не зашифровано: прочитать объект — значит прочитать секрет. Настоящая защита — в ограничении тех, кто может его читать, и в ключе шифрования на уровне хранилища.
Никогда не коммитьте секрет и не запекайте его в образ
Секрет, закоммиченный в репозиторий, остаётся в истории, и его нужно ротировать, а не просто удалить. Секрет в слое образа может прочитать любой, кто может вытянуть образ. Обе ошибки часты, потому что удобны на минуту, и обе превращают обычное изменение конфигурации в инцидент.
Внешние хранилища секретов держат один источник истины
Когда секрет уже есть в менеджере секретов облачного провайдера, копия в объекте кластера создаёт два источника, которые расходятся. Приём — позволить кластеру читать из внешнего хранилища: либо при развёртывании, либо оператором, который синхронизирует его, — чтобы ротация происходила в одном месте.
Pod должен явно падать, когда конфигурации не хватает
Pod, который стартует с пустым эндпоинтом и падает на первом запросе, диагностировать куда труднее, чем тот, что отказывается запускаться. Там, где платформа это поддерживает, проверка обязательной конфигурации при старте и выход с ненулевым кодом превращают запутанный отказ времени выполнения в очевидную проблему планирования.
Конфигурация — часть релиза, а не запоздалая мысль
Поведение deployment — это образ плюс его конфигурация, поэтому версионировать и выпускать их надо вместе. Изменение конфигурации, требующее перезапуска, — это развёртывание, и его нужно просматривать, фиксировать и уметь откатывать, как любое другое.
Практика
Вынесите настройку из образа
Возьмите сервис с эндпоинтом, зашитым в код. Перенесите значение в объект конфигурации, потребите его как значение среды и убедитесь, что один и тот же образ может указывать на два разных эндпоинта.
Готово, когда: один digest образа работает с двумя конфигурациями, и различается только эндпоинт.
Докажите, что секрета нет в образе
Возьмите существующий образ и поищите в его истории и файловой системе учётные данные, о которых знаете, что он их использует.
Готово, когда: учётных данных нет в образе и они есть только в объекте секрета кластера.
Частые ошибки
- Коммит секрета в репозиторий — он остаётся в истории и должен считаться утёкшим; исправить: ротируйте его и загружайте из хранилища секретов.
- Секрет, встроенный в образ — любой, кто может вытянуть образ, получает его; исправить: внедряйте его во время выполнения.
- Отношение к base64-кодированию как к шифрованию — значение читаемо для любого с доступом к объекту; исправить: ограничьте доступ и включите шифрование при хранении.
- Копирование секретов из внешнего хранилища в кластер — два источника расходятся, и ротация пропускается; исправить: читайте из хранилища напрямую или синхронизируйте осознанно.
- Подача изменения конфигурации как молчаливого изменения поведения — без diff, без ревью и без отката; исправить: версионируйте конфигурацию вместе с развёртыванием.
Что читать дальше
- Планирование и масштабирование (06-cloud-devops/14-kubernetes/02-scheduling-and-scaling) — объявления ресурсов, нужные pod’у ещё до того, как речь зайдёт о конфигурации.
- Kubernetes (06-cloud-devops/14-kubernetes) — платформа, частью которой являются эти объекты.
- Безопасность в облаке и IAM (06-cloud-devops/12-cloud-security-iam) — более широкая дисциплина выдачи идентичности ровно тех прав, что нужны.