Master Traefik 2.5: From Basics to Advanced Routing, TLS, and Kubernetes Gateway API
This comprehensive guide introduces Traefik as an open‑source edge router, explains its core components and capabilities, walks through Helm deployment, demonstrates various routing methods (Ingress, IngressRoute, CRD, Gateway API), showcases middleware usage, TLS/Let’s Encrypt configuration, TCP services, canary releases, traffic mirroring, and provides practical YAML examples for Kubernetes environments.
What is Traefik
Traefik is an open‑source edge router that makes publishing your services a fun and easy experience. It natively supports multiple clusters such as Kubernetes, Docker, Docker Swarm, AWS, Mesos, Marathon, and can handle many clusters simultaneously.
Core Concepts and Capabilities
Traefik intercepts external requests and, based on logical rules, decides how to process them. It provides automatic service discovery and updates routing rules in real time.
Requests first connect to
entrypoints, then are matched against
rules. If a rule matches, the request passes through a series of
middlewaresbefore reaching the appropriate
services.
Providers
Entrypoints
Routers
Services
Middlewares
Providers
Providers are the foundational component that discovers configuration from coordinators, container engines, cloud providers, or key‑value stores. Traefik queries the Provider API to retrieve routing information and updates routes dynamically when changes are detected.
Entrypoints
Entrypoints define the network interfaces that receive requests and specify whether they listen on TCP or UDP.
Routers
Routers analyze incoming requests and connect them to the corresponding services. Routers can also use Middlewares to modify requests, such as adding headers before forwarding to a service.
Services
Services configure how to reach the actual backend that processes the request.
Middlewares
Middlewares modify requests or make decisions (authentication, rate limiting, headers, etc.) before the request reaches the service.
Deploying Traefik
Traefik can be deployed in many ways; this guide uses the Helm method.
Helm Deployment
<code>$ helm repo add traefik https://helm.traefik.io/traefik
$ helm repo update</code> <code>$ helm search repo traefik
NAME CHART VERSION APP VERSION DESCRIPTION
traefik/traefik 10.6.0 2.5.3 A Traefik based Kubernetes ingress controller
$ helm pull traefik/traefik</code>Create a custom values file
my-value.yamlto adjust the default configuration:
<code>service:
type: NodePort
ingressRoute:
dashboard:
enabled: false
ports:
traefik:
port: 9000
expose: true
web:
port: 8000
hostPort: 80
expose: true
websecure:
port: 8443
hostPort: 443
expose: true
persistence:
enabled: true
name: data
accessMode: ReadWriteOnce
size: 5G
storageClass: "openebs-hostpath"
path: /data
additionalArguments:
- "--serversTransport.insecureSkipVerify=true"
- "--api.insecure=true"
- "--api.dashboard=true"
- "[email protected]"
- "--certificatesresolvers.coolops.acme.storage=/data/acme.json"
- "--certificatesresolvers.coolops.acme.tlschallenge=true"
</code>Install Traefik:
<code>$ helm install traefik -n traefik-ingress -f my-value.yaml .</code>Verify the deployment:
<code># kubectl get all -n traefik-ingress
NAME READY STATUS RESTARTS AGE
pod/traefik-77ff894bb5-qqszd 1/1 Running 0 6m26s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/traefik NodePort 10.108.170.22 <none> 9000:32271/TCP,80:31728/TCP,443:30358/TCP 6m26s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/traefik 1/1 1 1 6m26s
NAME DESIRED CURRENT READY AGE
replicaset.apps/traefik-77ff894bb5 1 1 1 6m26s</code>Access the Traefik dashboard via the exposed NodePort (e.g.,
http://<host>:31728/dashboard/).
Using Traefik
Creating the First Routing Rule
Two common methods are native Ingress and CRD IngressRoute.
Native Ingress Rule
<code># cat traefik-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-dashboard-ingress
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: traefik-web.coolops.cn
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: traefik
port:
number: 9000
</code> <code># kubectl apply -f traefik-ingress.yaml -n traefik-ingress
ingress.networking.k8s.io/traefik-dashboard-ingress created</code>Now the dashboard is reachable at
http://traefik-web.coolops.cn:31728/dashboard/.
CRD IngressRoute
<code># cat traefik-ingressRoute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
spec:
entryPoints:
- web
routes:
- match: Host(`traefik-web2.coolops.cn`)
kind: Rule
services:
- name: traefik
port: 9000
</code> <code># kubectl apply -f traefik-ingressRoute.yaml -n traefik-ingress
ingressroute.traefik.containo.us/traefik-dashboard-route created</code>Dashboard is now reachable at
http://traefik-web2.coolops.cn:31728/dashboard/.
Exposing HTTP Services
Deploy a simple
whoamiapplication:
<code>---
apiVersion: v1
kind: Pod
metadata:
name: whoami
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: whoami
</code>Create a routing rule to expose it:
<code># cat whoami-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: whoami-ingress
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: whoami.coolops.cn
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: whoami
port:
number: 80
</code> <code># kubectl apply -f whoami-ingress.yaml -n traefik-ingress</code>Access via the appropriate NodePort.
HTTPS and TLS
Traefik supports both custom certificates and automatic Let’s Encrypt certificates.
Using a Custom Certificate
Create a TLS secret:
<code># kubectl create secret tls whoami-tls --cert=whoami.crt --key=whoami.key</code>Define an IngressRoute with TLS:
<code># cat whoami-ingressroute-tls.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-route-tls
spec:
entryPoints:
- websecure
routes:
- match: Host(`whoami.coolops.cn`)
kind: Rule
services:
- name: whoami
port: 80
tls:
secretName: whoami-tls
</code>Now the service is reachable at
https://whoami.coolops.cn(port 443 mapped).
Automatic Let’s Encrypt
Configure a certificate resolver in
my-value.yaml:
<code>additionalArguments:
- "[email protected]"
- "--certificatesresolvers.coolops.acme.storage=/data/acme.json"
- "--certificatesresolvers.coolops.acme.tlschallenge=true"
</code>Then use the resolver in an IngressRoute:
<code># cat whoami-ingressroute-autotls.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-route-auto-tls
spec:
entryPoints:
- websecure
routes:
- match: Host(`whoami3.coolops.cn`)
kind: Rule
services:
- name: whoami
port: 80
tls:
certResolver: coolops
</code>Traefik will obtain a certificate automatically.
ACME Challenge Types
tlsChallenge – requires port 443 reachable.
httpChallenge – requires port 80 reachable.
dnsChallenge – requires DNS provider credentials (e.g., Alibaba Cloud DNS).
DNS Challenge Example (Alibaba Cloud)
<code># Create secret with Alibaba credentials
kubectl create secret generic traefik-alidns \
--from-literal=ALICLOUD_ACCESS_KEY=<access_key> \
--from-literal=ALICLOUD_SECRET_KEY=<secret_key> \
--from-literal=ALICLOUD_REGION_ID=cn-beijing \
-n traefik-ingress
</code> <code># Update my-value.yaml
additionalArguments:
- "--certificatesresolvers.coolops.acme.dnschallenge=true"
- "--certificatesresolvers.coolops.acme.dnschallenge.provider=alidns"
envFrom:
- secretRef:
name: traefik-alidns
</code>Middlewares
Middlewares can modify requests before they reach services.
Force HTTPS Redirect
<code># RedirectScheme middleware
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: redirect-https-middleware
spec:
redirectScheme:
scheme: https
</code> <code># HTTP IngressRoute using the middleware
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-http
spec:
entryPoints:
- web
routes:
- match: Host(`whoami3.coolops.cn`)
kind: Rule
services:
- name: whoami
port: 80
middlewares:
- name: redirect-https-middleware
</code>Strip Path Prefix
<code># Middleware to strip "/coolops" prefix
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: prefix-strip-middleware
spec:
stripPrefix:
prefixes:
- /coolops
</code> <code># IngressRoute using the middleware
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-prefix
spec:
entryPoints:
- web
routes:
- match: Host(`whoami7.coolops.cn`) && PathPrefix(`/coolops`)
kind: Rule
services:
- name: whoami
port: 80
middlewares:
- name: prefix-strip-middleware
</code>IP Whitelist
<code># IP whitelist middleware
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: ip-whitelist-middleware
spec:
ipWhiteList:
sourceRange:
- 127.0.0.1/32
- 192.168.100.180
</code>Attach this middleware to any route that requires restricted access.
Exposing TCP Services
Deploy a Redis instance and expose it via a custom entrypoint:
<code># Redis deployment and service (omitted for brevity)
</code> <code># Update my-value.yaml to add a TCP entrypoint
ports:
redis:
port: 6379
hostPort: 6379
additionalArguments:
- "--entryPoints.redis.address=:6379"
</code> <code># TCP IngressRoute
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: redis-traefik-tcp
spec:
entryPoints:
- redis
routes:
- match: HostSNI(`*`)
services:
- name: redis
port: 6379
</code>Now Redis can be accessed with a standard client.
Canary (Weighted) Deployments
Deploy two versions of an app (appv1 and appv2) and use a
TraefikServicewith weighted routing:
<code># appv1.yaml and appv2.yaml (deployments and services) – omitted for brevity
</code> <code># Weighted TraefikService
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
name: app-wrr
spec:
weighted:
services:
- name: appv1
weight: 3
port: 80
kind: Service
- name: appv2
weight: 1
port: 80
kind: Service
</code> <code># IngressRoute using the weighted service
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: app-ingressroute-canary
spec:
entryPoints:
- web
routes:
- match: Host(`app.coolops.cn`)
kind: Rule
services:
- name: app-wrr
kind: TraefikService
</code>Traffic will be split 75% to v1 and 25% to v2.
Traffic Mirroring
Mirror 50% of traffic from
appv1to
appv2for testing:
<code># Mirroring TraefikService
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
name: app-mirror
spec:
mirroring:
name: appv1
port: 80
mirrors:
- name: appv2
percent: 50
port: 80
</code> <code># IngressRoute using the mirroring service
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: app-ingressroute-mirror
spec:
entryPoints:
- web
routes:
- match: Host(`mirror.coolops.cn`)
kind: Rule
services:
- name: app-mirror
kind: TraefikService
</code>Kubernetes Gateway API
Traefik 2.4+ supports the Kubernetes Gateway API (v0.3.0). Install the CRDs:
<code>kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.3.0" | kubectl apply -f -</code>Create RBAC for Traefik:
<code># ClusterRole and ClusterRoleBinding (omitted for brevity)
</code>Enable the gateway provider in
my-value.yaml:
<code>additionalArguments:
- "--experimental.kubernetesgateway"
- "--providers.kubernetesgateway"
</code>Define a
GatewayClass:
<code>apiVersion: networking.x-k8s.io/v1alpha1
kind: GatewayClass
metadata:
name: traefik
spec:
controller: traefik.io/gateway-controller
</code>Create a
Gatewaythat listens on port 8000:
<code>apiVersion: networking.x-k8s.io/v1alpha1
kind: Gateway
metadata:
name: http-gateway
namespace: traefik-ingress
spec:
gatewayClassName: traefik
listeners:
- protocol: HTTP
port: 8000
routes:
kind: HTTPRoute
namespaces:
from: All
selector:
matchLabels:
app: traefik
</code>Create an
HTTPRoutefor the Traefik dashboard:
<code>apiVersion: networking.x-k8s.io/v1alpha1
kind: HTTPRoute
metadata:
name: traefik-dashboard-route
namespace: traefik-ingress
labels:
app: traefik
spec:
hostnames:
- "traefik1.coolops.cn"
rules:
- matches:
- path:
type: Prefix
value: "/"
forwardTo:
- serviceName: traefik
port: 9000
weight: 1
</code>Similarly, expose other services (e.g.,
whoami) via Gateway and
HTTPRouteresources.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.