Publique sites no Kubernetes com HTTPS automático: Ingress com Traefik, cert-manager e Let's Encrypt, redirecionamento e diagnóstico de certificados.
Para que serve
Este artigo mostra como publicar aplicações do cluster na internet com HTTPS automático usando um Ingress com Traefik e o cert-manager com Let's Encrypt no Kubernetes. O Ingress recebe as conexões nas portas 80 e 443 e encaminha cada domínio para o serviço certo; o cert-manager pede e renova os certificados sozinho. Os exemplos usam k3s, que já traz o Traefik instalado.
ingress-nginx foi aposentado pelo Kubernetes; a manutenção terminou em março de 2026 e não há mais correções de segurança. Não o use em instalações novas. Se você já tem clusters com ele, planeje a troca para Traefik (que consegue ler boa parte das anotações do ingress-nginx), outro controlador mantido ou Gateway API.Pré-requisitos
- Cluster k3s funcionando (veja Como instalar o k3s em servidor dedicado) e
kubectlehelmconfigurados (veja Helm na prática). - Um nome DNS (registro A/AAAA) apontando para o IP público que recebe o tráfego: o IP do nó ou um IP do bloco /28 entregue pelo MetalLB (veja Como usar MetalLB com os IPs públicos do bloco /28).
- Portas 80 e 443 liberadas no firewall para esse IP. A porta 80 é obrigatória para o desafio HTTP-01 do Let's Encrypt.
Etapa 1: confirmar que o Traefik está ativo
kubectl -n kube-system get pods -l app.kubernetes.io/name=traefik
kubectl -n kube-system get svc traefik
kubectl get ingressclass
O serviço traefik deve ter um EXTERNAL-IP (o IP do nó, via ServiceLB do k3s, ou o IP do MetalLB) e deve existir a IngressClass traefik. O k3s atual vem com Traefik v3.
Etapa 2: redirecionar HTTP para HTTPS
No k3s, não edite o manifesto do Traefik diretamente: crie um HelmChartConfig, que é mesclado aos valores padrão e sobrevive às atualizações. No nó servidor:
cat > /var/lib/rancher/k3s/server/manifests/traefik-config.yaml <<'EOF'
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
additionalArguments:
- "--entryPoints.web.http.redirections.entryPoint.to=websecure"
- "--entryPoints.web.http.redirections.entryPoint.scheme=https"
- "--entryPoints.web.http.redirections.entryPoint.permanent=true"
EOF
O k3s reaplica o chart em alguns segundos. Em cluster com vários servidores, basta criar o arquivo em um deles.
Etapa 3: instalar o cert-manager
helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \
--version v1.21.2 \
--namespace cert-manager --create-namespace \
--set crds.enabled=true
kubectl -n cert-manager get pods
Aguarde os três pods (cert-manager, cainjector e webhook) ficarem Running. Confira a versão mais recente na documentação do cert-manager antes de instalar.
Etapa 4: criar os emissores do Let's Encrypt
Crie dois ClusterIssuer: staging, para testar sem esbarrar nos limites de emissão, e produção. Salve como issuers.yaml, troque o e-mail e aplique com kubectl apply -f issuers.yaml:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: infra@seudominio.com.br
privateKeySecretRef:
name: letsencrypt-staging-conta
solvers:
- http01:
ingress:
ingressClassName: traefik
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: infra@seudominio.com.br
privateKeySecretRef:
name: letsencrypt-prod-conta
solvers:
- http01:
ingress:
ingressClassName: traefik
Verifique: kubectl get clusterissuer deve mostrar READY True nos dois.
Etapa 5: publicar uma aplicação com Ingress e certificado
kubectl create namespace site
kubectl -n site create deployment web --image=nginx:alpine
kubectl -n site expose deployment web --port=80
Crie ingress.yaml começando pelo emissor de staging:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
namespace: site
annotations:
cert-manager.io/cluster-issuer: letsencrypt-staging
spec:
ingressClassName: traefik
tls:
- hosts:
- app.seudominio.com.br
secretName: web-tls
rules:
- host: app.seudominio.com.br
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
Aplique com kubectl apply -f ingress.yaml. Quando o certificado de staging sair, troque a anotação para letsencrypt-prod, apague o Secret de teste (kubectl -n site delete secret web-tls) e aplique de novo.
Como saber se funcionou
kubectl -n site get certificate
curl -I http://app.seudominio.com.br
curl -vI https://app.seudominio.com.br 2>&1 | grep -E "issuer|HTTP/"
O certificado deve estar READY True, o HTTP deve responder com redirecionamento 301/308 para HTTPS, e o emissor deve ser o Let's Encrypt (no staging aparece um emissor de teste, que o navegador não reconhece; isso é esperado). A renovação é automática, cerca de 30 dias antes do vencimento.
Problemas comuns
Certificado fica em READY False
Siga a cadeia de objetos até achar o erro:
kubectl -n site describe certificate web-tls
kubectl -n site get certificaterequest,order,challenge
kubectl -n site describe challenge
As causas mais frequentes são DNS ainda não propagado ou apontando para outro IP, porta 80 bloqueada no firewall ou um proxy (como o da Cloudflare em modo laranja) interceptando o desafio. Teste de fora: curl http://app.seudominio.com.br/.well-known/acme-challenge/teste deve chegar ao Traefik (resposta 404 do Traefik, não timeout).
Erro "too many certificates" ou limite de taxa
Você emitiu muitas vezes em produção para o mesmo domínio. Use o staging enquanto ajusta a configuração e aguarde o limite expirar.
Preciso de certificado curinga (*.dominio)
O desafio HTTP-01 não emite curingas. Use o desafio DNS-01 com o provedor do seu DNS (Cloudflare, Route 53 e outros têm suporte no cert-manager).
Quero usar outro controlador no lugar do Traefik
Inicie o k3s com disable: [traefik] no config.yaml de todos os servidores e instale o controlador escolhido. Ajuste o ingressClassName nos Ingress e nos ClusterIssuer.
Perguntas frequentes
O que é Gateway API?
É a evolução do Ingress no Kubernetes, com recursos como Gateway e HTTPRoute e regras mais expressivas. O Traefik v3 do k3s suporta Gateway API ativando o provedor kubernetesGateway no HelmChartConfig, e o cert-manager também emite certificados para Gateways.
O ingress-nginx para de funcionar depois da aposentadoria?
Ele continua rodando, mas sem correções de segurança. Expor um componente sem manutenção à internet é um risco crescente.
Preciso de um IP por site?
Não. O Ingress separa os sites pelo nome do host (SNI), então um único IP atende dezenas de domínios.
Leitura complementar
- Documentação do cert-manager
- Serviços de rede do k3s (Traefik e ServiceLB)
- Anúncio da aposentadoria do ingress-nginx
Precisa de ajuda?
Se o desafio do Let's Encrypt não chega ao servidor e você suspeita de bloqueio na rede, abra um ticket com o domínio, o IP e a saída de kubectl describe challenge.
