Облачная платформаEvolution

Синхронизация секретов Secret Management с кластером Managed Kubernetes


Приложениям в кластере Kubernetes нужны пароли, ключи API и другие секретные данные. Если хранить их в манифестах или создавать секреты Kubernetes вручную, значения будут расходиться между окружениями, а смена пароля будет требовать ручного обновления в каждом кластере.

С помощью этого руководства вы настроите синхронизацию секрета из Secret Management в секрет Kubernetes в кластере Managed Kubernetes на платформе Cloud.ru Evolution. Доступ к Secret Management получит отдельный сервисный аккаунт, которому разрешено читать только один секрет.

Все действия выполняются в личном кабинете, использование kubectl не требуется.

Вы будете использовать следующие сервисы и инструменты:

Шаги:

  1. Подготовьте кластер Managed Kubernetes.

  2. Создайте секрет в Secret Management.

  3. Создайте сервисный аккаунт с доступом к секрету.

  4. Подключите External Secrets Operator к Secret Management.

  5. Синхронизируйте секрет.

  6. Проверьте обновление секрета.

  7. Проверьте ограничение доступа.

  8. Удалите неиспользуемые ресурсы.

Перед началом работы

  1. Зарегистрируйтесь в личном кабинете Cloud.ru.

    Если вы уже зарегистрированы, войдите под своей учетной записью.

  2. Убедитесь, что в проекте у вас есть права на создание кластеров Managed Kubernetes, сервисных аккаунтов и секретов Secret Management, например роль администратора проекта.

1. Подготовьте кластер Managed Kubernetes

  1. Создайте кластер и группу узлов с одним узлом.

    Для сценария достаточно минимальной конфигурации мастер-узла и рабочего узла. Публичный IP-адрес кластеру не нужен.

  2. Создайте SNAT-шлюз в той же зоне доступности, что и группа узлов.

  3. Установите в кластер плагин External Secrets Operator с конфигурацией по умолчанию.

    Дождитесь, пока плагин перейдет в статус «Установлен».

2. Создайте секрет в Secret Management

  1. Создайте секрет со следующими параметрами:

    • Путь — eso-lab/db-credentials;

    • Значение секрета — значение в формате JSON:

      {
      "username": "app",
      "password": "lab-value-v1"
      }

3. Создайте сервисный аккаунт с доступом к секрету

На этом шаге вы создадите сервисный аккаунт, которому доступен только секрет eso-lab/db-credentials. Роли на весь проект аккаунту не назначаются.

  1. Создайте сервисный аккаунт eso-lab-sa с уровнем «Проект».

    На шаге настройки ролей не выбирайте роли.

  2. Создайте ключ доступа для сервисного аккаунта.

    Внимание

    Сохраните значения Key ID и Key Secret.

  3. Назначьте сервисному аккаунту роль scsm.user на секрет eso-lab/db-credentials.

4. Подключите External Secrets Operator к Secret Management

В кластере создаются два ресурса External Secrets Operator:

  • SecretStore — описывает подключение к Secret Management: проект и секрет Kubernetes с ключом доступа сервисного аккаунта.

  • ExternalSecret — указывает, какой секрет Secret Management получить и в какой секрет Kubernetes записать его значение.

External Secrets Operator от имени сервисного аккаунта с заданным интервалом запрашивает последнюю версию секрета в Secret Management. Если значение изменилось, оператор обновит секрет Kubernetes.

