Настройка интеграции с Vault в развёрнутом кластере

Пост-деплойная настройка интеграции HashiCorp Vault в клиентском кластере и на стороне Vault.

Когда использовать

Инструкция применяется после того, как клиентский кластер создан с профилем, подготовленным по инструкции Интеграции с HashiCorp Vault, а сервис vault-secrets-operator развёрнут в неймспейсе vault-operator.


Общая схема

Настройка интеграции состоит из следующих этапов:


Шаг 1. Убедитесь, что сервис развёрнут

В развёрнутом клиентском кластере проверьте, что сервис vault-secrets-operator успешно установлен и созданы необходимые ресурсы в неймспейсе vault-operator.

Проверка Команда Ожидаемый результат
Неймспейс создан kubectl get ns vault-operator Неймспейс vault-operator присутствует в кластере
Pod сервиса запущен kubectl get pod -n vault-operator Pod сервиса находится в состоянии Running
ServiceAccount создан kubectl get sa -n vault-operator В неймспейсе vault-operator присутствует ServiceAccount сервиса. Имя ServiceAccount потребуется для настройки роли метода аутентификации Kubernetes на стороне Vault
Secret для ServiceAccount создан kubectl get secret -n vault-operator В неймспейсе vault-operator присутствует Secret типа kubernetes.io/service-account-token. Скопируйте имя Secret и используйте его на шаге 1.1

Шаг 1.1. Получите токен и CA-сертификат из Secret

После проверки созданных ресурсов получите из Secret данные для настройки метода аутентификации Kubernetes на стороне Vault в CLI или GUI.

Выполните команды для получения токена и CA-сертификата кластера Kubernetes:

kubectl get secret -n vault-operator <имя-secret> -o jsonpath='{.data.token}' | base64 --decode
kubectl get secret -n vault-operator <имя-secret> -o jsonpath="{.data.ca\.crt}" | base64 --decode
Данные Назначение
Токен ServiceAccount (token) Используется в поле Token Reviewer JWT при настройке метода аутентификации Kubernetes в Vault
Сертификат центра сертификации Kubernetes (ca.crt) Используется в поле Kubernetes CA Certificate при настройке метода аутентификации Kubernetes в Vault
  1. В интерфейсе кластера перейдите в неймспейс vault-operator.
  2. Откройте раздел Хранилище и выберите Secret с именем vault-secret.
  3. Скопируйте и сохраните значения ключей ca.crt и token.

Шаг 2. Настройте интеграцию на стороне Vault

После получения токена и CA-сертификата Kubernetes перейдите к настройке интеграции на стороне сервера Vault. Далее описан сценарий настройки в графическом интерфейсе. Инструкция по настройке метода аутентификации Kubernetes через интерфейс командной строки приведена в документации HashiCorp Vault: Kubernetes auth method.

Шаг 2.1. Создайте метод аутентификации Kubernetes

Создайте новый метод аутентификации типа Kubernetes, который позволит проходить аутентификацию с помощью токена ServiceAccount.

В интерфейсе Vault:

  1. Откройте раздел AccessAuth Methods.
  2. Нажмите Enable new method и выберите тип Kubernetes.
  3. Укажите путь в поле Path и нажмите Enable method.
Поле Значение Где получить значение
Path Рекомендуется использовать путь, отличный от значения по умолчанию, например имя клиентского кластера Задаётся администратором вручную при создании метода аутентификации Kubernetes в Vault
  1. Когда метод создан, на вкладке Configuration укажите параметры подключения к Kubernetes API:
Поле Значение Где получить значение
Kubernetes CA Certificate Значение ca.crt См. шаг 1.1
Token Reviewer JWT Токен ServiceAccount См. шаг 1.1
Kubernetes host Адрес Kubernetes API-сервера с указанием порта, например https://10.11.12.13:6443 В графическом интерфейсе используйте значение поля «API-сервер» в блоке Описание на дашборде клиентского кластера. Для консоли получите kubeconfig и определите адрес API-сервера командой kubectl cluster-info

Шаг 2.2. Настройте Secrets Engine

Создайте Secrets Engine типа KV или используйте существующий.

Чтобы настроить Secrets Engine в интерфейсе Vault, перейдите в раздел Secrets Engines и нажмите Enable new engine. Выберите тип KV и укажите путь, по которому будет доступно хранилище секретов, например kv.

Шаг 2.3. Создайте политику доступа

Создайте политику доступа (policy) или используйте существующую, которая разрешает чтение секретов в необходимом Secrets Engine.

Для создания политики доступа в интерфейсе Vault перейдите в раздел Policies и нажмите Create ACL policy. Укажите имя политики и добавьте правила доступа к Secrets Engine.

Пример политики для KV v2:

path "kv/data/*" { capabilities = ["read", "list"] }

Шаг 2.4. Создайте роль

Для созданного метода аутентификации Kubernetes добавьте роль. В интерфейсе Vault:

  1. Перейдите в раздел AccessAuth Methods.
  2. Откройте созданный метод аутентификации Kubernetes.
  3. На вкладке Roles нажмите Create role. Для роли обязательно заполните:
