Traefik + CertManager: Gerenciando certificados TLS no Kubernetes
Neste artigo, eu apresento um simples setup utilizando o Cert Manager e Traefik para gerenciar certificados via Let’s Encrypt em clusters Kubernetes.
Motivação
Atualmente, eu tenho um pequeno cluster Kubernetes utilizando o K3S, que é uma versão simplificada e que possui API compatível com o Kubernetes clássico. Eu estava precisando gerenciar alguns certificados TLS e resolvi experimentar uma nova ferramenta, o Cert Manager.
Conceitos Básicos
A instalação do Cert Manager é bem simples e não entrarei em detalhes, você pode instalá-lo com um simples kubectl apply
ou então com o Helm, consulte as instruções na documentação.
Nós vamos precisar configurar apenas 3 componentes principais.
- Issuer: é o componente responsável por criar e validar os seus certificados. No meu caso, utilizei o Let’s Encrypt. Mas ele possui integração com diversos provedores.
- Certificates: esse componente é responsável por declarar os domínios desejados e também identificar o
Secret
que irá armazenar o certificado final. - Anotations: Caso esteja utilizando algum
Ingress
como o Traefik, basta incluir algumas anotações em seus componentes para associá-lo a Deployment, Deamonset, etc.
Issuer
O Issuer é bastante simples. No caso do Let’s Encrypt, você precisa apenas de informar um email e a URL do servidor. No meu caso, também estou informando qual o meu sistema de Ingress, no caso é Traefik.
# cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-issuer
spec:
acme:
email: [email protected]
privateKeySecretRef:
name: prod-issuer-account-key
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- http01:
ingress:
class: traefik
Para aplicá-lo, basta executar: kubectl apply -f cluster-issuer.yaml
Certificate
Para cada grupo de domínios é necessário registrar uma configuração de Certificate
. Essa configuração também pode ser feita apenas com anotações, mas desta forma é mais fácil de gerenciar e reaproveitar entre Deployments
. No exemplo abaixo estou declarando o domínio example.com
, que após gerado será salvo no Secret
chamado example-com-tls
. Repare que é necessário informar também o nome do Issuer
que criamos anteriormente: letsencrypt-issuer
.
# cert-example-com.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cert-example-com
namespace:
spec:
dnsNames:
- "example.com"
secretName: example-com-tls
issuerRef:
name: letsencrypt-issuer
kind: ClusterIssuer
Para aplicar, basta executar o comando kubectl apply -f cert-example-com.yaml
.
Pronto, a partir desse momento, o Cert Manager já tem os dados necessários para criar os certificados usando o Let’s Encrypt.
Basta executar o comando kubectl get certificates
para listar os certificados e verificar o status de cada:
$ kubectl get certificates
NAME READY SECRET AGE
cert-example-com True example-com-tls 10s
Caso ele esteja com o valor True
na coluna READY
, o nosso certificado foi gerado e está pronto para ser utilizado.
Caso retorne algum erro, você pode verificar os detalhes do processo utilizando o comando: kubectl describe <cetificate-name>
.
Utilização
Não é necessário utilizar um Ingress
para consumir o certificado, você pode simplesmente montar um volume em um container e consumí-lo via aplicação.
No meu caso, estou utilizando o Traefik com Ingress Controller. Ele é responsável por mapear e rotear o tráfego dos domínios utilizados no cluster. O consumo via Traefik é bastante simples, como mostrado no exemplo abaixo:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: example-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: traefik
spec:
tls:
secretName: example-com-tls # Informe o secret com certificado aqui.
entryPoints:
- web
- websecure
routes:
- match: HostRegexp(`example.com`)
kind: Rule
services:
- name: my-service
port: 8080
E pronto, todo o meu tráfego que é requisitado no domínio example.com
será direcionado para o serviço my-service
na porta 8080
, utilizado um certificado auto gerenciado via Cert Manager.
Dica Extra
Para facilitar ainda mais o trabalho com o Traefik, você pode criar um Middleware
para redirecionar todo as requisições HTTP para HTTPS, e também redirecionar requests utilizando o subdomínio www
para o domínio raiz.
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: strip-www-https
namespace: default
spec:
redirectRegex:
regex: ^https?://(?:www\.)?(.+)
replacement: https://${1}
permanent: true