How to set a TLS enabled Ingress on Kubernetes

TL:DR: This is the ingress setting used on this website which is running on a Google Kubernetes Engine cluster. It points to a service called “reevedata-wordpress” that is running a wordpress container in another pod.

Ingress is achieved using the nginx ingress controller it was installed using helm. Once an nginx controller is installed. You can create new ingress rules as defined below. These are then combined together by nginx to make a big configuration for where traffic gets sent based on the host of the request (e.g you made a request to the ip address of this website with the hostname that leads to this blog (reevedata.com) it then pointed at the path of this post (everything after reevedata.com/*) and took you to this page.

# ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: "reevedata-ingress"
  namespace: reevedata
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    # Built in method for Redirecting requests
    # from www.reevedata.com to reevedata.com
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
  tls:
    - secretName: reevedata-com-tls
      hosts:
        - reevedata.com
  rules:
    - host: reevedata.com
      http:
        paths:
        - path: /applications/helloweb
          backend:
            servicePort: 80
            serviceName: helloweb
        - path: /
          backend:
            servicePort: 80
            serviceName: reevedata-wordpress

TLS Configuration

TLS Is configured automatically using cert-manager and the cloudflare DNS. Secrets are configured manually on the Kubernetes server.

Alternatives

If using Google Cloud ingress the setup would be very similar. “ingress.class” changes from “nginx” to “gce”. And actually if you just removed this line then currently any ingress resource created on GKE will use the google ingress by default.

#ingress-gce.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: "reevedata-ingress"
  namespace: reevedata
  annotations:
    kubernetes.io/ingress.class: gce
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - secretName: reevedata-com-tls
      hosts:
        - reevedata.com
  rules:
    - host: reevedata.com
      http:
        - path: /
          backend:
            servicePort: 80
            serviceName: reevedata-wordpress

The main reason it wasn’t used here is network traffic is that the NGINX controller creates less paid resources when being used and If I want to move this K8s cluster to another provider (e.g cheaper) then minimising reliance on cloud specific vendors can result in an increase in work. The trade-off for this is sometimes more upfront work so this is always something to consider when making the decision between set up time and ease of maintenance.

At this point is well worth noting that it is useful to become familiar with NGINX generally as its a ubiquitous way of dealing with web traffic even in more traditional set ups.