Install
A instalação é bem simples e podemos fazer usando o helm o external secret operator. O que muda e trás um pouco mais de complexidade é configurar o provider e fazer o mapeamento das coisas.
O Operator instala o Custom Resources Definitions que fará a extensão da API e fará a implantação (deployment) do external secrets que é o controller que gerencia os objetos definidos.
helm install external-secrets \
external-secrets/external-secrets \
-n external-secrets \
--create-namespace \
Verificando o que temos no cluster.
❯ k get all -n external-secrets
NAME READY STATUS RESTARTS AGE
pod/external-secrets-547987d945-d88xw 1/1 Running 0 6h45m
pod/external-secrets-cert-controller-f79f56cf4-7r2mx 1/1 Running 0 6h45m
pod/external-secrets-webhook-6cb79956f4-6gqn2 1/1 Running 0 6h45m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/external-secrets-webhook ClusterIP 172.20.142.40 <none> 443/TCP 6h45m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/external-secrets 1/1 1 1 6h45m
deployment.apps/external-secrets-cert-controller 1/1 1 1 6h45m
deployment.apps/external-secrets-webhook 1/1 1 1 6h45m
NAME DESIRED CURRENT READY AGE
replicaset.apps/external-secrets-547987d945 1 1 1 6h45m
replicaset.apps/external-secrets-cert-controller-f79f56cf4 1 1 1 6h45m
replicaset.apps/external-secrets-webhook-6cb79956f4 1 1 1 6h45m
Podemos observar 3 pods.
- external-secrets: O core do external secrets operator. Esse é o pod que realmente busca os dados do Secrets Manager ou SSM.
- Busca os segredos nos backends (AWS, GCP, Vault, etc).
- Concilia os ExternalSecret com os Secret do K8s.
- Aplica refreshInterval, dataFrom, target.creationPolicy etc.
- Fica assistindo os recursos do tipo ExternalSecret/SecretStore/ClusterSecretStore
- external-secrets-cert-controller: Gerencia os certificados internos do ESO
- Criar e renovar os certificados TLS usados internamente pelos webhooks do ESO.
- Garante que a comunicação entre o K8s API Server e os webhooks seja segura (via certificados).
- Cria um Certificate e Issuer usando cert-manager ou com self-signed.
- external-secrets-webhook: Validação e segurança
Validar os manifests antes de aplicar (ValidatingWebhook e MutatingWebhook)
- Adicionar default values (como default refreshInterval, creationPolicy, etc).
- Fazer verificações como:
- “O tipo do backend é suportado?”
- “O recurso está bem formado?”
- Ele atua no momento em que você cria ou altera um recurso (tipo kubectl apply).
Se executarmos então o comando kubectl apply -f external-secret.yaml (um manifesto do tipo ExternalSecret por exemplo) o fluxo será.
-
Kubectl envia a request para a API do kubernetes.
-
Depois da autenticação e autorização que o kube-api faz, uma terceira etapa é o admission controller. O kube-api server verifica se existe algum webhook de validação/mutação registrado o Custom Resource ExternalSecret. O webhook é um serviço e nesse momento o
external-secrets-cert-controller
já esta atuando por trás dos panos, fazendo com que o webhook tenha certificados válidos e rotacionados com segurança. -
O
external-secrets-webhook
entra em ação- O API Server faz uma chamada HTTPS pro pod external-secrets-webhook.
- O webhook faz:
- Validação de campos obrigatórios
- Verifica se o tipo de backend é válido (aws, gcp, vault, etc)
- Adiciona valores default se você esqueceu (ex: refreshInterval: 1h)
- Se tudo ok, o webhook devolve um 200 OK e o recurso é persistido no etcd.
-
O
external-secrets (controller)
detecta a criação- O controller fica "vendo" todos os ExternalSecret, SecretStore, etc, via watch no K8s.
- Quando detecta um novo ExternalSecret, ele:
- Resolve o SecretStore/ClusterSecretStore
- Usa as credenciais configuradas (IAM, accessKey, IRSA, etc)
- Acessa o backend (ex: AWS SSM, Secrets Manager)
- Busca os valores usando:
- data
- dataFrom
- Constrói um Secret do K8s com os valores obtidos
Quando escalar o external-secrets-controller?
- Muitos segredos (~milhares) sendo reconciliados frequentemente.
- Latência muito alta pra buscar dados em backends.
- Uso multi-tenant pesado com muitos ExternalSecret rodando por segundo.
Aí você pode escalar o external-secrets controller com mais réplicas e usar a feature de sharding (tem suporte).
O external-secrets-cert-controller roda somente tarefas períodicas de certificado, não precisa de escala. O webhook é bem simples, só recebe chamadas do API Server é de baixa carga então no máximo 2 pods se necessário, mas não por carga, e sim por resilieência.
O que seria um values.yaml produtivo.
replicaCount: 2 # Alta disponibilidade do controller
resources:
limits:
cpu: 250m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
# Adiciona probes de health check
controllerManager:
container:
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
# Tolerations para permitir execução em nós específicos, como nodes de infra
# tolerations:
# - key: "dedicated"
# operator: "Equal"
# value: "infra"
# effect: "NoSchedule"
# Se quiser rodar só em nodes com uma label específica
# nodeSelector:
# node-role.kubernetes.io/infra: "true"
# Prioridade para o controller (evitar preempção)
priorityClassName: "system-cluster-critical"
# Webhook config
webhook:
replicaCount: 2
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
# Cert controller
certController:
replicaCount: 1
resources:
limits:
cpu: 50m
memory: 64Mi
requests:
cpu: 25m
memory: 32Mi
installCRDs: false
# (Opcional) Sharding — divide os ExternalSecrets entre réplicas
sharding:
enabled: true
replicaCount: 2 # Deve bater com controllerManager.replicaCount
# Metrics habilitados
metrics:
serviceMonitor:
enabled: true # Requer Prometheus Operator
# Leader election para HA
# É um mecanismo onde só um dos pods é o líder ativo, e os outros ficam standby.
# Esse líder é o único que executa a reconciliação dos ExternalSecrets (ou o sharding, se tiver ativo).
leaderElection:
enabled: true
O que é o Sharding
É a capacidade do ESO de dividir automaticamente a carga de reconciliação de ExternalSecrets entre várias réplicas do controller.
Quando você tem muitos ExternalSecrets (ex: centenas ou milhares), uma única réplica do ESO pode:
- Ficar sobrecarregada
- Ter delays no refreshInterval
- Gerar throttling na AWS/GCP/Vault
Com sharding, você espalha a carga entre os pods, mantendo performance e confiabilidade.
Cada ExternalSecrets é hashado com base no metadata.name + namespace. Esse hash é usado pra determinar qual controller vai cuidar de qual recurso. Assim, cada réplica processa apenas uma fatia do universo total.
Fluxo com replicaCount: 3 e sharding.enabled: true Imagine que você tem 3 pods do ESO:
Pod 1 → processa ExternalSecrets cujo hash termina em 0
Pod 2 → hash termina em 1
Pod 3 → hash termina em 2
Cada pod processa só o que é "dele", e ignora o resto.
Situação | Sharding |
---|---|
< 100 ExternalSecrets | ❌ Não precisa |
100–500, latência ok | ⚠️ Opcional |
500+ secrets ou backends lentos/throttling | ✅ Recomendo |
Multi-tenant clusters com muitos namespaces | ✅ Sim |