Конфигурация и секреты

Что это такое

Образ контейнера должен быть одинаковым в любой среде, поэтому всё, что различается — эндпоинт, флаг функции, пароль базы данных, — поставляет кластер во время выполнения. 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) — более широкая дисциплина выдачи идентичности ровно тех прав, что нужны.