Настройка интеграции с 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