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. Аннотации в 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 - <<EOF path "secret/myapp/*" { capabilities = ["read"] } EOF vault token create -policy=myapp-policy -ttl=1h
Здесь создаётся политика 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 и наладить доставку секретов в поды через аннотации.