Как обновить секрет без перезапуска pod?

Ключевая идея — можно обновить содержимое Secret в Kubernetes без перезапуска Pod, но это зависит от способа потребления секрета контейнером. Если секрет смонтирован в виде файла (volume), kubelet периодически обновляет файлы в контейнере; если секрет передан как переменная окружения (env), то обновить её без перезапуска нельзя — переменные окружения вычисляются при запуске процесса.

1) Поведение для секретов, смонтированных как volume

  • При изменении объекта Secret в API kubelet обнаруживает это и обновляет файлы в примонтированной директории в поде (асинхронно). Это реализовано через атомическую замену файлов/ссылок, поэтому новое содержимое появляется в файловой системе контейнера.

  • Приложение должно считывать файл заново или уметь обрабатывать изменение (например, переоткрывать файл, смотреть на изменение содержимого). Если приложение читает файл только при старте — оно не увидит новый секрет.

  • subPath ломает автоперезапись: если вы монтируете конкретный файл через subPath, kubelet копирует файл один раз и дальше не обновляет его. Поэтому не используйте subPath, если хотите live-обновления.

2) Поведение для переменных окружения

  • Если секрет используется в env, его значение подставляется при старте контейнера и не меняется во время работы. Чтобы обновлённые значения в env появились — Pod нужно перезапустить (или заменить контейнер).

3) Как фактически обновить Secret (пример)

Обновить объект Secret в кластере можно командами:

# обновление/создание через apply

kubectl create secret generic my-secret \\
\--from-literal=password=newpass \\
\--dry-run=client -o yaml | kubectl apply -f -

# либо редактирование

kubectl edit secret my-secret

После изменения kubelet в скором времени (обычно в пределах минуты) обновит файлы в смонтированных volume внутри Pod'а.

4) Как приложение подхватывает изменения без перезапуска

  • Лучше всего — реализовать в приложении динамическую перезагрузку конфигурации при изменении файла (например, периодически перечитывать файл, реагировать на сигнал SIGHUP, или использовать файловые уведомления).

  • Учтите: kubelet делает атомическую замену файла (создаёт новую версию и меняет ссылку), поэтому простое inotify на файл может не сработать — лучше отслеживать событие в каталоге или реагировать на IN_MOVE/IN_CREATE. Эмпирически надёжнее реагировать на изменение родительской директории или периодически читать файл.

  • Альтернативный и удобный паттерн — sidecar-контейнер, который следит за файлом и при изменении шлёт сигнал в главный процесс (например, kill -HUP 1) или обновляет конфиг приложения.

5) Подводные камни

  • Если вы использовали subPath — обновлений не будет.

  • Если приложение кэширует значение в памяти и никогда не перечитывает файл — изменение не подействует.

  • Изменение Secret не меняет переменные окружения текущих контейнеров.

  • В некоторых CNI/платформах поведение обновления может отличаться по задержке, но в большинстве реализаций kubelet периодически синхронизирует.

6) Более надёжные/функциональные подходы (без рестарта Pod)

  • Secrets as files + приложение/sidecar, который умеет reload — стандартный и простой путь.

  • CSI Secrets Store (provider) — драйвер монтирует секреты из внешних хранилищ и поддерживает опции ротации/refresh; часто умеет обновлять контент по расписанию и уведомлять приложение.

  • Проекционные/short-lived токены (TokenRequest) для SA — kubelet автоматически обновляет токены сервис-аккаунта в поде (иногда используется для аутентификации без рестарта).

  • Если вы всё же хотите, чтобы изменение секрета автоматически перезапустило Deployment (чтобы env-переменные обновились), существуют паттерны/операторы, которые «подталкивают» rolling update при изменении Secret (это уже рестарт).

Пример простого манифеста Pod с монтированием секрета

volumes:
\- name: my-secret-vol
secret:
secretName: my-secret
containers:
\- name: app
image: myimage
volumeMounts:
\- name: my-secret-vol
mountPath: /etc/my-secret # приложение читает /etc/my-secret/password

Обновляете Secret через kubectl apply, kubelet обновит файлы; приложение должно уметь обнаружить и применить новые значения (рефреш/перечитывание или реакция на сигнал).