Traefik is a great declarative ingress controller for Kubernetes. Unless you want to avail all the features of cloud-managed Application Load Balancers, Traefik can be a great alternative.
However, there are certain limitations of Traefik on the cloud platform. It can handle the TLS/SSL layer only via Kubernetes Secret or Let's Encrypt. Also, AWS ACM can only be used with ALB, CloudFront etc resources.
But you might want to have both 1) SSL termination by ACM and 2) Support for Traefik specific features (Middleware, Circuit Breaker etc) all in one place. Well, you are in luck because I have tested one form of system where you can keep using an AWS ACM-provided SSL certificate, and then handle the ingress routing using Traefik. Here is the high-level architecture of my proposed system.
To initiate such a setup, first, you will need an EKS cluster with an AWS Load Balancer Controller add-on. You can bootstrap the cluster with eksctl.
Once the cluster is ready, deploy Traefik with web
mode only (disable the websecure
entrypoint.
apiVersion: apps/v1
kind: Deployment
metadata:
name: traefik
spec:
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik
containers:
- image: docker.io/traefik:v3.0
name: traefik
ports:
- name: "web"
containerPort: 80
args:
- "--entrypoints.web.address=:80/tcp"
- "--api.dashboard=false"
- "--providers.kubernetescrd"
Then create a service for the Traefik deployment/daemonset and make it of type NodePort (ALB requires that Service must be of NodePort type as ALB backend).
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
ports:
- name: web
nodePort: 30080
port: 80
protocol: TCP
targetPort: web
selector:
app: traefik
type: NodePort
Then create an ALB Ingress with proper annotation of ACM UUID, Name and Class.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/backend-protocol: HTTP
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-southeast-1:0000000000:certificate/cb6cf41e-a6f4-4fd3-9aa5-44503f317420
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/load-balancer-name: my-lb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/success-codes: 200-404
alb.ingress.kubernetes.io/target-type: instance
name: traefik
spec:
ingressClassName: alb
rules:
- http:
paths:
- backend:
service:
name: traefik
port:
name: web
path: /*
pathType: ImplementationSpecific
Once applied, an ALB will be created. You are then free to route any HTTPS traffic through ALB and eventually, they will be routed using Traefik inside your Kubernetes Cluster. A sample IngressRoute
object will look like this.
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: my-apps
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`a.example.com`)
services:
- name: app-a
port: 80
- kind: Rule
match: Host(`b.example.com`)
services:
- name: app-b
port: 80