15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar
22.10.2024

Cert-Manager no Kubernetes: Guia Completo de Configuração para Gerenciamento Automatizado de Certificados TLS

Cert-Manager é um controlador Kubernetes de código aberto que automatiza completamente o ciclo de vida dos certificados TLS — desde a emissão inicial até à validação e renovação — integrando-se diretamente com autoridades de certificação como Let’s Encrypt, HashiCorp Vault e sistemas PKI privados. Elimina fluxos de trabalho manuais de certificados ao tratar os certificados como recursos nativos do Kubernetes, geridos de forma declarativa através de Custom Resource Definitions (CRDs).

Em qualquer cluster Kubernetes de produção, os certificados TLS expirados ou mal configurados são uma das causas mais comuns de tempo de inatividade não planeado. O Cert-Manager resolve este problema reconciliando continuamente o estado dos certificados, renovando automaticamente as credenciais antes da expiração e armazenando o material de chave resultante em Secrets do Kubernetes que os controladores Ingress e as cargas de trabalho podem consumir imediatamente.

Por Que o Cert-Manager É o Padrão para Automação TLS no Kubernetes

Antes de o Cert-Manager se tornar a solução de facto, as equipas ou criavam scripts de renovações certbot em nós individuais, rotacionavam manualmente certificados entre namespaces, ou dependiam de integrações específicas de fornecedores de cloud que criavam dependência de fornecedor. O Cert-Manager unifica todas estas abordagens sob um único plano de controlo nativo do Kubernetes.

Principais vantagens em relação a abordagens ad-hoc:

  • Gestão declarativa: A intenção do certificado é expressa como um manifesto YAML, com controlo de versão junto ao código da aplicação.
  • Reconciliação automática: O ciclo do controlador deteta desvios entre o estado desejado e o estado real do certificado e corrige-os sem intervenção humana.
  • Suporte multi-emissor: Um único cluster pode usar simultaneamente o Let’s Encrypt para serviços públicos, uma CA interna para mTLS de service mesh e o HashiCorp Vault para cargas de trabalho sensíveis a segredos.
  • Trilha de auditoria: Cada objeto CertificateRequest é persistido na API do Kubernetes, fornecendo um histórico completo de emissão.

Executar Kubernetes numa plataforma de VPS Hosting com armazenamento NVMe e acesso root completo dá-lhe o controlo necessário para configurar resolvedores DNS personalizados, gerir regras de firewall para desafios ACME HTTP-01 e instalar CRDs ao nível do cluster sem restrições — todos pré-requisitos para uma implementação do Cert-Manager de nível de produção.

Arquitetura Principal: Como o Cert-Manager Funciona Internamente

Compreender a arquitetura interna do Cert-Manager previne configurações incorretas e ajuda a depurar falhas de emissão rapidamente.

A Máquina de Estados do Ciclo de Vida do Certificado

O Cert-Manager gere certificados através de uma máquina de estados determinística. Cada recurso Certificate transita pelos seguintes estados:

  1. Pendente — O objeto Certificate existe mas nenhum CertificateRequest válido foi cumprido.
  2. A Emitir — Um CertificateRequest foi criado e submetido ao emissor configurado.
  3. Pronto — Um certificado válido e não expirado está armazenado no Secret do Kubernetes referenciado.
  4. Renovação Pendente — O certificado está dentro da janela renewBefore (predefinição: 30 dias antes da expiração) e um novo CertificateRequest está a ser processado.

O controlador monitoriza todos os objetos Certificate em todo o cluster e reconcilia continuamente o seu estado. Se um Secret for eliminado manualmente, o Cert-Manager deteta o recurso em falta e aciona imediatamente a re-emissão — um comportamento crítico de auto-recuperação que previne interrupções acidentais.

Componentes CRD Principais

RecursoÂmbitoFinalidade
`Issuer`NamespaceDefine uma configuração de CA para um único namespace
`ClusterIssuer`Cluster-wideDefine uma configuração de CA utilizável por todos os namespaces
`Certificate`NamespaceDeclara o certificado TLS desejado e as suas propriedades
`CertificateRequest`NamespaceRastreia um único pedido de assinatura de certificado num momento específico
`Order`NamespaceRepresenta uma ordem ACME com uma CA (ex.: Let’s Encrypt)
`Challenge`NamespaceRastreia um único desafio ACME (HTTP-01 ou DNS-01)

Os recursos Order e Challenge são criados automaticamente pelo emissor ACME — raramente interage com eles diretamente, mas inspecioná-los é o principal caminho de depuração quando a emissão fica bloqueada.

