Traefik & Kubernetes

The Kubernetes Ingress Controller, The Custom Resource Way.

Resource Configuration

If you're in a hurry, maybe you'd rather go through the dynamic configuration reference.

Traefik IngressRoute definition

  1. apiVersion: apiextensions.k8s.io/v1beta1
  2. kind: CustomResourceDefinition
  3. metadata:
  4. name: ingressroutes.traefik.containo.us
  5. spec:
  6. group: traefik.containo.us
  7. version: v1alpha1
  8. names:
  9. kind: IngressRoute
  10. plural: ingressroutes
  11. singular: ingressroute
  12. scope: Namespaced
  13. ---
  14. apiVersion: apiextensions.k8s.io/v1beta1
  15. kind: CustomResourceDefinition
  16. metadata:
  17. name: ingressroutetcps.traefik.containo.us
  18. spec:
  19. group: traefik.containo.us
  20. version: v1alpha1
  21. names:
  22. kind: IngressRouteTCP
  23. plural: ingressroutetcps
  24. singular: ingressroutetcp
  25. scope: Namespaced

That IngressRoute kind can then be used to define an IngressRoute object, such as in:

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: ingressroutefoo
  5. spec:
  6. entryPoints:
  7. - web
  8. routes:
  9. # Match is the rule corresponding to an underlying router.
  10. # Later on, match could be the simple form of a path prefix, e.g. just "/bar",
  11. # but for now we only support a traefik style matching rule.
  12. - match: Host(`foo.com`) && PathPrefix(`/bar`)
  13. # kind could eventually be one of "Rule", "Path", "Host", "Method", "Header",
  14. # "Parameter", etc, to support simpler forms of rule matching, but for now we
  15. # only support "Rule".
  16. kind: Rule
  17. # (optional) Priority disambiguates rules of the same length, for route matching.
  18. priority: 12
  19. services:
  20. - name: whoami
  21. port: 80
  22. # (default 1) A weight used by the weighted round-robin strategy (WRR).
  23. weight: 1
  24. # (default true) PassHostHeader controls whether to leave the request's Host
  25. # Header as it was before it reached the proxy, or whether to let the proxy set it
  26. # to the destination (backend) host.
  27. passHostHeader: true
  28. responseForwarding:
  29. # (default 100ms) Interval between flushes of the buffered response body to the client.
  30. flushInterval: 100ms
  31. ---
  32. apiVersion: traefik.containo.us/v1alpha1
  33. kind: IngressRouteTCP
  34. metadata:
  35. name: ingressroutetcpfoo.crd
  36. spec:
  37. entryPoints:
  38. - footcp
  39. routes:
  40. # Match is the rule corresponding to an underlying router.
  41. - match: HostSNI(`*`)
  42. services:
  43. - name: whoamitcp
  44. port: 8080

Middleware

Additionally, to allow for the use of middlewares in an IngressRoute, we defined the CRD below for the Middleware kind.

  1. apiVersion: apiextensions.k8s.io/v1beta1
  2. kind: CustomResourceDefinition
  3. metadata:
  4. name: middlewares.traefik.containo.us
  5. spec:
  6. group: traefik.containo.us
  7. version: v1alpha1
  8. names:
  9. kind: Middleware
  10. plural: middlewares
  11. singular: middleware
  12. scope: Namespaced

Once the Middleware kind has been registered with the Kubernetes cluster, it can then be used in IngressRoute definitions, such as:

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: Middleware
  3. metadata:
  4. name: stripprefix
  5. namespace: foo
  6. spec:
  7. stripPrefix:
  8. prefixes:
  9. - /stripit
  10. ---
  11. apiVersion: traefik.containo.us/v1alpha1
  12. kind: IngressRoute
  13. metadata:
  14. name: ingressroutebar
  15. spec:
  16. entryPoints:
  17. - web
  18. routes:
  19. - match: Host(`bar.com`) && PathPrefix(`/stripit`)
  20. kind: Rule
  21. services:
  22. - name: whoami
  23. port: 80
  24. middlewares:
  25. - name: stripprefix
  26. namespace: foo

Cross-provider namespace

As Kubernetes also has its own notion of namespace, one should not confuse the kubernetes namespace of a resource(in the reference to the middleware) with the provider namespace,when the definition of the middleware is from another provider.In this context, specifying a namespace when referring to the resource does not make any sense, and will be ignored.

More information about available middlewares in the dedicated middlewares section.

Services