Поле Описание Где получить значение
Name Имя роли, которое потребуется указать в параметре kubernetes.role ресурса VaultAuth Задаётся администратором вручную при создании роли в Vault
Bound service account names Имя ServiceAccount в неймспейсе vault-operator Получить в клиентском кластере командой kubectl get sa -n vault-operator
Bound service account namespaces Имя неймспейса vault-operator, в котором создан ServiceAccount Использовать значение vault-operator, так как сервис разворачивается в этом неймспейсе
Generated Token's Policies Имя созданной политики доступа Использовать имя политики, созданной на шаге 2.3

Шаг 3. Создание VaultAuth и базовая проверка интеграции

Вы можете выполнить создание VaultAuth и базовую проверку интеграции через VaultStaticSecret вручную или одним запуском с помощью Bash-скрипта.

Шаг 3.1 Создайте VaultAuth

После настройки аутентификации на стороне Vault завершите интеграцию: создайте VaultAuth в развёрнутом клиентском кластере.

Пример VaultAuth:

apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
  name: vault-auth-name
  namespace: vault-operator
spec:
  kubernetes:
    role: role-name
    serviceAccount: name-service-account
    tokenExpirationSeconds: 600
  method: kubernetes
  mount: path-name
  vaultConnectionRef: vault-connection-name
Поле Тип данных Описание
kubernetes.role string Имя роли, созданной для метода аутентификации Kubernetes на стороне Vault
kubernetes.serviceAccount string Имя ServiceAccount для аутентификации в Vault, созданного в неймспейсе vault-operator при установке vault-secrets-operator
kubernetes.tokenExpirationSeconds integer Время жизни токена, используемого для аутентификации в Vault
method string Метод аутентификации в Vault. Должен быть указан kubernetes
mount string Путь метода аутентификации Kubernetes, созданного на стороне Vault
vaultConnectionRef string Имя VaultConnection, созданного в кластере при инициализации

Важно: значения в spec.mount и spec.kubernetes.role должны совпадать с настройками конфигурации созданного метода аутентификации Kubernetes на стороне Vault.


Шаг 3.2 Проверьте интеграцию

Предварительно убедитесь:

Проверка Команда Ожидаемый результат
Статус VaultConnection kubectl get vaultconnection -n vault-operator <vault-connection-name> -o yaml В status отсутствуют ошибки и в параметре valid установлено значение true
Статус VaultAuth kubectl get vaultauth -n vault-operator <vault-auth-name> -o yaml В status отсутствуют ошибки аутентификации и в параметре valid установлено значение true
Логи vault-secrets-operator kubectl logs -n vault-operator <vault-secrets-operator-pod> Нет ошибок подключения и аутентификации в Vault

При необходимости проверьте настроенную интеграцию с помощью тестового ресурса VaultStaticSecret. Перед применением манифеста убедитесь, что по указанному пути в Vault существует секрет и политика доступа разрешает его чтение.

Пример VaultStaticSecret:

apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
  name: vault-static-secret
  namespace: vault-operator
spec:
  destination:
    create: true
    name: secret-kubernetes-name
    overwrite: true
  mount: kv
  path: secret-name
  refreshAfter: 10s
  type: kv-v2
  vaultAuthRef: vault-auth-name
Поле Тип Пример значения Описание
destination object Параметры Secret Kubernetes, который будет создан или обновлён на основе данных из Vault
destination.create boolean true Создать Kubernetes Secret автоматически, если такого Secret ещё нет
destination.name string secret-kubernetes-name Имя Secret, который будет создан в кластере
destination.overwrite boolean true Перезаписывать существующий Kubernetes Secret при обновлении данных
mount string kv Путь Secrets Engine в Vault
path string secret-name Путь к секрету внутри указанного Secrets Engine
refreshAfter string 10s Интервал, через который оператор повторно проверяет и синхронизирует данные из Vault
type string kv-v2 Тип Secrets Engine в Vault
vaultAuthRef string vault-auth-name Имя созданного VaultAuth, используемого для аутентификации в Vault

После применения манифеста проверьте, что в неймспейсе vault-operator появился Kubernetes Secret с именем, указанным в destination.name.

kubectl get secret -n vault-operator

Вместо шагов 3 и 4: примените Bash-скрипт

Обратите внимание! Перед запуском скрипта проверьте значения переменных. Скрипт автоматически создаёт VaultAuth, проверяет состояние ресурсов интеграции и создаёт VaultStaticSecret, поэтому ошибка в параметрах может привести к некорректной настройке подключения к Vault.

Перед запуском скрипта подключитесь к клиентскому кластеру через kubeconfig.

Переменные, используемые в скрипте:

