DEV Community

Celso Nery
Celso Nery

Posted on

Kubernetes: Automatizando Certificados TLS com Cert-Manager

🇺🇸 English version here.

Com o Ingress Controller já configurado (veja o artigo anterior desta série de addons), o cluster consegue rotear múltiplos domínios HTTP para os Services corretos. O próximo passo natural é habilitar HTTPS nesses domínios — e fazer isso manualmente, renovando certificados antes de expirarem, não escala bem conforme o número de domínios cresce. É exatamente esse problema que o cert-manager resolve: ele automatiza a emissão, renovação e gestão de certificados TLS dentro do cluster, integrando-se diretamente com autoridades certificadoras como o Let's Encrypt.

🔗 Site oficial: https://cert-manager.io/

Instalando o cert-manager

A instalação é feita aplicando o manifesto oficial do projeto, referente à versão desejada:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.1/cert-manager.yaml
Enter fullscreen mode Exit fullscreen mode

Sempre confira a página de releases do cert-manager para instalar a versão estável mais recente — o link acima referencia a v1.16.1 como exemplo, mas o projeto lança novas versões com frequência, e vale usar uma compatível com a versão do seu Kubernetes.

Esse manifesto cria os componentes do cert-manager (controller, webhook e cainjector) em um namespace próprio (cert-manager), além das Custom Resource Definitions (CRDs) necessárias — como ClusterIssuer, Certificate e CertificateRequest — que passam a existir no cluster como novos tipos de objeto.

Criando um ClusterIssuer

O cert-manager, sozinho, não sabe de onde emitir certificados — é preciso configurar um Issuer (restrito a um namespace) ou um ClusterIssuer (disponível para todo o cluster), apontando para uma autoridade certificadora.

Um exemplo comum, usando o Let's Encrypt com validação via HTTP-01 (que depende do Ingress Controller já estar funcionando, já que a validação acontece através de uma requisição HTTP ao domínio):

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: seu-email@bagarote.com.br
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
      - http01:
          ingress:
            ingressClassName: nginx
Enter fullscreen mode Exit fullscreen mode

Onde:

  • server: endereço da API do Let's Encrypt em produção (existe também um ambiente de staging, recomendado para testes, evitando esbarrar nos limites de emissão de certificados do ambiente de produção);
  • email: usado pelo Let's Encrypt para notificações sobre expiração ou problemas com os certificados;
  • solvers.http01.ingress.ingressClassName: indica que a validação será feita através do Ingress Controller nginx, já instalado.

Aplicando o ClusterIssuer:

kubectl apply -f clusterissuer.yaml
Enter fullscreen mode Exit fullscreen mode

Para confirmar que foi criado corretamente:

kubectl get clusterissuer
Enter fullscreen mode Exit fullscreen mode

Habilitando HTTPS no Ingress da aplicação

Com o ClusterIssuer criado, basta anotar o Ingress da aplicação para que o cert-manager emita e gerencie automaticamente o certificado daquele domínio:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ecommerce-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
    - hosts:
        - ecommerce.bagarote.com.br
      secretName: ecommerce-tls
  rules:
    - host: ecommerce.bagarote.com.br
      http:
        paths:
          - pathType: "Prefix"
            path: "/"
            backend:
              service:
                name: ecommerce
                port:
                  number: 80
Enter fullscreen mode Exit fullscreen mode

A anotação cert-manager.io/cluster-issuer diz ao cert-manager qual ClusterIssuer usar para esse domínio, e o bloco tls define em qual Secret (ecommerce-tls, no exemplo) o certificado emitido deve ser armazenado.

Acompanhando a emissão do certificado

Depois de aplicar o Ingress, o cert-manager inicia automaticamente o processo de solicitação e validação do certificado. É possível acompanhar cada etapa através de alguns comandos:

Verificar se o Secret com o certificado já foi criado:

kubectl get secrets
Enter fullscreen mode Exit fullscreen mode

Verificar o status do objeto Certificate (criado automaticamente pelo cert-manager a partir da anotação no Ingress):

kubectl get certificate
kubectl describe certificate ecommerce-tls
Enter fullscreen mode Exit fullscreen mode

Se o certificado não ficar Ready rapidamente, o próximo nível de detalhe é o CertificateRequest — o pedido de emissão propriamente dito:

kubectl describe certificaterequest ecommerce-tls-2ld57
Enter fullscreen mode Exit fullscreen mode

E, indo ainda mais fundo, o Challenge — que representa a etapa de validação do domínio junto ao Let's Encrypt (é aqui que problemas de DNS ou de roteamento do Ingress costumam aparecer):

kubectl describe challenges --all-namespaces
Enter fullscreen mode Exit fullscreen mode

Por fim, para visualizar todas as Custom Resource Definitions instaladas pelo cert-manager (útil para entender a extensão do que foi adicionado ao cluster):

kubectl get crd
Enter fullscreen mode Exit fullscreen mode

Considerações finais

Com o cert-manager configurado, novos domínios passam a ter certificados TLS emitidos e renovados automaticamente, bastando adicionar a anotação correta no respectivo Ingress — sem nenhuma intervenção manual futura. Quando algo não funciona como esperado, a sequência Certificate → CertificateRequest → Challenge é o caminho natural de investigação, já que cada objeto representa uma etapa mais granular do processo de emissão.

Top comments (0)