Expor um serviço com HTTPS
Ao final deste guia, https://loja.exemplo.com.br responde do seu cluster com certificado
válido que renova sozinho — e você tem um alerta para o dia em que a renovação falhar.
Pré-requisitos: cluster com um LoadBalancer disponível, e controle sobre a zona DNS do domínio.
1. Instale o controlador de Ingress
Seção intitulada “1. Instale o controlador de Ingress”helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginxhelm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \ -n ingress-nginx --create-namespace \ --version 4.11.2 \ --set controller.service.type=LoadBalancer
kubectl get svc -n ingress-nginx -w # espere o EXTERNAL-IP aparecerAponte o DNS para esse endereço antes de continuar — a validação HTTP do certificado depende disso.
dig +short loja.exemplo.com.br # precisa devolver o IP do LoadBalancer2. Instale o cert-manager
Seção intitulada “2. Instale o cert-manager”helm repo add jetstack https://charts.jetstack.iohelm upgrade --install cert-manager jetstack/cert-manager \ -n cert-manager --create-namespace \ --version v1.16.1 --set crds.enabled=true
kubectl get pods -n cert-manager # três Pods: controller, webhook, cainjector3. Crie o emissor
Seção intitulada “3. Crie o emissor”Comece pelo ambiente de staging do Let’s Encrypt. Ele emite certificado não confiável pelo navegador, mas tem limites generosos — e o de produção bloqueia por horas se você errar algumas vezes.
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: { name: letsencrypt-staging }spec: acme: server: https://acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef: { name: letsencrypt-staging-key } solvers: - http01: { ingress: { ingressClassName: nginx } }Depois de validar o fluxo, duplique o manifesto trocando o nome para letsencrypt-prod e o
server para https://acme-v02.api.letsencrypt.org/directory.
Para certificado curinga (*.exemplo.com.br) ou serviço sem exposição pública, o
solver HTTP-01 não funciona: use DNS-01, com credencial do seu provedor de DNS em um
Secret.
4. Crie o Ingress com TLS
Seção intitulada “4. Crie o Ingress com TLS”O cert-manager observa a anotação e emite o certificado sozinho.
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: loja namespace: loja annotations: cert-manager.io/cluster-issuer: letsencrypt-prodspec: ingressClassName: nginx tls: - hosts: [loja.exemplo.com.br] secretName: loja-tls # o cert-manager cria este Secret rules: - host: loja.exemplo.com.br http: paths: - path: / pathType: Prefix backend: service: { name: loja, port: { number: 80 } }5. Acompanhe a emissão
Seção intitulada “5. Acompanhe a emissão”A emissão passa por uma cadeia de recursos. Quando algo falha, os eventos dizem onde:
kubectl get certificate -n loja # READY deve virar True em ~1 minutokubectl describe certificate loja-tls -n lojakubectl get certificaterequest,order,challenge -n lojakubectl describe challenge -n loja | sed -n '/Events/,$p'Confirme de fora:
curl -sI https://loja.exemplo.com.br | head -3openssl s_client -connect loja.exemplo.com.br:443 -servername loja.exemplo.com.br \ </dev/null 2>/dev/null | openssl x509 -noout -issuer -dates6. Monitore a expiração
Seção intitulada “6. Monitore a expiração”Automação também falha — permissão de DNS revogada, limite atingido, validação bloqueada. O certificado tem 90 dias e a renovação começa aos 60; se ninguém observa, você descobre no dia 90.
# cert-manager expõe esta métrica; alerte com folga(certmanager_certificate_expiration_timestamp_seconds - time()) / 86400 < 21Monitore também o certificado servido na porta e não só o objeto no cluster — assim você pega o caso em que o Secret renovou e o controlador não recarregou.
Se der errado
Seção intitulada “Se der errado”| Sintoma | Causa provável |
|---|---|
Challenge preso em pending |
DNS não aponta para o LoadBalancer, ou porta 80 fechada |
Certificate sem sair de False |
Emissor errado no cluster-issuer, ou e-mail inválido |
| Erro de limite de emissão | Você usou produção para testar; volte para staging e espere |
| Navegador reclama do certificado | Emissor de staging ainda configurado |
| 404 no domínio, mas TLS ok | ingressClassName, host ou backend errado no Ingress |
Funciona no navegador, falha no curl |
Cadeia incompleta servida pelo controlador |
Redirecionamento de HTTP para HTTPS já vem ligado por padrão no ingress-nginx. Se você precisa desligá-lo para algum caminho (um webhook legado, por exemplo), faça por anotação naquele Ingress específico, nunca no controlador inteiro.
Checklist de pronto
Seção intitulada “Checklist de pronto”- DNS apontando para o LoadBalancer, verificado com
dig. - Fluxo validado no emissor de staging antes do de produção.
-
CertificatecomREADY=Truee Secret criado. -
curl -sIdevolve 200 em HTTPS, com cadeia completa. - Alerta de expiração com pelo menos 21 dias de folga.
- Registro CAA configurado no domínio.