This episode covers Traefik CRDs: IngressRoute for HTTP, IngressRouteTCP and IngressRouteUDP, the Middleware CRD, TLSOption and TLSStore, routes and services syntax, cross-namespace references, and advanced features such as weighted services, traffic splitting, and mirroring in Kubernetes.

The standard Ingress resource is enough for basic routing, but limited: no middlewares, no weighted services, no TCP/UDP support. Episode 21 introduces Traefik CRDs — Custom Resource Definitions that make Traefik in Kubernetes equivalent to all the capabilities you learned in previous episodes.
With IngressRoute, Traefik's Kubernetes configuration becomes nearly identical to the file provider: routes, services, middlewares, and tls are written directly in YAML resources. This is the most recommended way to use Traefik in modern Kubernetes.
All these resources are registered when installing Traefik via Helm — a Kubernetes Traefik deployment usually enables CRDs automatically. Check with kubectl get crd and filter for traefik to confirm.
IngressRoute replaces the standard Ingress with a more explicit structure:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: web
namespace: default
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`app.example.com`) && PathPrefix(`/api`)
middlewares:
- name: api-rate
namespace: default
services:
- name: api-service
port: 8080entryPoints: the list of entrypoints served.match: the full Traefik rule — the same syntax as episode 6.middlewares: the list of middleware CRDs with their namespaces.services: the destination backends with name and port.Middlewares are defined as separate resources, then referenced by IngressRoutes:
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: api-rate
namespace: default
spec:
rateLimit:
average: 100
burst: 50Cross-namespace references use the name@namespace syntax or an explicit namespace field. Traefik v3 also introduces namespaces for middlewares: a middleware referenced with name@namespacename can be shared across namespaces if allowed. This lets teams share security middlewares without duplication.
The TLSOption previously written in the file provider now becomes its own resource:
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: hardened
namespace: default
spec:
minVersion: VersionTLS12
cipherSuites:
- TLS_AES_128_GCM_SHA256
sniStrict: trueAn IngressRoute references it in the tls.options section:
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`app.example.com`)
services:
- name: app-service
port: 443
tls:
options:
name: hardened
certResolver: letsencryptThe canary capability we built earlier with weighted services in the file provider is now available directly in IngressRoute:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: app-canary
namespace: default
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`app.example.com`)
services:
- name: app-stable
port: 80
weight: 9
- name: app-v2
port: 80
weight: 1A 9:1 weight sends 90 percent of traffic to the stable version and 10 percent to the new version. Raising the new version's weight — e.g. to 5:5 — is done with kubectl apply without restarting Traefik. The same technique can be used for mirroring and sticky sessions by adding sticky and mirror to the resource.
Tip
For finer-grained canaries, combine weighted services with a Header rule: a small subset of users carrying a specific header are directed to the new version, the rest to the old one. This gives precise control before raising the global weight.
Key takeaways:
name@namespace syntax.In episode 22 next we will cover Kubernetes Service Mesh with Traefik Mesh — a lightweight SMI-based service mesh, traffic splitting, circuit breaking, retry, and observability features, and canary, A/B testing, and blue-green deployment patterns. You will see Traefik go beyond the ingress controller role.