====== Hashicorp Vault в Kubernetes: установка и интеграция ======
Vault - отличный инструмент для управления секретами, который кроме всего можно еще и интегрировать с Kubernetes. В этой статье разберём, как установить Vault в Kubernetes и как связать секреты Vault с аннотациями Kubernetes.
=== Установка Vault в Kubernetes ===
Есть несколько способов установить Vault в Kubernetes, но один из самых распространённых - через пакетный менеджер Helm. Helm упрощает процесс деплоя за счёт системы шаблонов для генерации Kubernetes-манифестов.
Чтобы установить Vault в Kubernetes с помощью Helm, сделайте следующее:
**Установите Helm**
Helm должен быть установлен на вашей локальной машине. Следуйте официальной инструкции по установке Helm для вашей операционной системы.
**Добавьте репозиторий Helm от HashiCorp**
Выполните следующую команду, чтобы добавить репозиторий HashiCorp в Helm:
helm repo add hashicorp https://helm.releases.hashicorp.com
**Установите Vault**
Выполните следующую команду, чтобы установить Vault в Kubernetes:
helm install vault hashicorp/vault \
--set "server.dev.enabled=true"
Эта команда устанавливает Vault с включённым dev-сервером, что удобно для тестов и разработки. В продакшене так делать не стоит - там лучше использовать постоянное хранилище, например, Amazon S3 или Azure Blob Storage.
=== Интеграция секретов Vault с аннотациями Kubernetes ===
Когда Vault установлен в кластере, можно использовать его для управления секретами и интеграции этих секретов с аннотациями Kubernetes. Аннотации в Kubernetes - это пары ключ-значение, которые можно добавлять к объектам вроде pod'ов, deployment'ов и сервисов. Они дают дополнительную информацию об объекте и могут использоваться, например, для мониторинга, отладки или конфигурации.
Чтобы интегрировать секреты Vault с аннотациями Kubernetes, сделайте следующее:
**Включите Kubernetes-аутентификацию в Vault**
Запустите команду:
vault auth enable kubernetes
Это включает метод аутентификации через Kubernetes в Vault.
**Настройте Kubernetes-аутентификацию**
Выполните следующую команду:
vault write auth/kubernetes/config \
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
kubernetes_host="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT_HTTPS" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Здесь Vault настраивается на использование токена сервисного аккаунта Kubernetes, а также указываются адрес и порт API-сервера Kubernetes и путь к CA-сертификату. Всё это Vault будет использовать для проверки подлинности.
**Создайте политику и токен в Vault**
Выполните команды:
vault policy write myapp-policy - <
Здесь создаётся политика ''myapp-policy'', которая даёт права только на чтение секретов по пути ''secret/myapp/*''. Также создаётся токен с этой политикой и временем жизни 1 час.
**Создайте секрет Kubernetes с этим токеном Vault**
Выполните:
kubectl create secret generic vault-auth \
--from-literal "token=$(vault print-token)"
Это создаёт Kubernetes-секрет ''vault-auth'', в котором токен Vault передаётся как обычное значение.
**Добавьте аннотации к объекту Kubernetes**
Добавьте следующие аннотации в объект Kubernetes - например, Pod или Deployment - чтобы получить секрет из Vault и пробросить его как переменную окружения:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-myapp-password: "secret/myapp/password"
vault.hashicorp.com/agent-inject-template-myapp-password: |
{{- with secret "secret/data/myapp-password" -}}
export MY_SECRET_PASSWORD={{ .Data.password }}
{{- end }}
Эти аннотации указывают Vault Agent'у, что нужно инжектировать секрет ''secret/myapp/password'' и пробросить его в переменную окружения ''MY_SECRET_PASSWORD'' с помощью шаблона.
**Задеплойте объект Kubernetes**
После добавления аннотаций задеплойте объект. Vault Agent в виде побочного контейнера (sidecar) сам заберёт секрет из Vault и вставит его в основной контейнер как переменную окружения.
Пример манифеста Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-myapp-password: "secret/myapp/password"
vault.hashicorp.com/agent-inject-template-myapp-password: |
{{- with secret "secret/myapp/password" }}
MYAPP_PASSWORD={{ .Data.password }}
{{- end }}
spec:
containers:
- name: myapp
image: myapp:v1
env:
- name: MYAPP_PASSWORD
valueFrom:
secretKeyRef:
name: vault-auth
key: token
- name: vault-agent
image: vault:1.7.1
command: ["/bin/sh", "-c"]
args:
- "vault agent -config /etc/vault/config.hcl"
volumeMounts:
- name: vault-config
mountPath: /etc/vault
volumes:
- name: vault-config
configMap:
name: vault-agent-config
В этом примере деплой включает два контейнера: основной контейнер приложения ''myapp'' и побочный контейнер с Vault Agent'ом. Аннотации указываются в метаданных шаблона pod’а и описывают, откуда брать секрет в Vault и как именно его вставлять в контейнер в виде переменной окружения.
==== Заключение ====
Интеграция Vault с Kubernetes даёт безопасный и гибкий способ управления секретами в кластере. С Vault вы централизованно управляете секретами через API или UI, а Kubernetes-аннотации позволяют автоматически инжектировать эти секреты в приложения. Если пройти по шагам из этой статьи, можно без особых сложностей установить Vault в Kubernetes и наладить доставку секретов в поды через аннотации.