I'm starting with Kubernetes and I try to deploy my FastAPI service with Kubernetes. I try to use cert-manager
to manage SSL. I created my Deployment, Service, Ingress, and ClusterIssuer. Everything seams to be working but Let's Encrypt ACME seams to not be able to reach my issuer, and the Challenge stays in "Pending" status. What am I missing?
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-cluster-issuer
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: myemail@xxxxxx.com # removed for StackOverflow
privateKeySecretRef:
name: letsencrypt-private-key
solvers:
- http01:
ingress:
class: nginx
---
apiVersion: v1
kind: Service
metadata:
name: my-api-service
spec:
selector:
app: my-api
ports:
- name: http
protocol: TCP
port: 80
# targetPort: 8080
type: LoadBalancer
# type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-api-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-cluster-issuer
spec:
rules:
- host: api.myapp.app
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-api-service
port:
number: 80
tls:
- hosts:
- api.myapp.app
secretName: secret-ingress-cert
Result of the kubectl describe challenge
command
Status:
Presented: true
Processing: true
Reason: Waiting for HTTP-01 challenge propagation: wrong status code '404', expected '200'
State: pending
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Started 19m cert-manager-challenges Challenge scheduled for processing
Normal Presented 19m cert-manager-challenges Presented challenge using HTTP-01 challenge mechanism
Result of the kubectl get services
command:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cm-acme-http-solver-zmcjf NodePort 10.3.208.142 <none> 8089:30754/TCP 25m
kubernetes ClusterIP 10.3.0.1 <none> 443/TCP 6d2h
postgres NodePort 10.3.50.255 <none> 5432:30607/TCP 6d2h
my-api-service LoadBalancer 10.3.127.2 51.91.81.209 80:32566/TCP 6d2h
I tried many stuff, there is my DNS: api.solfy.app which is correctly forwarding to 51.91.81.209. It seams that maybe I only expose 80 port while ACME may look for HTTPS (port 443) challenge?
It seams that maybe I only expose 80 port while ACME may look for HTTPS (port 443) challenge?
No, your my-api-service
is going to be exposed via nginx reverse proxy. You can see both the 80
and 443
ports are exposed in the ingress-nginx-controller
service which has type LoadBalancer
:
k get svc ingress-nginx-controller -n ingress-nginx
You should keep my-api-service
as ClusterIP
type, no need for another public IP separately for the service, and the service provider charges you for two public IPs.
Now, the issue is so obvious. The HTTP-01
challenge has to happen via the Ingress
service but, as you pointed direct service IP in your DNS records. Your DNS record should be changed from 51.91.81.209
to the external-ip
you get from the above-mentioned command (Ingress LoadBalancer IP).
Let me know if it's not clear to you!