Armazenamento de Certificados e Formato de Secret

Uma vez emitido, o Cert-Manager escreve três chaves de dados no Secret do Kubernetes de destino:

  • tls.crt — A cadeia de certificados completa (folha + intermediários), codificada em PEM.
  • tls.key — A chave privada, codificada em PEM.
  • ca.crt — O certificado da CA emissora (preenchido para CAs internas; pode estar vazio para emissores ACME).

Os controladores Ingress, service meshes e pods de aplicações montam este Secret diretamente. O formato é compatível com NGINX, Traefik, Istio, Linkerd e a maioria dos outros consumidores TLS nativos do Kubernetes.

Emissores Suportados e Quando Usar Cada Um

ACME (Let’s Encrypt e Alternativas)

O protocolo ACME é o caminho de emissão mais comum. O Cert-Manager implementa o cliente ACME RFC 8555 completo, suportando endpoints de staging e produção.

Desafio HTTP-01: O Cert-Manager serve temporariamente um token em http://<domain>/.well-known/acme-challenge/<token>. Isto requer que o domínio resolva para um IP publicamente acessível na porta 80. Funciona para certificados de domínio único e SAN, mas não pode emitir certificados wildcard.

Desafio DNS-01: O Cert-Manager cria um registo TXT _acme-challenge.<domain> através de uma API de fornecedor DNS. Funciona atrás de firewalls, suporta certificados wildcard (*.example.com) e é necessário para qualquer cluster não exposto diretamente à internet. Os fornecedores DNS suportados incluem Cloudflare, Route53, Google Cloud DNS, Azure DNS e muitos outros através de solvers webhook.

HashiCorp Vault

O emissor Vault integra-se com o motor de segredos PKI do Vault. É a escolha preferida para:

  • mTLS de microsserviços internos onde os certificados devem ter vida curta (horas, não meses).
  • Ambientes com requisitos rigorosos de custódia de chaves onde as chaves privadas nunca devem sair do Vault.
  • Rotação automatizada de certificados vinculada ao sistema de renovação de leases do Vault.

Emissores Self-Signed e CA

O emissor SelfSigned gera certificados assinados pela própria chave privada do certificado — útil para inicializar uma CA raiz dentro do cluster. O emissor CA usa um Secret do Kubernetes contendo um par de chaves CA para assinar certificados, tornando-o adequado para ambientes de desenvolvimento interno e PKI de service mesh.

Venafi

A integração com o Venafi destina-se a ambientes empresariais com aplicação centralizada de políticas de certificados, auditoria de conformidade e integração com módulos de segurança de hardware (HSMs).

Cert-Manager vs. Abordagens Alternativas de Automação TLS

AbordagemSuporte WildcardNativo KubernetesMulti-CARenovação AutomáticaComplexidade
Cert-ManagerSim (DNS-01)Sim (CRDs)SimSimMédia
Certbot ManualNão (apenas HTTP-01)NãoLimitadoCom ScriptBaixa–Média
Terminação TLS em Cloud LBVariávelNãoNãoSimBaixa
Istio / CA de Service MeshApenas internoSimNãoSimAlta
HashiCorp Vault (standalone)SimNãoSimManualAlta

Para equipas que executam Kubernetes num Servidor Dedicado ou VPS, o Cert-Manager é a única abordagem que é simultaneamente nativa do Kubernetes, suporta todas as principais CAs e não requer qualquer intervenção manual contínua.

Instalação do Cert-Manager: Configuração Pronta para Produção

Pré-requisitos

  • Kubernetes 1.22+ (1.26+ recomendado para estabilidade total de CRD)
  • kubectl configurado com privilégios cluster-admin
  • Helm 3.x instalado
  • Um domínio registado com acesso à gestão DNS (para DNS-01) ou um IP de ingress publicamente acessível (para HTTP-01)

Se estiver a gerir o seu próprio domínio, o Registo de Domínios através de um fornecedor que expõe uma API é fortemente recomendado — permite a resolução totalmente automatizada de desafios DNS-01 sem intervenção manual.

Passo 1: Instalar CRDs e o Controlador Cert-Manager

O método de instalação de produção recomendado usa Helm com CRDs geridos separadamente para evitar conflitos de atualização do Helm:

# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io
helm repo update

# Install Cert-Manager with CRDs included
helm install cert-manager jetstack/cert-manager 
  --namespace cert-manager 
  --create-namespace 
  --version v1.14.5 
  --set installCRDs=true 
  --set global.leaderElection.namespace=cert-manager

