Настройка интеграции с 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-operatorPod сервиса находится в состоянии 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. Откройте раздел Access → Auth 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. Перейдите в раздел Access → Auth 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.rolestringИмя роли, созданной для метода аутентификации Kubernetes на стороне Vault
kubernetes.serviceAccountstringИмя ServiceAccount для аутентификации в Vault, созданного в неймспейсе vault-operator при установке vault-secrets-operator
kubernetes.tokenExpirationSecondsintegerВремя жизни токена, используемого для аутентификации в Vault
methodstringМетод аутентификации в Vault. Должен быть указан kubernetes
mountstringПуть метода аутентификации Kubernetes, созданного на стороне Vault
vaultConnectionRefstringИмя VaultConnection, созданного в кластере при инициализации

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


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

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

ПроверкаКомандаОжидаемый результат
Статус VaultConnectionkubectl get vaultconnection -n vault-operator <vault-connection-name> -o yamlВ status отсутствуют ошибки и в параметре valid установлено значение true
Статус VaultAuthkubectl get vaultauth -n vault-operator <vault-auth-name> -o yamlВ status отсутствуют ошибки аутентификации и в параметре valid установлено значение true
Логи vault-secrets-operatorkubectl 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
ПолеТипПример значенияОписание
destinationobject—Параметры Secret Kubernetes, который будет создан или обновлён на основе данных из Vault
destination.createbooleantrueСоздать Kubernetes Secret автоматически, если такого Secret ещё нет
destination.namestringsecret-kubernetes-nameИмя Secret, который будет создан в кластере
destination.overwritebooleantrueПерезаписывать существующий Kubernetes Secret при обновлении данных
mountstringkvПуть Secrets Engine в Vault
pathstringsecret-nameПуть к секрету внутри указанного Secrets Engine
refreshAfterstring10sИнтервал, через который оператор повторно проверяет и синхронизирует данные из Vault
typestringkv-v2Тип Secrets Engine в Vault
vaultAuthRefstringvault-auth-nameИмя созданного VaultAuth, используемого для аутентификации в Vault

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

kubectl get secret -n vault-operator

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

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

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

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

ПеременнаяЗначение по умолчаниюОписание
VSO_NAMESPACEvault-operatorНеймспейс, в котором развёрнут vault-secrets-operator
VAULTAUTH_NAMEvault-auth-nameИмя создаваемого ресурса VaultAuth
VAULT_ROLE—Имя роли, созданной для метода аутентификации Kubernetes на стороне Vault
VSO_SERVICEACCOUNTvault-secrets-operator-controller-managerИмя ServiceAccount vault-secrets-operator, используемого для аутентификации в Vault
VAULT_AUTH_MOUNT—Путь метода аутентификации Kubernetes, созданного на стороне Vault
VAULTCONNECTION_REFvault-connection-nameИмя ресурса VaultConnection
K8S_TOKEN_EXPIRATION_SECONDS600Время жизни токена, используемого для аутентификации в Vault
CHECK_DELAY_SECONDS10Задержка в секундах перед проверкой статусов ресурсов после применения манифестов
CREATE_VAULTSTATICSECRETfalseДополнительно создать VaultStaticSecret для проверки интеграции
VAULTSTATICSECRET_NAMEvault-static-secretИмя создаваемого ресурса VaultStaticSecret
DESTINATION_SECRET_NAMEsecret-kubernetes-nameИмя Kubernetes Secret, который будет создан оператором
DESTINATION_OVERWRITEtrueПерезаписывать существующий Kubernetes Secret при обновлении данных
KV_MOUNTkvПуть Secrets Engine в Vault
KV_PATHsecret-nameПуть к существующему секрету в Secrets Engine
REFRESH_AFTER10sИнтервал повторной синхронизации секрета
SECRET_ENGINE_TYPEkv-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