If one needs a setup more sophisticated than a load-balancer of servers (which is a Kubernetes Service kind behind the scenes),one can define and use additional service objects specific to Traefik, based on the TraefikService kind defined in the CRD below.

  1. apiVersion: apiextensions.k8s.io/v1beta1
  2. kind: CustomResourceDefinition
  3. metadata:
  4. name: traefikservices.traefik.containo.us
  5. spec:
  6. group: traefik.containo.us
  7. version: v1alpha1
  8. names:
  9. kind: TraefikService
  10. plural: traefikservices
  11. singular: traefikservice
  12. scope: Namespaced

Once the TraefikService kind has been registered with the Kubernetes cluster, it can then be used in IngressRoute definitions(as well as recursively in other Traefik Services), such as below.Note how the name field in the IngressRoute definition now refers to a TraefikService instead of a (Kubernetes) Service.The reason this is allowed, and why a name can refer either to a TraefikService or a Service,is because the kind field is used to break the ambiguity. The allowed values for this field are TraefikService, or Service(which is the default value).

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: TraefikService
  3. metadata:
  4. name: wrr1
  5. namespace: default
  6. spec:
  7. weighted:
  8. services:
  9. - name: s2
  10. kind: Service
  11. port: 80
  12. weight: 1
  13. - name: s3
  14. weight: 1
  15. port: 80
  16. ---
  17. apiVersion: traefik.containo.us/v1alpha1
  18. kind: TraefikService
  19. metadata:
  20. name: mirror1
  21. namespace: default
  22. spec:
  23. mirroring:
  24. name: wrr1
  25. kind: TraefikService
  26. mirrors:
  27. - name: s1
  28. percent: 20
  29. port: 80
  30. ---
  31. apiVersion: traefik.containo.us/v1alpha1
  32. kind: IngressRoute
  33. metadata:
  34. name: ingressroutebar
  35. namespace: default
  36. spec:
  37. entryPoints:
  38. - web
  39. routes:
  40. - match: Host(`bar.com`) && PathPrefix(`/foo`)
  41. kind: Rule
  42. services:
  43. - name: mirror1
  44. namespace: default
  45. kind: TraefikService

References and namespaces

If the optional namespace attribute is not set, the configuration will be applied with the namespace of the current resource.

Additionally, when the definition of the TraefikService is from another provider,the cross-provider syntax ([email protected]) should be used to refer to the TraefikService, just as in the middleware case.Specifying a namespace attribute in this case would not make any sense, and will be ignored (except if the provider is kubernetescrd).

TLS Option

Additionally, to allow for the use of TLS options in an IngressRoute, we defined the CRD below for the TLSOption kind.More information about TLS Options is available in the dedicated TLS Configuration Options.

  1. apiVersion: apiextensions.k8s.io/v1beta1
  2. kind: CustomResourceDefinition
  3. metadata:
  4. name: tlsoptions.traefik.containo.us
  5. spec:
  6. group: traefik.containo.us
  7. version: v1alpha1
  8. names:
  9. kind: TLSOption
  10. plural: tlsoptions
  11. singular: tlsoption
  12. scope: Namespaced

Once the TLSOption kind has been registered with the Kubernetes cluster or defined in the File Provider, it can then be used in IngressRoute definitions, such as:

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: TLSOption
  3. metadata:
  4. name: mytlsoption
  5. namespace: default
  6. spec:
  7. minVersion: VersionTLS12
  8. ---
  9. apiVersion: traefik.containo.us/v1alpha1
  10. kind: IngressRoute
  11. metadata:
  12. name: ingressroutebar
  13. spec:
  14. entryPoints:
  15. - web
  16. routes:
  17. - match: Host(`bar.com`) && PathPrefix(`/stripit`)
  18. kind: Rule
  19. services:
  20. - name: whoami
  21. port: 80
  22. tls:
  23. options:
  24. name: mytlsoption
  25. namespace: default

References and namespaces

If the optional namespace attribute is not set, the configuration will be applied with the namespace of the IngressRoute.

Additionally, when the definition of the TLS option is from another provider,the cross-provider syntax ([email protected]) should be used to refer to the TLS option,just as in the middleware case.Specifying a namespace attribute in this case would not make any sense, and will be ignored.

TLS

To allow for TLS, we made use of the Secret kind, as it was already defined, and it can be directly used in an IngressRoute:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: supersecret
  5. data:
  6. tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
  7. tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
  8. ---
  9. apiVersion: traefik.containo.us/v1alpha1
  10. kind: IngressRoute
  11. metadata:
  12. name: ingressroutetls
  13. spec:
  14. entryPoints:
  15. - websecure
  16. routes:
  17. - match: Host(`foo.com`) && PathPrefix(`/bar`)
  18. kind: Rule
  19. services:
  20. - name: whoami
  21. port: 443
  22. tls:
  23. secretName: supersecret

Further

Also see the full example with Let's Encrypt.