Переменная Значение по умолчанию Описание
VSO_NAMESPACE vault-operator Неймспейс, в котором развёрнут vault-secrets-operator
VAULTAUTH_NAME vault-auth-name Имя создаваемого ресурса VaultAuth
VAULT_ROLE Имя роли, созданной для метода аутентификации Kubernetes на стороне Vault
VSO_SERVICEACCOUNT vault-secrets-operator-controller-manager Имя ServiceAccount vault-secrets-operator, используемого для аутентификации в Vault
VAULT_AUTH_MOUNT Путь метода аутентификации Kubernetes, созданного на стороне Vault
VAULTCONNECTION_REF vault-connection-name Имя ресурса VaultConnection
K8S_TOKEN_EXPIRATION_SECONDS 600 Время жизни токена, используемого для аутентификации в Vault
CHECK_DELAY_SECONDS 10 Задержка в секундах перед проверкой статусов ресурсов после применения манифестов
CREATE_VAULTSTATICSECRET false Дополнительно создать VaultStaticSecret для проверки интеграции
VAULTSTATICSECRET_NAME vault-static-secret Имя создаваемого ресурса VaultStaticSecret
DESTINATION_SECRET_NAME secret-kubernetes-name Имя Kubernetes Secret, который будет создан оператором
DESTINATION_OVERWRITE true Перезаписывать существующий Kubernetes Secret при обновлении данных
KV_MOUNT kv Путь Secrets Engine в Vault
KV_PATH secret-name Путь к существующему секрету в Secrets Engine
REFRESH_AFTER 10s Интервал повторной синхронизации секрета
SECRET_ENGINE_TYPE kv-v2 Тип Secrets Engine в Vault
bash /dev/stdin <<'EOF'
set -euo pipefail

VSO_NAMESPACE="${VSO_NAMESPACE:-vault-operator}"
VAULTAUTH_NAME="${VAULTAUTH_NAME:-vault-auth-name}"
VAULTCONNECTION_REF="${VAULTCONNECTION_REF:-vault-connection-name}"
K8S_TOKEN_EXPIRATION_SECONDS="${K8S_TOKEN_EXPIRATION_SECONDS:-600}"
CHECK_DELAY_SECONDS="${CHECK_DELAY_SECONDS:-10}"
VSO_SERVICEACCOUNT="${VSO_SERVICEACCOUNT:-vault-secrets-operator-controller-manager}"

: "${VAULT_ROLE:?Задайте VAULT_ROLE, например vault-role-name}"
: "${VAULT_AUTH_MOUNT:?Задайте VAULT_AUTH_MOUNT, например cluster-name}"

CREATE_VAULTSTATICSECRET="${CREATE_VAULTSTATICSECRET:-false}"
VAULTSTATICSECRET_NAME="${VAULTSTATICSECRET_NAME:-vault-static-secret}"
DESTINATION_SECRET_NAME="${DESTINATION_SECRET_NAME:-secret-kubernetes-name}"
DESTINATION_OVERWRITE="${DESTINATION_OVERWRITE:-true}"
KV_MOUNT="${KV_MOUNT:-kv}"
KV_PATH="${KV_PATH:-secret-name}"
REFRESH_AFTER="${REFRESH_AFTER:-10s}"
SECRET_ENGINE_TYPE="${SECRET_ENGINE_TYPE:-kv-v2}"

kubectl apply -f - <<EOF2
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
  name: ${VAULTAUTH_NAME}
  namespace: ${VSO_NAMESPACE}
spec:
  kubernetes:
    role: ${VAULT_ROLE}
    serviceAccount: ${VSO_SERVICEACCOUNT}
    tokenExpirationSeconds: ${K8S_TOKEN_EXPIRATION_SECONDS}
  method: kubernetes
  mount: ${VAULT_AUTH_MOUNT}
  vaultConnectionRef: ${VAULTCONNECTION_REF}
EOF2

sleep "${CHECK_DELAY_SECONDS}"

echo "Проверка статуса VaultConnection"
kubectl get vaultconnection -n "${VSO_NAMESPACE}" "${VAULTCONNECTION_REF}" -o yaml

echo "Проверка статуса VaultAuth"
kubectl get vaultauth -n "${VSO_NAMESPACE}" "${VAULTAUTH_NAME}" -o yaml

if [ "${CREATE_VAULTSTATICSECRET}" = "true" ]; then
  kubectl apply -f - <<EOF2
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
  name: ${VAULTSTATICSECRET_NAME}
  namespace: ${VSO_NAMESPACE}
spec:
  destination:
    create: true
    name: ${DESTINATION_SECRET_NAME}
    overwrite: ${DESTINATION_OVERWRITE}
  mount: ${KV_MOUNT}
  path: ${KV_PATH}
  refreshAfter: ${REFRESH_AFTER}
  type: ${SECRET_ENGINE_TYPE}
  vaultAuthRef: ${VAULTAUTH_NAME}
EOF2

  sleep "${CHECK_DELAY_SECONDS}"

  echo "Проверка созданного Kubernetes Secret"
  kubectl get secret -n "${VSO_NAMESPACE}" "${DESTINATION_SECRET_NAME}"
fi
EOF