How to setup Letsencrypt with Kubernetes microk8s using default Ingress?
This guide is to set up Letsencrypt with Kubernetes using Microk8s and the default Ingress controller.
Versions used:
microk8s version 1.21/stable
cert-manager v1.3.1
Pre-requisite: Forward ports 80 & 443 to your server. Set up a domain name that points to your server.
Install microk8s
snap install microk8s --classic --channel=1.21/stable
Enable dns and ingress
sudo microk8s enable dns ingress
We'll create a test webserver deployment/service using the nginx webserver image to test web traffic
webserver-depl-svc.yaml
apiVersion: apps/v1kind: Deploymentmetadata: name: webserver-deplspec: selector: matchLabels: app: webserver-app template: metadata: labels: app: webserver-app spec: containers: - name: webserver-app image: nginx:1.8---apiVersion: v1kind: Servicemetadata: name: webserver-svcspec: selector: app: webserver-app ports: - name: webserver-app protocol: TCP port: 80 targetPort: 80
apply the config file
sudo microk8s kubectl apply -f webserver-depl-svc.yaml
now to configure the default ingress to serve the test webserver
ingress-routes.yaml
apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata: name: ingress-routesspec: rules:#change yourdomain.com to your domain - host: yourdomain.com http: paths: - path: / backend: serviceName: webserver-svc servicePort: 80
Apply the ingress routes
sudo microk8s kubectl apply -f ingress-routes.yaml
When you visit yourdomain.com, you should see the default "welcome to nginx!" splash screen.
Now to install cert-manager https://cert-manager.io/docs/installation/kubernetes/
sudo microk8s kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager.yaml
The next command should show 3 pods to confirm cert-manager is installed and running
sudo microk8s kubectl get pods --n=cert-manager
Now to create the certificate issuer config. A detail to notice is that the class used in this config is public as opposed to nginx. This may be microk8s specific. https://cert-manager.io/docs/tutorials/acme/ingress/
letsencrypt-staging.yaml
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencrypt-stagingspec: acme:#change to your email email: youremail@gmail.com server: https://acme-staging-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-staging solvers: - http01: ingress: class: public
letsencrypt-prod.yaml
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencrypt-prodspec: acme: server: https://acme-v02.api.letsencrypt.org/directory#change to your email email: youremail@gmail.com privateKeySecretRef: name: letsencrypt-prod solvers: - http01: ingress: class: public
Apply both issuer configs
sudo microk8s kubectl apply -f letsencrypt-staging.yamlsudo microk8s kubectl apply -f letsencrypt-prod.yaml
now to update ingress-routes.yaml to use the staging certificate.
apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata: name: ingress-routes annotations: cert-manager.io/cluster-issuer: "letsencrypt-staging"spec: tls: - hosts:#change to your domain - yourdomain.com secretName: tls-secret rules:#change to your domain - host: yourdomain.com http: paths: - path: / backend: serviceName: webserver-svc servicePort: 80
Apply the update
sudo microk8s kubectl apply -f ingress-routes.yaml
Run the next command to confirm Ready=True
sudo microk8s kubectl get certificate
If it returned true, that means HTTP-01 challenge was successful.You can see more detail at the end of output running the next command
sudo microk8s kubectl describe certificate tls-secret
Now to change ingress-routes.yaml to use the production certificate.
apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata: name: ingress-routes annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod"spec: tls: - hosts:#change to your domain - yourdomain.com secretName: tls-secret rules:#change to your domain - host: yourdomain.com http: paths: - path: / backend: serviceName: webserver-svc servicePort: 80
Apply the update
sudo microk8s kubectl apply -f ingress-routes.yaml
Now the moment of truth. Run the next command to confirm a certificate was generated. Ready=True
sudo microk8s kubectl get certificate
Run the next command and look at the final output to verify the certificate was issued.
sudo microk8s kubectl describe certificate tls-secret
Now if you visit your domain. You should see the little lock of success! :-)