Verifique se todos os três pods principais estão em execução antes de prosseguir:

kubectl get pods --namespace cert-manager

Saída esperada:

NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-xxxxxxxxx-xxxxx              1/1     Running   0          60s
cert-manager-cainjector-xxxxxxxxx-xxxxx   1/1     Running   0          60s
cert-manager-webhook-xxxxxxxxx-xxxxx      1/1     Running   0          60s

O cainjector injeta dados de bundle CA nas configurações de webhook. O webhook valida e muta objetos CRD do Cert-Manager — se não estiver em execução, todas as operações kubectl apply em recursos do Cert-Manager falharão.

Passo 2: Configurar um ClusterIssuer para o Let’s Encrypt

Comece sempre com o ambiente de staging do Let’s Encrypt para evitar atingir os limites de taxa de produção (50 certificados por domínio registado por semana):

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-staging-account-key
    solvers:
      - http01:
          ingress:
            class: nginx

Assim que os certificados de staging forem emitidos com sucesso, crie o emissor de produção:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-account-key
    solvers:
      - http01:
          ingress:
            class: nginx

Aplique ambos os manifestos:

kubectl apply -f clusterissuer-staging.yaml
kubectl apply -f clusterissuer-prod.yaml

Verifique a disponibilidade do emissor:

kubectl describe clusterissuer letsencrypt-prod

O campo Status.Conditions deve mostrar Ready: True. Se mostrar False, o registo da conta ACME falhou — verifique o endereço de e-mail e a conectividade de rede do pod cert-manager.

Passo 3: Solicitar um Certificado Explicitamente

Pode solicitar certificados criando diretamente um recurso Certificate ou anotando um recurso Ingress. A abordagem explícita Certificate dá-lhe mais controlo:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-com-tls
  namespace: production
spec:
  secretName: example-com-tls-secret
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: example.com
  dnsNames:
    - example.com
    - www.example.com
  duration: 2160h    # 90 days (Let's Encrypt default)
  renewBefore: 720h  # Renew 30 days before expiry

Aplique e monitorize a emissão:

kubectl apply -f certificate.yaml
kubectl describe certificate example-com-tls -n production

Observe os objetos CertificateRequest e Order para obter o estado detalhado:

kubectl get certificaterequest -n production
kubectl describe order -n production

Passo 4: Método de Anotação Ingress (Simplificado)

Para equipas que usam o NGINX Ingress Controller, o Cert-Manager pode ser acionado automaticamente através de uma anotação — não é necessário um manifesto Certificate separado:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: production
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - example.com
        - www.example.com
      secretName: example-com-tls-secret
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: example-service
                port:
                  number: 80

O Cert-Manager deteta a anotação e cria automaticamente o recurso Certificate correspondente. Este é o padrão mais comum em fluxos de trabalho GitOps.

Padrões de Configuração Avançada

Certificados Wildcard com DNS-01 (Exemplo Cloudflare)

Os certificados wildcard requerem validação DNS-01. Primeiro, crie um Secret contendo o seu token de API Cloudflare:

kubectl create secret generic cloudflare-api-token 
  --from-literal=api-token=<YOUR_CLOUDFLARE_API_TOKEN> 
  --namespace cert-manager

Configure o ClusterIssuer com um solver DNS-01:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod-dns
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-dns-account-key
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: cloudflare-api-token
              key: api-token

Solicite o certificado wildcard:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-example-com
  namespace: production
spec:
  secretName: wildcard-example-com-tls
  issuerRef:
    name: letsencrypt-prod-dns
    kind: ClusterIssuer
  dnsNames:
    - "*.example.com"
    - example.com

Armadilha crítica: O Secret contendo as credenciais do fornecedor DNS deve residir no namespace cert-manager quando referenciado por um ClusterIssuer. Se o colocar noutro namespace, o controlador não consegue lê-lo e a emissão falhará silenciosamente. Verifique os logs do controlador cert-manager com kubectl logs -n cert-manager deploy/cert-manager se os desafios ficarem bloqueados.

PKI Interno com um Emissor CA

Para mTLS entre serviços dentro de um cluster, um emissor CA suportado por uma raiz self-signed é mais adequado do que ACME:

# Step 1: Create a self-signed root CA certificate
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned-root
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: internal-root-ca
  namespace: cert-manager
spec:
  isCA: true
  commonName: internal-root-ca
  secretName: internal-root-ca-secret
  issuerRef:
    name: selfsigned-root
    kind: ClusterIssuer
