Como usar o Vault Agent para injetar segredos em pods Kubernetes
1. Fundamentos do Vault Agent e sua integração com Kubernetes
O Vault Agent é um componente do HashiCorp Vault projetado para automatizar a autenticação e injeção de segredos em aplicações. Quando integrado ao Kubernetes, ele opera como um sidecar dentro do pod, interceptando requisições de inicialização e injetando segredos diretamente no sistema de arquivos do contêiner principal.
A arquitetura da integração envolve três componentes principais:
- Vault Server: responsável por armazenar e gerenciar segredos, políticas e métodos de autenticação
- Vault Agent Injector: um mutating admission webhook que modifica dinamicamente as especificações dos pods
- Pods Kubernetes: que recebem os segredos injetados sem necessidade de alterações no código da aplicação
As vantagens sobre abordagens tradicionais são significativas. Enquanto variáveis de ambiente estáticas expõem segredos em texto plano e Secrets nativos do Kubernetes exigem gerenciamento manual de rotação, o Vault Agent oferece:
- Renovação automática de segredos dinâmicos
- Políticas granulares de acesso
- Auditoria completa de acessos
- Sem exposição de segredos em manifestos YAML
2. Pré-requisitos e configuração inicial do ambiente
Para começar, é necessário ter um cluster Kubernetes funcional e o Helm instalado. A instalação do Vault Server pode ser feita com:
helm repo add hashicorp https://helm.releases.hashicorp.com
helm install vault hashicorp/vault --set "server.dev.enabled=true"
Após a instalação, configure o Kubernetes Auth Method no Vault:
vault auth enable 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" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Crie uma política e role de acesso para os pods:
vault policy write app-policy - <<EOF
path "secret/data/app/*" {
capabilities = ["read"]
}
EOF
vault write auth/kubernetes/role/app-role \
bound_service_account_names=app-sa \
bound_service_account_namespaces=default \
policies=app-policy \
ttl=1h
3. Instalação e configuração do Vault Agent Injector
O Vault Agent Injector é um webhook que modifica pods automaticamente. Instale-o com:
helm install vault-agent-injector hashicorp/vault-agent-injector \
--set "agentImage.repository=hashicorp/vault" \
--set "agentImage.tag=1.15.0"
Para habilitar a injeção em um deployment, adicione annotations ao manifesto:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
namespace: default
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "app-role"
spec:
serviceAccountName: app-sa
containers:
- name: app-container
image: nginx:latest
Os parâmetros essenciais são:
vault.hashicorp.com/agent-inject: ativa o sidecar do Vault Agentvault.hashicorp.com/role: define qual role do Kubernetes Auth Method será usada
4. Injeção de segredos estáticos em volumes de arquivos
Para injetar segredos estáticos, utilize as annotations específicas:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "app-role"
vault.hashicorp.com/agent-inject-secret-db-creds: "secret/data/app/database"
vault.hashicorp.com/agent-inject-template-db-creds: |
{{- with secret "secret/data/app/database" -}}
{{ .Data.data.username }}:{{ .Data.data.password }}
{{- end -}}
O segredo será injetado em /vault/secrets/db-creds dentro do contêiner principal. O template personalizado permite formatar os dados conforme necessário.
Exemplo prático de injeção de credenciais de banco de dados:
vault kv put secret/data/app/database username=admin password=Str0ngP@ss
O arquivo gerado no pod conterá admin:Str0ngP@ss, pronto para ser lido pela aplicação.
5. Injeção de segredos dinâmicos com Vault Agent
Para segredos dinâmicos, configure o database secrets engine no Vault:
vault secrets enable database
vault write database/config/postgres-db \
plugin_name=postgresql-database-plugin \
allowed_roles="db-role" \
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb" \
username="vault-admin" \
password="admin-password"
vault write database/roles/db-role \
db_name=postgres-db \
creation_statements="CREATE USER \"{{name}}\" WITH PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
Configure o template no deployment para renovação automática:
vault.hashicorp.com/agent-inject-secret-db-creds: "database/creds/db-role"
vault.hashicorp.com/agent-inject-template-db-creds: |
{{- with secret "database/creds/db-role" -}}
{{ .Data.username }}:{{ .Data.password }}
{{- end -}}
O Vault Agent renovará automaticamente as credenciais antes do lease expirar, garantindo acesso contínuo ao banco de dados.
6. Estratégias de segurança e boas práticas
Para limitar permissões, crie políticas granulares:
vault policy write app-policy - <<EOF
path "secret/data/app/*" {
capabilities = ["read"]
allowed_parameters = {
"username" = []
"password" = []
}
}
EOF
Utilize vault.hashicorp.com/agent-run-as-user para executar o sidecar com usuário não-root:
vault.hashicorp.com/agent-run-as-user: "1000"
Combine com securityContext no contêiner principal:
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
Monitore leases e renove tokens automaticamente configurando vault.hashicorp.com/agent-extra-secret para tokens de renovação.
7. Troubleshooting e depuração da injeção de segredos
Verifique logs do sidecar para diagnosticar problemas:
kubectl logs <pod-name> -c vault-agent
Teste conectividade entre pod e Vault Server:
kubectl exec <pod-name> -c vault-agent -- vault status
Erros comuns incluem:
- Falha de autenticação: verifique se o service account está corretamente vinculado à role
- Template malformado: valide a sintaxe Go template com
vault readmanual - Políticas ausentes: confirme se a política permite acesso ao caminho do segredo
Para depurar, inspecione o webhook:
kubectl describe mutatingwebhookconfiguration vault-agent-injector-cfg
8. Casos de uso avançados e integração com ecossistema
Para injeção em múltiplos contêineres no mesmo pod, especifique annotations por contêiner:
vault.hashicorp.com/agent-inject-secret-container1: "secret/data/app1"
vault.hashicorp.com/agent-inject-secret-container2: "secret/data/app2"
Combine com service mesh como Istio para segurança adicional:
annotations:
sidecar.istio.io/inject: "true"
vault.hashicorp.com/agent-inject: "true"
Estratégias de rotação sem reinicialização de pods podem ser implementadas com:
vault.hashicorp.com/agent-inject-command: executa comando pós-injeçãovault.hashicorp.com/agent-inject-command-period: define período de verificação
Exemplo de rotação automática:
vault.hashicorp.com/agent-inject-command: "/bin/sh -c 'kill -HUP 1'"
vault.hashicorp.com/agent-inject-command-period: "30m"
Isso envia SIGHUP para o processo principal a cada 30 minutos, forçando recarga de configurações sem reinicializar o pod.
Referências
- HashiCorp Vault Agent Documentation — Documentação oficial completa sobre Vault Agent, incluindo modos de operação e configurações avançadas para Kubernetes
- Vault Agent Injector Guide — Tutorial prático da HashiCorp sobre instalação e configuração do Vault Agent Injector em clusters Kubernetes
- Kubernetes Auth Method Configuration — Guia detalhado sobre configuração do método de autenticação Kubernetes no Vault, incluindo service accounts e roles
- Vault Dynamic Database Secrets — Documentação sobre criação e gerenciamento de segredos dinâmicos de banco de dados com Vault
- Best Practices for Vault on Kubernetes — Guia de boas práticas da HashiCorp para deploy seguro de Vault em ambientes Kubernetes