I used to run an Nginx reverse proxy outside of my Kubernetes cluster on a 4th Dell Optiplex acting as a monolith server. I still use it for all things I would not put on Kubernetes (eg Minecraft servers) but I want to reduce the impact of this single point of failure with regards to my Kubernetes cluster.
If that server fails, then my website will be inaccessible to the world, even if the Ghost instance is still running perfectly fine on Kubernetes.
This led me to learning about Ingress. Ingress, as the name suggests, is that thing which deals with everything going into the cluster. The cool thing is that K3S comes with Traefik, an Ingress controller, for which I can basically setup ingress rules declaratively.
While an external Nginx/Caddy instance would undoubtedly be easier to manage, there are two main advantages of the on-Kubernetes Ingress. First is, of course, the high availability. My Ingress Controller can move around seamlessly between nodes, meaning 0 downtime. Secondly, everything can be declared as a manifest which I can then keep on Github and sync with ArgoCD.
Traefik comes pre-installed with K3S by default, so that's what I will use. However, you can also use Nginx Ingress which is another option for Cloud Native Ingresses and, so I've heard, easier to use. I am also using cert-manager (installed through helm) for my TLS certificates.
So, the first thing is to create an Issuer or ClusterIssuer. This part will represent the CAs being used, and sort of acts as a middleman for getting certificates signed. I went with a ClusterIssuer as it works across the cluster and is not namespace-specific like the Issuer.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: issuer
kubernetes.io/ingress.class: traefik
labels:
app.kubernetes.io/instance: tls-ghost-ingress
name: tls-ghost-ingress
spec:
rules:
- host: alexbissessur.dev
http:
paths:
- backend:
service:
name: ghost-svc
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- alexbissessur.dev
secretName: tls-ghost-ingress
This feels somewhat self-explanatory. Basically the Ingress resource will tell the Ingress Controller (the Traefik pod) where to redirect requests to based on the destination of the request as per an HTTP header.
Now, I have this website running behind Traefik rather than behind Nginx on my single-point-of-failure. Certificates provisioned by Cert-Manager, and everything running surprisingly well!