---
# Step 2: Create a CA issuer backed by the root certificate
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: internal-ca-issuer
spec:
  ca:
    secretName: internal-root-ca-secret

Os serviços podem agora solicitar certificados de vida curta a internal-ca-issuer para mTLS sem qualquer dependência de CA externa.

Configuração de renewBefore para Ambientes de Alta Segurança

O renewBefore predefinido de 30 dias é adequado para certificados Let’s Encrypt de 90 dias. Para certificados internos de vida curta (ex.: validade de 24 horas), defina renewBefore como uma fração da duração total:

spec:
  duration: 24h
  renewBefore: 8h

O Cert-Manager iniciará a renovação 8 horas antes da expiração, dando ao controlador três janelas de renovação dentro de um ciclo de vida de certificado de 24 horas — uma margem de segurança crítica se o cluster experimentar indisponibilidade transitória do servidor API.

Depuração de Falhas Comuns do Cert-Manager

Certificado Bloqueado no Estado “A Emitir”

# Check the Certificate status
kubectl describe certificate <name> -n <namespace>

# Check the associated CertificateRequest
kubectl describe certificaterequest -n <namespace>

# Check the ACME Order
kubectl describe order -n <namespace>

# Check the Challenge
kubectl describe challenge -n <namespace>

# Check controller logs
kubectl logs -n cert-manager deploy/cert-manager --tail=100

Causas raiz comuns:

  • Falha HTTP-01: O controlador Ingress não está a encaminhar corretamente o tráfego /.well-known/acme-challenge/. Verifique se o objeto Ingress do desafio foi criado e se a porta 80 é acessível a partir da internet. As firewalls no host devem permitir TCP/80 de entrada.
  • Falha DNS-01: O token de API do fornecedor DNS tem permissões insuficientes, ou a propagação DNS ainda não foi concluída. Os servidores de validação do Let’s Encrypt podem consultar resolvedores diferentes do seu DNS local — atrasos de propagação de 60–120 segundos são normais.
  • Limite de taxa excedido: O Let’s Encrypt aplica 5 tentativas de validação falhadas por domínio por hora. Após atingir este limite, deve aguardar antes de tentar novamente. Teste sempre com o endpoint de staging primeiro.
  • Webhook não disponível: Se o pod de webhook do cert-manager não estiver em execução, todas as operações CRD falharão com um erro de ligação recusada. Certifique-se de que o serviço de webhook tem um endpoint válido.

Verificação de um Certificado Implementado

# Check the Secret contents
kubectl get secret example-com-tls-secret -n production -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -noout -text

# Check expiry date specifically
kubectl get secret example-com-tls-secret -n production -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -noout -enddate

Lista de Verificação de Proteção para Produção

Implementar o Cert-Manager num ambiente de produção requer mais do que uma instalação Helm predefinida. Aplique estas medidas de proteção antes de entrar em produção:

  • Limites de recursos: Defina requests e limits de CPU e memória em todos os três pods do Cert-Manager para evitar contenção de recursos em nós partilhados.
  • Auditoria RBAC: O Cert-Manager requer permissões RBAC amplas. Reveja os objetos ClusterRole instalados e restrinja-os ao mínimo necessário para os seus tipos de emissor.
  • Namespace separado: Implemente sempre o Cert-Manager no seu próprio namespace cert-manager, isolado das cargas de trabalho das aplicações.
  • Monitorização: Exponha o endpoint de métricas Prometheus do Cert-Manager (--metrics-listen-address) e configure alertas em certmanager_certificate_expiration_timestamp_seconds para detetar falhas de renovação antes de impactarem os serviços.
  • Backup do estado CRD: Inclua os objetos Certificate, ClusterIssuer e Issuer na sua estratégia de backup do cluster. Perder estes manifestos após um evento de recuperação de desastre significa recriar manualmente todas as configurações de certificados.
  • Validação em staging: Nunca emita o seu primeiro certificado contra um endpoint ACME de produção. As violações de limites de taxa podem bloquear o seu domínio por até uma semana.

Se estiver a executar múltiplos clusters Kubernetes — por exemplo, separando cargas de trabalho de staging e produção — os Painéis de Controlo VPS podem simplificar a gestão do ciclo de vida do cluster e fornecer uma interface unificada para aprovisionar a infraestrutura subjacente em que cada cluster é executado.

