Kustomize: генератор Secret
secretGenerator и честный разбор того, что base64 в Secret ничего не защищает.
Secret - это объект Kubernetes для чувствительных данных: паролей, токенов, ключей и сертификатов. Устроен он почти как ConfigMap, отличается типом объекта, отдельными правилами доступа и тем, что значения хранятся в поле data закодированными в base64.
secretGenerator работает по тем же правилам, что и configMapGenerator. Те же три источника, тот же хеш-суффикс, тот же блок generatorOptions.
Генерация из literals
secretGenerator:
- name: app-secret
literals:
- DB_PASSWORD=s3cr3t
- API_TOKEN=abc123
Значения пишутся как есть. Кодировать в base64 руками не нужно: Kustomize сделает это при рендере. На выходе получится Secret типа Opaque с полем data, где значения уже закодированы.
Секрет из файлов
Для сертификатов и ключей удобнее files, потому что PEM-файл в literals не вставишь:
secretGenerator:
- name: web-tls
type: kubernetes.io/tls
files:
- tls.crt=certs/site.pem
- tls.key=certs/site.key
Поле type задаёт тип Secret. Для kubernetes.io/tls Kubernetes требует ровно ключи tls.crt и tls.key, поэтому исходные файлы переименовываются при подключении. Без указания type получится обычный Opaque.
Есть ещё envs, который разбирает файл КЛЮЧ=значение построчно. Полезно, когда набор переменных уже лежит в .env-файле.
Файл попадает в Secret ровно как есть, вместе с завершающим переводом
строки. Пароль, сгенерированный через echo, приедет на символ длиннее
и не подойдёт. Спасает echo -n или printf.
base64 - это кодирование, а не шифрование
Значения в Secret выглядят как случайный текст, и это легко принять за защиту. Защиты там нет. base64 - обратимое кодирование, придуманное для передачи бинарных данных текстом. Любой, у кого есть право читать Secret, достанет исходное значение одной командой:
kubectl get secret app-secret-9t2hk4m6c2 -o jsonpath='{.data.DB_PASSWORD}' | base64 -d
Что действительно ограничивает доступ:
- RBAC решает, кто вообще может выполнить
get secretв этом namespace. - Шифрование etcd в состоянии покоя закрывает данные на диске узлов control plane.
- Внешние хранилища (Vault, облачные secret manager) держат значения вне кластера, а в Kubernetes попадает только ссылка или короткоживущий токен.
Практическая ценность Secret в том, что он отделяет чувствительные данные от остальной конфигурации и даёт для них отдельную точку контроля доступа. Само содержимое объект не шифрует.
По этой же причине kubectl kustomize . печатает готовый Secret в
терминал. В CI такой вывод уезжает в логи пайплайна, где его прочитает
любой, у кого есть доступ к сборкам.
Хеш-суффикс
Как и у ConfigMap, к имени добавляется хеш содержимого: app-secret-9t2hk4m6c2. Меняется значение - меняется имя, Kustomize правит ссылку в Deployment, кластер запускает rollout, и Pod подхватывают новый пароль. Отключается тем же способом:
generatorOptions:
disableNameSuffixHash: true
Что обычно ломается
Пароль в literals попадает в git открытым текстом. Это главная проблема secretGenerator, и решают её не Kustomize. В репозитории держат либо зашифрованные файлы (SOPS, sealed-secrets), либо только ссылку на внешнее хранилище, а literals оставляют для локальных экспериментов.
Рендер для отладки лучше не делать на шаге, который пишет логи в общий доступ.
Смена типа Secret на живом объекте не проходит: поле type неизменяемое. Если Secret создавали как Opaque, а потом решили сделать kubernetes.io/tls, объект придётся удалить и создать заново.
Домашка
Теорию закрепляет задание на своём кластере: 2 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.
./run.sh start k8s-kustomize-secret-generator # развернуть стартовое состояние
./run.sh verify k8s-kustomize-secret-generator # проверить текущий шаг
Коротко
secretGeneratorустроен какconfigMapGenerator: те жеliterals,files,envsи хеш-суффикс.- Значения пишутся в открытом виде, base64 Kustomize добавляет сам.
- Поле
typeзадаёт тип Secret, напримерkubernetes.io/tlsс ключамиtls.crtиtls.key. - base64 раскодируется одной командой; защиту дают RBAC, шифрование etcd и внешние хранилища.
- Пароли в
literalsлежат в git открытым текстом, поэтому в реальных репозиториях используют SOPS, sealed-secrets или внешний secret manager.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс