Tenho um pequeno cluster k3s em minha casa que hospeda alguns sites e aplicativos locais. Na maior parte, consegui organizá-lo para hospedar uma variedade de serviços, mas a funcionalidade LetsEncrypt nunca funcionou muito bem para mim. Quando funcionou, fiquei sem saber por que e com medo de mexer nele para que não quebrasse novamente.
No momento, há dois sites no cluster com suporte a TLS funcionando bem... até há anos, mas agora que estou adicionando um terceiro site, estou enfrentando os mesmos erros que recebia no passado e não tenho ideia do porquê. Espero que alguém aqui possa explicar o que perdi.
O erro parece ser uma reclamação de que quando o URL mágico é solicitado (como determino o URL que está sendo tentado?), eles obtêm HTML em vez da resposta esperada, embora não esteja claro por que está fazendo isso, ou mesmo qual serviço está construindo a resposta.
I0820 17:28:23.398812 1 service.go:43] cert-manager/challenges/http01/selfCheck/http01/ensureService "msg"="found one existing HTTP01 solver Service for challenge resource" "dnsName"="REDACTED.tld" "related_resource_kind"="Service" "related_resource_name"="cm-acme-http-solver-9qp5z" "related_resource_namespace"="my-namespace" "related_resource_version"="v1" "resource_kind"="Challenge" "resource_name"="tls-REDACTED" "resource_namespace"="my-namespace" "resource_version"="v1" "type"="HTTP-01"
E0820 17:28:23.585197 1 sync.go:190] cert-manager/challenges "msg"="propagation check failed" "error"="did not get expected response when querying endpoint, expected \"REDACTED.REDACTED\" but got: <!DOCTYPE html PUBLIC \"-... (truncated)" "dnsName"="REDACTED.tld" "resource_kind"="Challenge" "resource_name"="tls-REDACTED" "resource_namespace"="my-namespace" "resource_version"="v1" "type"="HTTP-01"
I0820 17:28:33.585741 1 pod.go:59] cert-manager/challenges/http01/selfCheck/http01/ensurePod "msg"="found one existing HTTP01 solver pod" "dnsName"="REDACTED.tld" "related_resource_kind"="Pod" "related_resource_name"="cm-acme-http-solver-5gnhm" "related_resource_namespace"="my-namespace" "related_resource_version"="v1" "resource_kind"="Challenge" "resource_name"="tls-REDACTED" "resource_namespace"="my-namespace" "resource_version"="v1" "type"="HTTP-01"
I0820 17:28:33.585898 1 service.go:43] cert-manager/challenges/http01/selfCheck/http01/ensureService "msg"="found one existing HTTP01 solver Service for challenge resource" "dnsName"="REDACTED.tld" "related_resource_kind"="Service" "related_resource_name"="cm-acme-http-solver-9qp5z" "related_resource_namespace"="my-namespace" "related_resource_version"="v1" "resource_kind"="Challenge" "resource_name"="tls-REDACTED" "resource_namespace"="my-namespace" "resource_version"="v1" "type"="HTTP-01"
E0820 17:28:33.600402 1 sync.go:190] cert-manager/challenges "msg"="propagation check failed" "error"="did not get expected response when querying endpoint, expected \"REDACTED.REDACTED\" but got: <!DOCTYPE html PUBLIC \"-... (truncated)" "dnsName"="REDACTED.tld" "resource_kind"="Challenge" "resource_name"="tls-REDACTED" "resource_namespace"="my-namespace" "resource_version"="v1" "type"="HTTP-01"
Todo o aplicativo consiste em um aplicativo web Python, um trabalhador Python, Redis e Nginx, o que resulta em muito YAML. Estou incluindo a marcação que presumo ser relevante para este caso:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: my-namespace
spec:
replicas: 1
revisionHistoryLimit: 0
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
resources:
requests:
memory: 32Mi
cpu: 125m
limits:
memory: 32Mi
cpu: 125m
ports:
- containerPort: 80
volumeMounts:
- name: public
mountPath: "/usr/share/nginx/html"
volumes:
- name: public
persistentVolumeClaim:
claimName: public
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
namespace: my-namespace
annotations:
kubernetes.io/ingress.class: traefik
cert-manager.io/cluster-issuer: letsencrypt
acme.cert-manager.io/http01-edit-in-place: 'true'
spec:
rules:
- host: REDACTED.tld
http:
paths:
- path: /static
pathType: Prefix
backend:
service:
name: nginx
port:
number: 8000
- path: /media
pathType: Prefix
backend:
service:
name: nginx
port:
number: 8000
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 8000
tls:
- secretName: tls
hosts:
- REDACTED.tld
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: my-namespace
spec:
selector:
app: nginx
ports:
- port: 8000
targetPort: 80
name: tcp
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: my-namespace
spec:
selector:
app: web
ports:
- port: 8000
targetPort: 8000
name: gunicorn
Sinto-me bastante confortável trabalhando com administração Linux "bare metal", mas o Kubernetes ainda parece "mágico" demais para mim. O texto acima foi construído seguindo os tutoriais do K3s Rocks e, como mencionado acima, de alguma forma funciona para dois outros domínios - embora não funcionassem no início e então de alguma forma começaram a funcionar.
Eu apreciaria qualquer sugestão para esse problema, bem como qualquer recomendação sobre como eu poderia/deveria fazer melhor o que foi dito acima.
Graças ao comentário de @DavidW, consegui rastrear o problema. O CertManager estava de fato criando uma entrada apontando para:
E quando solicitei esse URL de uma rede remota, ele respondeu com o valor apropriado. Então estava funcionando, mas esse processo de testar essa resposta antes de enviar a solicitação de certificado para LetsEncrypt ainda estava falhando.
Acontece que, como esse serviço é executado em minha casa, tenho um servidor de domínio local que permite acesso local a serviços remotos. Dessa forma, quando faço uma consulta
my-domain.tld
no meu escritório em casa, recebo192.168.x.x
em vez do IP público. Como meu roteador não consegue lidar com solicitações de seu próprio IP externo provenientes de dentro da LAN, esta é minha solução alternativa.De qualquer forma, este servidor de domínio não tinha registro para
my-domain.tld
, portanto, embora uma solicitaçãomy-domain.tld
vinda de fora da minha casa tenha resolvido a URL de teste corretamente, as solicitações do CertManager provavelmente estavam recebendo algum tipo de página padrão que meu roteador retorna ao tentar acessar meu IP externo da rede interna.A solução no meu caso foi adicionar um
CNAME
registro para esse novo domínio ao meu DNS local que aponta para o nó principal do k8s.