Para cargas de trabalho que requerem inferência acelerada por GPU ou serviço de ML atrás de endpoints terminados em TLS, os mesmos padrões do Cert-Manager aplicam-se em infraestrutura de GPU Hosting, onde a gestão automatizada de certificados é igualmente crítica para proteger os endpoints de API de modelos.

Matriz de Decisão Prática: Escolher o Emissor Correto

CenárioEmissor RecomendadoTipo de DesafioWildcard
Aplicação web pública, domínio único`letsencrypt-prod`HTTP-01Não
Aplicação web pública, múltiplos subdomínios`letsencrypt-prod`DNS-01Sim
Cluster air-gapped / privado`CA` ou `Vault`N/A (interno)Sim
Empresa com requisitos de conformidade`Venafi`N/ASim
mTLS de service mesh (certificados de vida curta)`Vault` ou `CA`N/A (interno)Sim
Desenvolvimento / cluster local`SelfSigned` ou `CA`N/ASim

Principais Conclusões

  • Instale o Cert-Manager usando Helm com installCRDs=true e valide sempre contra o endpoint ACME de staging antes de mudar para produção.
  • Use ClusterIssuer para clusters multi-namespace; use Issuer com âmbito de namespace apenas quando precisar de isolamento de CA por equipa.
  • DNS-01 é estritamente necessário para certificados wildcard e para clusters não diretamente acessíveis a partir da internet na porta 80.
  • O campo renewBefore não é opcional em produção — defina-o para pelo menos um terço do duration total do certificado.
  • Quando a emissão fica bloqueada, o caminho de depuração é sempre: CertificateCertificateRequestOrderChallenge → logs do controlador.
  • As credenciais de API do fornecedor DNS referenciadas por um ClusterIssuer devem residir no namespace cert-manager, não nos namespaces das aplicações.
  • Monitorize certmanager_certificate_expiration_timestamp_seconds no Prometheus e configure alertas — as falhas silenciosas de renovação são o modo de falha mais perigoso.
  • Faça backup dos seus manifestos Certificate e ClusterIssuer como parte do seu plano de recuperação de desastre.

Perguntas Frequentes

Qual é a diferença entre um Issuer e um ClusterIssuer no Cert-Manager?

Um Issuer tem âmbito de namespace e só pode emitir certificados dentro do namespace onde está definido. Um ClusterIssuer tem âmbito de cluster e pode ser referenciado por recursos Certificate em qualquer namespace. Para a maioria dos clusters de produção, ClusterIssuer é a escolha correta, a menos que precise de isolamento estrito de CA ao nível do namespace.

Por que o meu certificado Cert-Manager está bloqueado no estado “A Emitir”?

Inspecione os objetos Order e Challenge no mesmo namespace usando kubectl describe. As causas mais comuns são: porta 80 bloqueada por uma firewall (HTTP-01), credenciais de API DNS incorretas ou atraso de propagação (DNS-01), limites de taxa do Let’s Encrypt excedidos, ou o pod de webhook do cert-manager não estar em execução. Verifique sempre os logs do controlador com kubectl logs -n cert-manager deploy/cert-manager.

O Cert-Manager pode emitir certificados wildcard do Let’s Encrypt?

Sim, mas apenas usando o tipo de desafio DNS-01. O HTTP-01 não consegue validar domínios wildcard. Deve configurar uma integração de fornecedor DNS (Cloudflare, Route53, etc.) na configuração do solver ClusterIssuer e garantir que as credenciais de API têm permissão para criar registos TXT no domínio de destino.

Como é que o Cert-Manager trata a renovação automática de certificados?

O controlador do Cert-Manager compara continuamente a expiração de cada objeto Certificate com a hora atual. Quando a validade restante cai abaixo do limiar renewBefore (predefinição: 30 dias), o controlador cria um novo CertificateRequest, completa o desafio ACME e substitui atomicamente o conteúdo do Secret de destino — tudo sem reiniciar os pods que consomem o certificado. Os pods que montam o Secret como volume verão o certificado atualizado no próximo ciclo de sincronização do kubelet.

O Cert-Manager é adequado para proteger a comunicação interna entre serviços, não apenas HTTPS público?

Sim. Usando o emissor CA ou o emissor HashiCorp Vault, o Cert-Manager pode emitir certificados de vida curta para mTLS interno entre microsserviços. Este é um padrão comum em implementações de service mesh onde cada carga de trabalho precisa de um certificado de identidade único. Os campos duration e renewBefore permitem que os certificados tenham vida tão curta quanto minutos, com rotação totalmente automatizada.

15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar