Add TLS/HTTPS encrypted endpoints to your Kubernetes application with Ingress

Following up with Simple bare metal Kubernetes Cluster on Hetzner, I'd like to give a hint, how easy it can be to add an Ingress with TLS certificate to your application.
To make this work, you need to prepare five things:
- Point a domain of your choice to a node where the ingress controller is running
- Add an ingress controller
- Add cert manager for certificate management
- Issuer resource
- Ingress resource
1. Domain -> Node IP
Here you can proceed as usual with a DNS A-Record for the domain containing the IP of one of the worker nodes for example. I would do this first because it might take 24-48h depending on the TTL of your DNS Record until it's known around the globe. If it's a new domain, it should be much faster (sometimes almost instantly).
2. Nginx ingress controller
Following the official guide to install with manifests, I came up with this script:
#!/bin/bash
# adjust to your needs or get rid of it along with
# the branch argument in the clone command
version=v3.5.2
git clone https://github.com/nginxinc/kubernetes-ingress.git --branch $version
cd kubernetes-ingress
kubectl apply -f deployments/common/ns-and-sa.yaml
kubectl apply -f deployments/rbac/rbac.yaml
kubectl apply -f deployments/common/nginx-config.yaml
# uncomment annotations to make it the default ingress controller
sed -i 's/ # annotations/ annotations/g' deployments/common/ingress-class.yaml
sed -i 's/ # ingressclass/ ingressclass/g' deployments/common/ingress-class.yaml
kubectl apply -f deployments/common/ingress-class.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_virtualservers.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_virtualserverroutes.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_transportservers.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_policies.yaml
kubectl apply -f config/crd/bases/k8s.nginx.org_globalconfigurations.yaml
kubectl apply -f deploy/crds.yaml
kubectl apply -f deployments/daemon-set/nginx-ingress.yaml
Then you can take a look at the result using this. The pods should spin up very fast.
kubectl get pods --namespace=nginx-ingress
3. Cert Manager
For cert manager you can just do this and wait about a minute until the new pods are running.
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.14.6/cert-manager.yaml
4. Issuer
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: YOURMAIL@HERE.COM
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
ingressClassName: nginx
Don't forget to change the email
field to be a real mail address where you can be notified about issues with your certificates.
5. Ingress
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
cert-manager.io/issuer: "letsencrypt"
acme.cert-manager.io/http01-edit-in-place: "true"
spec:
tls:
- hosts:
- __FQDN__
secretName: my-tls
rules:
- host: __FQDN__
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-test-service
port:
number: 8080
Make sure to replace the __FQDN__
with the domain that's pointing to your IP address as mentioned in step 1. Also you need to expose your application (e.g. Deployment or Statefulset) with a service on some port. The service name and port then need to be replaced as well. This is filled out with nginx-test-service and 8080 in the example.
Applying these manifest will give the cert manager some work to do in the background, namely create and register the certificate (using other resources: order, challenge, certificate and secret) and in the end, the application should be available at the specified domain if everything was configured properly.
More information about this can be found here:
- https://cert-manager.io/docs/tutorials/acme/nginx-ingress
- https://docs.nginx.com/nginx-ingress-controller/
Happy operations!