Immutable Secret: запрет на изменение данных
Что делает флаг immutable у Secret и ConfigMap, зачем он нужен и как ротировать данные, когда правки запрещены.
Зачем immutable
У Secret и ConfigMap с Kubernetes 1.21 (GA) есть поле
immutable: bool. Если выставить true, API server запрещает менять
data, stringData и binaryData. Можно только удалить и пересоздать.
Зачем это нужно:
- Защита от случайных правок. Конфиг или ключ не «уплывёт» через
kubectl edit secret prod. - Снижение нагрузки на kube-apiserver и kubelet. За каждым mutable secret/configmap kubelet держит watch и периодически синхронизирует данные в смонтированных volume. Для immutable watch не нужен: kubelet кеширует данные один раз. На кластере с тысячами Pod это заметная экономия запросов к API.
- Иммутабельные деплои. В CI генерируется уникальное имя
(
app-config-abc123), деплой ссылается на него, после ротации создаётся новыйapp-config-def456. Старый удаляется только когда на него никто не ссылается.
Манифест
apiVersion: v1
kind: Secret
metadata:
name: db-password
type: Opaque
immutable: true
data:
password: c2VjcmV0MTIz
data всегда в base64. stringData пишется в открытом виде, API
server сам кодирует при сохранении (но в API всё равно лежит в data).
После kubectl apply Secret оказывается в API server. Поле immutable
можно выставить позже на обычном Secret, но обратно снять нельзя (true
→ false запрещено). Чтобы поменять данные, Secret пересоздают.
Что запрещено
kubectl edit secret db-password
# Error from server (Forbidden): Forbidden: field is immutable when `immutable`
# is set
kubectl patch secret db-password \
--type=merge -p '{"stringData":{"password":"new"}}'
# Error from server (Forbidden): Secret "db-password" is invalid:
# data: Forbidden: field is immutable when `immutable` is set
kubectl apply -f db-password.yaml # с другим password
# Error from server (Invalid): ... field is immutable
Запрещено: изменение data, stringData, binaryData, переключение
immutable: true → false.
Разрешено: правка metadata.labels и metadata.annotations. Также
можно полностью удалить и создать заново - это два отдельных action.
Sealed Secrets или External Secrets пытается обновить Secret сам и упирается в тот же Forbidden. Либо выключают immutable, либо ротируют через новое имя.
Как «обновлять» immutable Secret
Главный паттерн - ротация через новое имя.
# Старый Secret остаётся нетронутым
apiVersion: v1
kind: Secret
metadata:
name: db-password-v2 # новое имя
immutable: true
type: Opaque
data:
password: bmV3LXNlY3JldA==
В Deployment правится ссылка:
envFrom:
- secretRef:
name: db-password-v2 # было v1
Rollout катит новые Pod с обновлённым ключом, старый Secret можно удалить, когда ни одна реплика на него не смотрит.
Альтернатива (грубее, но работает) - kubectl delete secret и сразу
kubectl create secret. Уже запущенные Pod с этим Secret в volume
продолжат работать на старых данных, новые значения подхватят только
после пересоздания. Поэтому чище ротировать через envFrom и новый
rollout.
Что обычно ломается
- Поставили
immutable: trueв проде и забыли, что ротация теперь через новое имя. На любом обновлении прилетает Forbidden. kubectl applyпадает с ошибкой при попытке поменять что угодно внутриdata. Поведение by design.- Флаг захотели снять - нельзя. Только delete и создание заново.
Домашка
Теорию закрепляет задание на своём кластере: 2 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.
./run.sh start k8s-immutable-secret # развернуть стартовое состояние
./run.sh verify k8s-immutable-secret # проверить текущий шаг
Коротко
immutable: trueзапрещает менятьdata,stringDataиbinaryDataу Secret и ConfigMap.- Флаг можно включить на существующем объекте, выключить обратно нельзя.
- Метки и аннотации править по-прежнему можно.
- Kubelet перестаёт держать watch за таким объектом, что экономит запросы к API на больших кластерах.
- Обновление делают ротацией: новое имя, правка ссылки в Deployment, rollout, удаление старого объекта.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс