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

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:

  1. Point a domain of your choice to a node where the ingress controller is running
  2. Add an ingress controller
  3. Add cert manager for certificate management
  4. Issuer resource
  5. 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!

Impressum     Datenschutz