Модуль secrets-store-integration реализует доставку секретов для приложений в Deckhouse Kubernetes Platform (DKP) из внешнего хранилища, совместимого с API HashiCorp Vault.
Модуль предоставляет следующие возможности:
- доставка секретов в поды в виде примонтированных файлов или переменных окружения без хранения в etcd;
- автоматическое подключение к внутреннему экземпляру Deckhouse Stronghold без ручной настройки (режим
DiscoverLocalStronghold); - работа с любым Vault-совместимым хранилищем секретов в режиме
Manual; - автоматическое обновление примонтированных секретов каждые две минуты при изменении значения в хранилище;
- подмена команды запуска (entrypoint) для приложений, которые нельзя модифицировать для прямого чтения секретов из хранилища;
- доставка бинарных секретов в формате Base64 (например, JKS-хранилища, keytab-файлы для Kerberos) с автоматическим раскодированием.
Режим работы (Manual или DiscoverLocalStronghold) задаётся параметром settings.connectionConfiguration в настройках модуля.
Модуль работает со следующими кастомными ресурсами:
- SecretProviderClass — описывает, какие секреты и из какого внешнего хранилища нужно доставлять в под. В спецификации этого ресурса также определяются параметры подключения к источнику секретов и сопоставление путей в контейнере;
- SecretProviderClassPodStatus — содержит статус процесса монтирования секретов в под и диагностическую информацию;
- SecretsStoreImport — хранит сопоставление секретов между Vault-совместимым хранилищем и файлами в контейнерах.
Подробнее с описанием модуля можно ознакомиться в соответствующем разделе документации.
Архитектура модуля
Для упрощения схемы приняты следующие допущения:
- На схеме контейнеры разных подов показаны как взаимодействующие напрямую. Фактически обмен выполняется через соответствующие сервисы Kubernetes (внутренние балансировщики). Названия сервисов не указываются, если они очевидны из контекста. В остальных случаях название сервиса приводится над стрелкой.
- Поды могут быть запущены в нескольких репликах, однако на схеме каждый под показан в единственном экземпляре.
Архитектура модуля secrets-store-integration на уровне 2 модели C4 и его взаимодействия с другими компонентами DKP изображены на следующей диаграмме:
Компоненты модуля
Модуль secrets-store-integration состоит из следующих компонентов:
-
Csi-secrets-store (DaemonSet) — компонент работает на всех узлах кластера и реализует стандарт Container Storage Interface (CSI) для обеспечения доставки секретов в под в виде примонтированных файлов.
Csi-secrets-store выполняет следующие действия:
- регистрирует эфемерный CSI-драйвер
secrets-store.csi.deckhouse.ioв kubelet; - взаимодействует с vault-csi-provider для получения данных из хранилища секретов;
- монтирует секреты в виде файлов в под;
- выполняет ротацию секретов;
- отслеживает ресурсы Pod, CSIDriver и кастомный ресурс SecretProviderClass;
- работает с кастомным ресурсом SecretProviderClassPodStatus.
Компонент содержит следующие контейнеры:
- injector-puller — init-контейнер, который выполняет однократный запуск файл-инжектора (исполняемого файла для безопасного внедрения секретов из внешнего хранилища в окружение приложения внутри пода) из служебного образа
secrets-store-integration/env-injector. Однократный запуск необходим для предварительной загрузки этого образа на каждый узел кластера. Образ используется компонентом webhook для доставки секретов в пользовательское приложение в виде переменных окружения. - csi-node-driver-registrar — сайдкар-контейнер, регистрирующий CSI Node Plugin в kubelet. Вызывает RPC
GetPluginInfoиNodeGetInfoв контейнере secrets-store, чтобы получить информацию о плагине и узле; - secrets-store — основной контейнер;
- csi-livenessprobe — сайдкар-контейнер, который отслеживает состояние Unix-сокета CSI-драйвера и предоставляет HTTP-эндпоинт
/healthz, за которым следит kubelet. При неуспешном выполнении проверкиlivenessProbekubelet перезапускает под csi-secrets-store; - kube-rbac-proxy — сайдкар-контейнер с авторизующим прокси на основе Kubernetes RBAC для организации защищённого доступа к метрикам контейнера secrets-store.
- регистрирует эфемерный CSI-драйвер
-
Vault-csi-provider (DaemonSet) — компонент работает на всех узлах кластера и состоит из одного контейнера vault-csi-provider. Vault-csi-provider авторизуется в хранилище секретов, получает из него данные и передаёт их csi-secrets-store.
-
Ssi-controller (Deployment) — контроллер состоит из одного контейнера ssi-controller. Контроллер отслеживает кастомные ресурсы SecretsStoreImport и создаёт на их основе кастомные ресурсы SecretProviderClass.
-
Webhook (Deployment) — компонент реализует mutating-вебхуки для ресурсов Pod через механизм Mutating Admission Controllers.
Компонент изменяет манифест пода, если задана аннотация пода
secrets-store.deckhouse.io/role. При этом компонент выполняет следующие модификации манифеста пода:- добавляет init-контейнер, который копирует из служебного образа
secrets-store-integration/env-injectorстатически собранный файл-инжектор во временную директорию, общую для всех контейнеров пода; -
если в манифесте пода задана аннотация
secrets-store.deckhouse.io/env-from-pathили контейнер использует секреты из хранилища, то для каждого такого контейнера, включая init-контейнеры, компонент заменяет оригинальную команду запуска на запуск файл-инжектора.В качестве аргумента файл-инжектор получает оригинальную команду запуска. Если в манифесте пода у контейнера отсутствует команда запуска, компонент получает команду запуска из образа в хранилище образов контейнеров.
Компонент содержит следующие контейнеры:
- vault-secrets-webhook — основной контейнер;
- kube-rbac-proxy — сайдкар-контейнер с авторизующим прокси на основе Kubernetes RBAC для организации защищённого доступа к метрикам контейнера vault-secrets-webhook.
- добавляет init-контейнер, который копирует из служебного образа
Следующие компоненты не входят в состав модуля, но модуль влияет на них:
-
User-app — компонент представляет типовое приложение пользователя, в которое требуется доставить секреты в переменные окружения.
Компонент содержит следующие контейнеры:
- copy-env-injector — init-контейнер, добавленный компонентом webhook, который выполняет копирование исполняемого файл-инжектора из служебного образа
secrets-store-integration/env-injector; - <CONTAINER_NAME> — один или несколько контейнеров (в том числе init-контейнеры) оригинального приложения пользователя, команда запуска которых изменена компонентом webhook на запуск файл-инжектора.
Файл-инжектор авторизуется в хранилище секретов, получает данные, передаёт секреты приложению через переменные окружения и запускает исходную команду контейнера. Если указана аннотация
secrets-store.deckhouse.io/restart-on-secret-changeсо значениемwatch-for-leaseилиwatch-for-data, файл-инжектор выполняет ротацию секретов при их изменении в хранилище. - copy-env-injector — init-контейнер, добавленный компонентом webhook, который выполняет копирование исполняемого файл-инжектора из служебного образа
Взаимодействия модуля
Модуль secrets-store-integration взаимодействует со следующими компонентами:
-
Kube-apiserver:
- авторизация запросов;
- получение CSIDriver, Secret, ConfigMap и ServiceAccount;
- работа с кастомными ресурсами SecretsStoreImport, SecretProviderClass и SecretProviderClassPodStatus.
-
Хранилище образов — получение команды запуска из образа пользовательского контейнера.
-
Хранилище секретов — авторизация запросов и получение секретов.
С модулем взаимодействуют следующие внешние компоненты:
-
Kube-apiserver — вызов mutating-вебхука при создании ресурса Pod.
-
Kubelet:
- регистрирует Node Plugin;
- проверяет
livenessProbeCSI-драйвера; - вызывает RPC
NodePublishVolumeиNodeUnpublishVolumeв Node Plugin.
-
Prometheus-main — собирает метрики компонентов csi-secrets-store и webhook.