Чтобы применить манифест:

  1. В личном кабинете перейдите в сервис Managed Kubernetes.

  2. Откройте кластер Managed Kubernetes.

  3. В меню слева выберите любой тип ресурса, например Cluster → Namespaces.

  4. Нажмите Применить YAML.

  5. Вставьте манифест в YAML-редактор.

  6. Нажмите Применить.

    Появится сообщение, что ресурс создан.

    Тип ресурса задается в манифесте и не зависит от раздела, в котором нажата кнопка Применить YAML. Таким способом создаются и ресурсы SecretStore, и ExternalSecret, для которых в меню кластера нет отдельного раздела.

    Подсказка

    Манифесты также можно применить с помощью kubectl, если вы подключились к кластеру.

  7. Примените манифесты в следующем порядке:

    1. Создайте пространство имен eso-lab:

      apiVersion: v1
      kind: Namespace
      metadata:
      name: eso-lab
    2. Создайте секрет Kubernetes с ключом доступа сервисного аккаунта:

      apiVersion: v1
      kind: Secret
      metadata:
      name: sm-credentials
      namespace: eso-lab
      type: Opaque
      stringData:
      key_id: <key_id>
      key_secret: <key_secret>

      Где:

      • <key_id> — Key ID ключа доступа сервисного аккаунта;

      • <key_secret> — Key Secret ключа доступа сервисного аккаунта.

      Подсказка

      Создайте секрет до создания SecretStore. Если SecretStore не найдет секрет с ключом, External Secrets Operator будет повторять подключение с увеличивающимся интервалом, и синхронизация начнется с задержкой до нескольких минут.

    3. Создайте SecretStore:

      apiVersion: external-secrets.io/v1
      kind: SecretStore
      metadata:
      name: cloudru-sm
      namespace: eso-lab
      spec:
      provider:
      cloudrusm:
      auth:
      secretRef:
      accessKeyIDSecretRef:
      name: sm-credentials
      key: key_id
      accessKeySecretSecretRef:
      name: sm-credentials
      key: key_secret
      projectID: <project_id>

      Где <project_id> — идентификатор проекта, в котором создан секрет.

      SecretStore доступен только в своем пространстве имен. Ключ сервисного аккаунта не будет доступен ресурсам из других пространств имен.

  8. Проверьте подключение:

    1. В меню кластера выберите Cluster → Events.

    2. В фильтре Namespace выберите eso-lab.

    3. Найдите событие, у которого в поле Object указано cloudru-sm, а в поле Object Type — SecretStore.

    Если подключение настроено, в поле Reason будет указано Valid, а в поле Message — store validated.

5. Синхронизируйте секрет

  1. Примените манифест, чтобы создать ExternalSecret:

    apiVersion: external-secrets.io/v1
    kind: ExternalSecret
    metadata:
    name: db-credentials
    namespace: eso-lab
    spec:
    refreshInterval: 1m
    secretStoreRef:
    name: cloudru-sm
    kind: SecretStore
    target:
    name: db-credentials
    creationPolicy: Owner
    dataFrom:
    - 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-значения секрета.

  2. В меню кластера выберите Configuration → Secrets.

  3. Откройте секрет db-credentials в пространстве имен eso-lab.

    В блоке Данные отобразятся ключи username и password. Значения будут показаны в кодировке Base64: YX** для app и bGFiLXZh******** для lab-value-v1.

6. Проверьте обновление секрета

  1. Добавьте версию секрета eso-lab/db-credentials с новым значением:

    {
    "username": "app",
    "password": "lab-value-v2"
    }
  2. Дождитесь окончания обновления данных — время ожидания будет указанов поле refreshInterval.

  3. Откройте секрет db-credentials в Configuration → Secrets.

    Значение password изменится на bGFiLXZh******** — это lab-value-v2 в кодировке Base64.

Примечание

External Secrets Operator обновляет секрет Kubernetes, но не перезапускает поды. Секрет, смонтированный в под как том, обновится автоматически. Переменные окружения из секрета обновятся только после перезапуска пода. Чтобы перезапускать поды при изменении секрета, используйте плагин Reloader.

7. Проверьте ограничение доступа

Сервисному аккаунту eso-lab-sa доступен только секрет eso-lab/db-credentials. Чтобы убедиться в этом, запросите другой секрет проекта.

  1. Примените манифест, чтобы создать ExternalSecret, который ссылается на другой секрет:

    apiVersion: external-secrets.io/v1
    kind: ExternalSecret
    metadata:
    name: access-check
    namespace: eso-lab
    spec:
    refreshInterval: 1m
    secretStoreRef:
    name: cloudru-sm
    kind: SecretStore
    target:
    name: access-check
    creationPolicy: Owner
    dataFrom:
    - extract:
    key: <other_secret_path>

    Где <other_secret_path> — путь любого другого секрета в проекте.

  2. В меню кластера выберите Cluster → Events.

  3. В фильтре Namespace выберите eso-lab.

  4. Найдите событие, у которого в поле Object указано access-check, а в поле Object Type — ExternalSecret.

    В поле Reason будет указано UpdateFailed, а в поле Message — ошибка PermissionDenied desc = permission denied.

    Секрет Kubernetes access-check не будет создан.

8. Удалите неиспользуемые ресурсы

Если ресурсы больше не нужны, удалите их:

  1. Удалите кластер eso-lab.

  2. Удалите SNAT-шлюз.

  3. Удалите сервисный аккаунт eso-lab-sa.

  4. Удалите секрет eso-lab/db-credentials.

Результат

Вы научились:

  • Устанавливать External Secrets Operator в кластер Managed Kubernetes и подключать его к Secret Management.

  • Выдавать сервисному аккаунту доступ к одному секрету без роли на весь проект.

  • Синхронизировать секрет Secret Management с секретом Kubernetes и получать новые версии секрета автоматически.

  • Проверять состояние синхронизации в личном кабинете без kubectl.