Настройка интеграции с Vault в развёрнутом кластере
Пост-деплойная настройка интеграции HashiCorp Vault в клиентском кластере и на стороне Vault.
Когда использовать
Инструкция применяется, когда клиентский кластер уже создан с профилем по инструкции Настройка интеграции с HashiCorp Vault в профиле кластера, а сервис vault-secrets-operator уже развёрнут в неймспейсе vault-operator.
Общая схема
Настройка интеграции состоит из следующих этапов:
- Шаг 1. Убедитесь, что сервис развёрнут и получите токен и CA-сертификат из Secret.
- Шаг 2. Настройте интеграцию на стороне Vault
- Шаг 3. Создайте VaultAuth и проверьте интеграцию.
Шаг 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 |
- В интерфейсе кластера перейдите в неймспейс
vault-operator. - Откройте раздел Хранилище и выберите Secret с именем
vault-secret. - Скопируйте и сохраните значения ключей
ca.crtиtoken.
Шаг 2. Настройте интеграцию на стороне Vault
После получения токена и CA-сертификата Kubernetes перейдите к настройке интеграции на стороне сервера Vault. Далее описан сценарий настройки в графическом интерфейсе. Инструкция по настройке метода аутентификации Kubernetes через интерфейс командной строки приведена в документации HashiCorp Vault: Kubernetes auth method.
Шаг 2.1. Создайте метод аутентификации Kubernetes
Создайте новый метод аутентификации типа Kubernetes, который позволит проходить аутентификацию с помощью токена ServiceAccount.
В интерфейсе Vault:
- Откройте раздел Access → Auth Methods.
- Нажмите Enable new method и выберите тип Kubernetes.
- Укажите путь в поле Path и нажмите Enable method.
| Поле | Значение | Где получить значение |
|---|---|---|
Path | Рекомендуется использовать путь, отличный от значения по умолчанию, например имя клиентского кластера | Задаётся администратором вручную при создании метода аутентификации Kubernetes в Vault |
- Когда метод создан, на вкладке 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:
- Перейдите в раздел Access → Auth Methods.
- Откройте созданный метод аутентификации Kubernetes.
- На вкладке 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