Приложениям в кластере Kubernetes нужны пароли, ключи API и другие секретные данные. Если хранить их в манифестах или создавать секреты Kubernetes вручную, значения будут расходиться между окружениями, а смена пароля будет требовать ручного обновления в каждом кластере.
С помощью этого руководства вы настроите синхронизацию секрета из Secret Management в секрет Kubernetes в кластере Managed Kubernetes на платформе Cloud.ru Evolution. Доступ к Secret Management получит отдельный сервисный аккаунт, которому разрешено читать только один секрет.
Все действия выполняются в личном кабинете, использование kubectl не требуется.
Вы будете использовать следующие сервисы и инструменты:
Secret Management — сервис для безопасного хранения секретов.
Managed Kubernetes — сервис управления кластерами Kubernetes на вычислительных ресурсах облака.
«SNAT-шлюзы» — сервис управления сетевыми шлюзами облака.
Плагин External Secrets Operator — оператор Kubernetes, который получает секреты из внешних хранилищ и создает на их основе секреты Kubernetes.
Шаги:
Зарегистрируйтесь в личном кабинете Cloud.ru.
Если вы уже зарегистрированы, войдите под своей учетной записью.
Убедитесь, что в проекте у вас есть права на создание кластеров Managed Kubernetes, сервисных аккаунтов и секретов Secret Management, например роль администратора проекта.
Создайте кластер и группу узлов с одним узлом.
Для сценария достаточно минимальной конфигурации мастер-узла и рабочего узла. Публичный IP-адрес кластеру не нужен.
Создайте SNAT-шлюз в той же зоне доступности, что и группа узлов.
Установите в кластер плагин External Secrets Operator с конфигурацией по умолчанию.
Дождитесь, пока плагин перейдет в статус «Установлен».
Создайте секрет со следующими параметрами:
Путь — eso-lab/db-credentials;
Значение секрета — значение в формате JSON:
{"username": "app","password": "lab-value-v1"}
На этом шаге вы создадите сервисный аккаунт, которому доступен только секрет eso-lab/db-credentials. Роли на весь проект аккаунту не назначаются.
Создайте сервисный аккаунт eso-lab-sa с уровнем «Проект».
На шаге настройки ролей не выбирайте роли.
Создайте ключ доступа для сервисного аккаунта.
Сохраните значения Key ID и Key Secret.
Назначьте сервисному аккаунту роль scsm.user на секрет eso-lab/db-credentials.
В кластере создаются два ресурса External Secrets Operator:
SecretStore — описывает подключение к Secret Management: проект и секрет Kubernetes с ключом доступа сервисного аккаунта.
ExternalSecret — указывает, какой секрет Secret Management получить и в какой секрет Kubernetes записать его значение.
External Secrets Operator от имени сервисного аккаунта с заданным интервалом запрашивает последнюю версию секрета в Secret Management. Если значение изменилось, оператор обновит секрет Kubernetes.
Чтобы применить манифест:
В личном кабинете перейдите в сервис Managed Kubernetes.
Откройте кластер Managed Kubernetes.
В меню слева выберите любой тип ресурса, например Cluster → Namespaces.
Нажмите Применить YAML.
Вставьте манифест в YAML-редактор.
Нажмите Применить.
Появится сообщение, что ресурс создан.
Тип ресурса задается в манифесте и не зависит от раздела, в котором нажата кнопка Применить YAML. Таким способом создаются и ресурсы SecretStore, и ExternalSecret, для которых в меню кластера нет отдельного раздела.
Манифесты также можно применить с помощью kubectl, если вы подключились к кластеру.
Примените манифесты в следующем порядке:
Создайте пространство имен eso-lab:
apiVersion: v1kind: Namespacemetadata:name: eso-lab
Создайте секрет Kubernetes с ключом доступа сервисного аккаунта:
apiVersion: v1kind: Secretmetadata:name: sm-credentialsnamespace: eso-labtype: OpaquestringData:key_id: <key_id>key_secret: <key_secret>
Где:
<key_id> — Key ID ключа доступа сервисного аккаунта;
<key_secret> — Key Secret ключа доступа сервисного аккаунта.
Создайте секрет до создания SecretStore. Если SecretStore не найдет секрет с ключом, External Secrets Operator будет повторять подключение с увеличивающимся интервалом, и синхронизация начнется с задержкой до нескольких минут.
Создайте SecretStore:
apiVersion: external-secrets.io/v1kind: SecretStoremetadata:name: cloudru-smnamespace: eso-labspec:provider:cloudrusm:auth:secretRef:accessKeyIDSecretRef:name: sm-credentialskey: key_idaccessKeySecretSecretRef:name: sm-credentialskey: key_secretprojectID: <project_id>
Где <project_id> — идентификатор проекта, в котором создан секрет.
SecretStore доступен только в своем пространстве имен. Ключ сервисного аккаунта не будет доступен ресурсам из других пространств имен.
Проверьте подключение:
В меню кластера выберите Cluster → Events.
В фильтре Namespace выберите eso-lab.
Найдите событие, у которого в поле Object указано cloudru-sm, а в поле Object Type — SecretStore.
Если подключение настроено, в поле Reason будет указано Valid, а в поле Message — store validated.
Примените манифест, чтобы создать ExternalSecret:
apiVersion: external-secrets.io/v1kind: ExternalSecretmetadata:name: db-credentialsnamespace: eso-labspec:refreshInterval: 1msecretStoreRef:name: cloudru-smkind: SecretStoretarget:name: db-credentialscreationPolicy: OwnerdataFrom:- extract:key: eso-lab/db-credentials
Где:
refreshInterval — интервал, с которым External Secrets Operator проверяет значение секрета в Secret Management.
target.name — название секрета Kubernetes, который создаст External Secrets Operator.
dataFrom.extract.key — путь секрета в Secret Management. Вместо пути можно указать UUID секрета.
dataFrom.extract перенесет в секрет Kubernetes все поля JSON-значения секрета.
В меню кластера выберите Configuration → Secrets.
Откройте секрет db-credentials в пространстве имен eso-lab.
В блоке Данные отобразятся ключи username и password. Значения будут показаны в кодировке Base64: YX** для app и bGFiLXZh******** для lab-value-v1.
Добавьте версию секрета eso-lab/db-credentials с новым значением:
{"username": "app","password": "lab-value-v2"}
Дождитесь окончания обновления данных — время ожидания будет указанов поле refreshInterval.
Откройте секрет db-credentials в Configuration → Secrets.
Значение password изменится на bGFiLXZh******** — это lab-value-v2 в кодировке Base64.
External Secrets Operator обновляет секрет Kubernetes, но не перезапускает поды. Секрет, смонтированный в под как том, обновится автоматически. Переменные окружения из секрета обновятся только после перезапуска пода. Чтобы перезапускать поды при изменении секрета, используйте плагин Reloader.
Сервисному аккаунту eso-lab-sa доступен только секрет eso-lab/db-credentials. Чтобы убедиться в этом, запросите другой секрет проекта.
Примените манифест, чтобы создать ExternalSecret, который ссылается на другой секрет:
apiVersion: external-secrets.io/v1kind: ExternalSecretmetadata:name: access-checknamespace: eso-labspec:refreshInterval: 1msecretStoreRef:name: cloudru-smkind: SecretStoretarget:name: access-checkcreationPolicy: OwnerdataFrom:- extract:key: <other_secret_path>
Где <other_secret_path> — путь любого другого секрета в проекте.
В меню кластера выберите Cluster → Events.
В фильтре Namespace выберите eso-lab.
Найдите событие, у которого в поле Object указано access-check, а в поле Object Type — ExternalSecret.
В поле Reason будет указано UpdateFailed, а в поле Message — ошибка PermissionDenied desc = permission denied.
Секрет Kubernetes access-check не будет создан.
Если ресурсы больше не нужны, удалите их:
Удалите кластер eso-lab.
Удалите сервисный аккаунт eso-lab-sa.
Удалите секрет eso-lab/db-credentials.
Вы научились:
Устанавливать External Secrets Operator в кластер Managed Kubernetes и подключать его к Secret Management.
Выдавать сервисному аккаунту доступ к одному секрету без роли на весь проект.
Синхронизировать секрет Secret Management с секретом Kubernetes и получать новые версии секрета автоматически.
Проверять состояние синхронизации в личном кабинете без kubectl.