Traefik & Kubernetes

The Kubernetes Ingress Controller, The Custom Resource Way.

Configuration Examples

Configuring KubernetesCRD and Deploying/Exposing Services

Resource Definition

  1. # All resources definition must be declared
  2. apiVersion: apiextensions.k8s.io/v1beta1
  3. kind: CustomResourceDefinition
  4. metadata:
  5. name: ingressroutes.traefik.containo.us
  6. spec:
  7. group: traefik.containo.us
  8. version: v1alpha1
  9. names:
  10. kind: IngressRoute
  11. plural: ingressroutes
  12. singular: ingressroute
  13. scope: Namespaced
  14. ---
  15. apiVersion: apiextensions.k8s.io/v1beta1
  16. kind: CustomResourceDefinition
  17. metadata:
  18. name: middlewares.traefik.containo.us
  19. spec:
  20. group: traefik.containo.us
  21. version: v1alpha1
  22. names:
  23. kind: Middleware
  24. plural: middlewares
  25. singular: middleware
  26. scope: Namespaced
  27. ---
  28. apiVersion: apiextensions.k8s.io/v1beta1
  29. kind: CustomResourceDefinition
  30. metadata:
  31. name: ingressroutetcps.traefik.containo.us
  32. spec:
  33. group: traefik.containo.us
  34. version: v1alpha1
  35. names:
  36. kind: IngressRouteTCP
  37. plural: ingressroutetcps
  38. singular: ingressroutetcp
  39. scope: Namespaced
  40. ---
  41. apiVersion: apiextensions.k8s.io/v1beta1
  42. kind: CustomResourceDefinition
  43. metadata:
  44. name: ingressrouteudps.traefik.containo.us
  45. spec:
  46. group: traefik.containo.us
  47. version: v1alpha1
  48. names:
  49. kind: IngressRouteUDP
  50. plural: ingressrouteudps
  51. singular: ingressrouteudp
  52. scope: Namespaced
  53. ---
  54. apiVersion: apiextensions.k8s.io/v1beta1
  55. kind: CustomResourceDefinition
  56. metadata:
  57. name: tlsoptions.traefik.containo.us
  58. spec:
  59. group: traefik.containo.us
  60. version: v1alpha1
  61. names:
  62. kind: TLSOption
  63. plural: tlsoptions
  64. singular: tlsoption
  65. scope: Namespaced
  66. ---
  67. apiVersion: apiextensions.k8s.io/v1beta1
  68. kind: CustomResourceDefinition
  69. metadata:
  70. name: tlsstores.traefik.containo.us
  71. spec:
  72. group: traefik.containo.us
  73. version: v1alpha1
  74. names:
  75. kind: TLSStore
  76. plural: tlsstores
  77. singular: tlsstore
  78. scope: Namespaced
  79. ---
  80. apiVersion: apiextensions.k8s.io/v1beta1
  81. kind: CustomResourceDefinition
  82. metadata:
  83. name: traefikservices.traefik.containo.us
  84. spec:
  85. group: traefik.containo.us
  86. version: v1alpha1
  87. names:
  88. kind: TraefikService
  89. plural: traefikservices
  90. singular: traefikservice
  91. scope: Namespaced

RBAC

  1. kind: ClusterRole
  2. apiVersion: rbac.authorization.k8s.io/v1beta1
  3. metadata:
  4. name: traefik-ingress-controller
  5. rules:
  6. - apiGroups:
  7. - ""
  8. resources:
  9. - services
  10. - endpoints
  11. - secrets
  12. verbs:
  13. - get
  14. - list
  15. - watch
  16. - apiGroups:
  17. - extensions
  18. - networking.k8s.io
  19. resources:
  20. - ingresses
  21. - ingressclasses
  22. verbs:
  23. - get
  24. - list
  25. - watch
  26. - apiGroups:
  27. - extensions
  28. resources:
  29. - ingresses/status
  30. verbs:
  31. - update
  32. - apiGroups:
  33. - traefik.containo.us
  34. resources:
  35. - middlewares
  36. - ingressroutes
  37. - traefikservices
  38. - ingressroutetcps
  39. - ingressrouteudps
  40. - tlsoptions
  41. - tlsstores
  42. verbs:
  43. - get
  44. - list
  45. - watch
  46. ---
  47. kind: ClusterRoleBinding
  48. apiVersion: rbac.authorization.k8s.io/v1beta1
  49. metadata:
  50. name: traefik-ingress-controller
  51. roleRef:
  52. apiGroup: rbac.authorization.k8s.io
  53. kind: ClusterRole
  54. name: traefik-ingress-controller
  55. subjects:
  56. - kind: ServiceAccount
  57. name: traefik-ingress-controller
  58. namespace: default

Traefik

  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4. name: traefik-ingress-controller
  5. ---
  6. kind: Deployment
  7. apiVersion: apps/v1
  8. metadata:
  9. name: traefik
  10. labels:
  11. app: traefik
  12. spec:
  13. replicas: 1
  14. selector:
  15. matchLabels:
  16. app: traefik
  17. template:
  18. metadata:
  19. labels:
  20. app: traefik
  21. spec:
  22. serviceAccountName: traefik-ingress-controller
  23. containers:
  24. - name: traefik
  25. image: traefik:v2.3
  26. args:
  27. - --log.level=DEBUG
  28. - --api
  29. - --api.insecure
  30. - --entrypoints.web.address=:80
  31. - --entrypoints.tcpep.address=:8000
  32. - --entrypoints.udpep.address=:9000/udp
  33. - --providers.kubernetescrd
  34. ports:
  35. - name: web
  36. containerPort: 80
  37. - name: admin
  38. containerPort: 8080
  39. - name: tcpep
  40. containerPort: 8000
  41. - name: udpep
  42. containerPort: 9000
  43. ---
  44. apiVersion: v1
  45. kind: Service
  46. metadata:
  47. name: traefik
  48. spec:
  49. type: LoadBalancer
  50. selector:
  51. app: traefik
  52. ports:
  53. - protocol: TCP
  54. port: 80
  55. name: web
  56. targetPort: 80
  57. - protocol: TCP
  58. port: 8080
  59. name: admin
  60. targetPort: 8080
  61. - protocol: TCP
  62. port: 8000
  63. name: tcpep
  64. targetPort: 8000
  65. ---
  66. apiVersion: v1
  67. kind: Service
  68. metadata:
  69. name: traefikudp
  70. spec:
  71. type: LoadBalancer
  72. selector:
  73. app: traefik
  74. ports:
  75. - protocol: UDP
  76. port: 9000
  77. name: udpep
  78. targetPort: 9000

IngressRoute

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: myingressroute
  5. namespace: default
  6. spec:
  7. entryPoints:
  8. - web
  9. routes:
  10. - match: Host(`foo`) && PathPrefix(`/bar`)
  11. kind: Rule
  12. services:
  13. - name: whoami
  14. port: 80
  15. ---
  16. apiVersion: traefik.containo.us/v1alpha1
  17. kind: IngressRouteTCP
  18. metadata:
  19. name: ingressroute.tcp
  20. namespace: default
  21. spec:
  22. entryPoints:
  23. - tcpep
  24. routes:
  25. - match: HostSNI(`bar`)
  26. kind: Rule
  27. services:
  28. - name: whoamitcp
  29. port: 8080
  30. ---
  31. apiVersion: traefik.containo.us/v1alpha1
  32. kind: IngressRouteUDP
  33. metadata:
  34. name: ingressroute.udp
  35. namespace: default
  36. spec:
  37. entryPoints:
  38. - fooudp
  39. routes:
  40. - kind: Rule
  41. services:
  42. - name: whoamiudp
  43. port: 8080

Whoami

  1. kind: Deployment
  2. apiVersion: apps/v1
  3. metadata:
  4. name: whoami
  5. namespace: default
  6. labels:
  7. app: traefiklabs
  8. name: whoami
  9. spec:
  10. replicas: 2
  11. selector:
  12. matchLabels:
  13. app: traefiklabs
  14. task: whoami
  15. template:
  16. metadata:
  17. labels:
  18. app: traefiklabs
  19. task: whoami
  20. spec:
  21. containers:
  22. - name: whoami
  23. image: traefik/whoami
  24. ports:
  25. - containerPort: 80
  26. ---
  27. apiVersion: v1
  28. kind: Service
  29. metadata:
  30. name: whoami
  31. namespace: default
  32. spec:
  33. ports:
  34. - name: http
  35. port: 80
  36. selector:
  37. app: traefiklabs
  38. task: whoami
  39. ---
  40. kind: Deployment
  41. apiVersion: apps/v1
  42. metadata:
  43. name: whoamitcp
  44. namespace: default
  45. labels:
  46. app: traefiklabs
  47. name: whoamitcp
  48. spec:
  49. replicas: 2
  50. selector:
  51. matchLabels:
  52. app: traefiklabs
  53. task: whoamitcp
  54. template:
  55. metadata:
  56. labels:
  57. app: traefiklabs
  58. task: whoamitcp
  59. spec:
  60. containers:
  61. - name: whoamitcp
  62. image: traefik/whoamitcp
  63. ports:
  64. - containerPort: 8080
  65. ---
  66. apiVersion: v1
  67. kind: Service
  68. metadata:
  69. name: whoamitcp
  70. namespace: default
  71. spec:
  72. ports:
  73. - protocol: TCP
  74. port: 8080
  75. selector:
  76. app: traefiklabs
  77. task: whoamitcp
  78. ---
  79. kind: Deployment
  80. apiVersion: apps/v1
  81. metadata:
  82. name: whoamiudp
  83. namespace: default
  84. labels:
  85. app: traefiklabs
  86. name: whoamiudp
  87. spec:
  88. replicas: 2
  89. selector:
  90. matchLabels:
  91. app: traefiklabs
  92. task: whoamiudp
  93. template:
  94. metadata:
  95. labels:
  96. app: traefiklabs
  97. task: whoamiudp
  98. spec:
  99. containers:
  100. - name: whoamiudp
  101. image: traefik/whoamiudp:latest
  102. ports:
  103. - containerPort: 8080
  104. ---
  105. apiVersion: v1
  106. kind: Service
  107. metadata:
  108. name: whoamiudp
  109. namespace: default
  110. spec:
  111. ports:
  112. - port: 8080
  113. selector:
  114. app: traefiklabs
  115. task: whoamiudp

Routing Configuration

Custom Resource Definition (CRD)

  • You can find an exhaustive list, generated from Traefik’s source code, of the custom resources and their attributes in the reference page.
  • Validate that the prerequisites are fulfilled before using the Traefik custom resources.
  • Traefik CRDs are building blocks that you can assemble according to your needs.

You can find an excerpt of the available custom resources in the table below:

KindPurposeConcept Behind
IngressRouteHTTP RoutingHTTP router
MiddlewareTweaks the HTTP requests before they are sent to your serviceHTTP Middlewares
TraefikServiceAbstraction for HTTP loadbalancing/mirroringHTTP service
IngressRouteTCPTCP RoutingTCP router
IngressRouteUDPUDP RoutingUDP router
TLSOptionsAllows to configure some parameters of the TLS connectionTLSOptions
TLSStoresAllows to configure the default TLS storeTLSStores

Kind: IngressRoute

IngressRoute is the CRD implementation of a Traefik HTTP router.

Register the IngressRoute kind in the Kubernetes cluster before creating IngressRoute objects.

IngressRoute Attributes

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: foo
  5. namespace: bar
  6. spec:
  7. entryPoints: # [1]
  8. - foo
  9. routes: # [2]
  10. - kind: Rule
  11. match: Host(`test.example.com`) # [3]
  12. priority: 10 # [4]
  13. middlewares: # [5]
  14. - name: middleware1 # [6]
  15. namespace: default # [7]
  16. services: # [8]
  17. - kind: Service
  18. name: foo
  19. namespace: default
  20. passHostHeader: true
  21. port: 80
  22. responseForwarding:
  23. flushInterval: 1ms
  24. scheme: https
  25. sticky:
  26. cookie:
  27. httpOnly: true
  28. name: cookie
  29. secure: true
  30. sameSite: none
  31. strategy: RoundRobin
  32. weight: 10
  33. tls: # [9]
  34. secretName: supersecret # [10]
  35. options: # [11]
  36. name: opt # [12]
  37. namespace: default # [13]
  38. certResolver: foo # [14]
  39. domains: # [15]
  40. - main: example.net # [16]
  41. sans: # [17]
  42. - a.example.net
  43. - b.example.net
RefAttributePurpose
[1]entryPointsList of entry points names
[2]routesList of routes
[3]routes[n].matchDefines the rule corresponding to an underlying router.
[4]routes[n].priorityDisambiguate rules of the same length, for route matching
[5]routes[n].middlewaresList of reference to Middleware
[6]middlewares[n].nameDefines the Middleware name
[7]middlewares[n].namespaceDefines the Middleware namespace
[8]routes[n].servicesList of any combination of TraefikService and reference to a Kubernetes service (See below for ExternalName Service setup)
[9]tlsDefines TLS certificate configuration
[10]tls.secretNameDefines the secret name used to store the certificate (in the IngressRoute namespace)
[11]tls.optionsDefines the reference to a TLSOption
[12]options.nameDefines the TLSOption name
[13]options.namespaceDefines the TLSOption namespace
[14]tls.certResolverDefines the reference to a CertResolver
[15]tls.domainsList of domains
[16]domains[n].mainDefines the main domain name
[17]domains[n].sansList of SANs (alternative domains)

Declaring an IngressRoute

IngressRoute

  1. # All resources definition must be declared
  2. apiVersion: traefik.containo.us/v1alpha1
  3. kind: IngressRoute
  4. metadata:
  5. name: testName
  6. namespace: default
  7. spec:
  8. entryPoints:
  9. - web
  10. routes:
  11. - kind: Rule
  12. match: Host(`test.example.com`)
  13. middlewares:
  14. - name: middleware1
  15. namespace: default
  16. priority: 10
  17. services:
  18. - kind: Service
  19. name: foo
  20. namespace: default
  21. passHostHeader: true
  22. port: 80
  23. responseForwarding:
  24. flushInterval: 1ms
  25. scheme: https
  26. sticky:
  27. cookie:
  28. httpOnly: true
  29. name: cookie
  30. secure: true
  31. strategy: RoundRobin
  32. weight: 10
  33. tls:
  34. certResolver: foo
  35. domains:
  36. - main: example.net
  37. sans:
  38. - a.example.net
  39. - b.example.net
  40. options:
  41. name: opt
  42. namespace: default
  43. secretName: supersecret

Middlewares

  1. # All resources definition must be declared
  2. # Prefixing with /foo
  3. apiVersion: traefik.containo.us/v1alpha1
  4. kind: Middleware
  5. metadata:
  6. name: middleware1
  7. namespace: default
  8. spec:
  9. addPrefix:
  10. prefix: /foo

TLSOption

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: TLSOption
  3. metadata:
  4. name: opt
  5. namespace: default
  6. spec:
  7. minVersion: VersionTLS12

Secret

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: supersecret
  5. data:
  6. tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
  7. tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=

Configuring Backend Protocol

There are 3 ways to configure the backend protocol for communication between Traefik and your pods:

  • Setting the scheme explicitly (http/https/h2c)
  • Configuring the name of the kubernetes service port to start with https (https)
  • Setting the kubernetes service port to use port 443 (https)

If you do not configure the above, Traefik will assume an http connection.

Using Kubernetes ExternalName Service

Traefik backends creation needs a port to be set, however Kubernetes ExternalName Service could be defined without any port. Accordingly, Traefik supports defining a port in two ways:

  • only on IngressRoute service
  • on both sides, you’ll be warned if the ports don’t match, and the IngressRoute service port is used

Thus, in case of two sides port definition, Traefik expects a match between ports.

Examples

IngressRoute

  1. ---
  2. apiVersion: traefik.containo.us/v1alpha1
  3. kind: IngressRoute
  4. metadata:
  5. name: test.route
  6. namespace: default
  7. spec:
  8. entryPoints:
  9. - foo
  10. routes:
  11. - match: Host(`example.net`)
  12. kind: Rule
  13. services:
  14. - name: external-svc
  15. port: 80
  16. ---
  17. apiVersion: v1
  18. kind: Service
  19. metadata:
  20. name: external-svc
  21. namespace: default
  22. spec:
  23. externalName: external.domain
  24. type: ExternalName

ExternalName Service

  1. ---
  2. apiVersion: traefik.containo.us/v1alpha1
  3. kind: IngressRoute
  4. metadata:
  5. name: test.route
  6. namespace: default
  7. spec:
  8. entryPoints:
  9. - foo
  10. routes:
  11. - match: Host(`example.net`)
  12. kind: Rule
  13. services:
  14. - name: external-svc
  15. ---
  16. apiVersion: v1
  17. kind: Service
  18. metadata:
  19. name: external-svc
  20. namespace: default
  21. spec:
  22. externalName: external.domain
  23. type: ExternalName
  24. ports:
  25. - port: 80

Both sides

  1. ---
  2. apiVersion: traefik.containo.us/v1alpha1
  3. kind: IngressRoute
  4. metadata:
  5. name: test.route
  6. namespace: default
  7. spec:
  8. entryPoints:
  9. - foo
  10. routes:
  11. - match: Host(`example.net`)
  12. kind: Rule
  13. services:
  14. - name: external-svc
  15. port: 80
  16. ---
  17. apiVersion: v1
  18. kind: Service
  19. metadata:
  20. name: external-svc
  21. namespace: default
  22. spec:
  23. externalName: external.domain
  24. type: ExternalName
  25. ports:
  26. - port: 80

Kind: Middleware

Middleware is the CRD implementation of a Traefik middleware.

Register the Middleware kind in the Kubernetes cluster before creating Middleware objects or referencing middlewares in the IngressRoute objects.

Declaring and Referencing a Middleware

Middleware

  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

IngressRoute

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: ingressroutebar
  5. spec:
  6. entryPoints:
  7. - web
  8. routes:
  9. - match: Host(`example.com`) && PathPrefix(`/stripit`)
  10. kind: Rule
  11. services:
  12. - name: whoami
  13. port: 80
  14. middlewares:
  15. - name: stripprefix
  16. 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 comes from another provider. In this context, specifying a namespace when referring to the resource does not make any sense, and will be ignored. Additionally, when you want to reference a Middleware from the CRD Provider, you have to append the namespace of the resource in the resource-name as Traefik appends the namespace internally automatically.

More information about available middlewares in the dedicated middlewares section.

Kind: TraefikService

TraefikService is the CRD implementation of a “Traefik Service”.

Register the TraefikService kind in the Kubernetes cluster before creating TraefikService objects, referencing services in the IngressRoute objects, or recursively in others TraefikService objects.

Disambiguate Traefik and Kubernetes Services

As the field name can reference different types of objects, use the field kind to avoid any ambiguity.

The field kind allows the following values:

TraefikService object allows to use any (valid) combinations of:

Server Load Balancing

More information in the dedicated server load balancing section.

Declaring and Using Server Load Balancing

IngressRoute

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: ingressroutebar
  5. namespace: default
  6. spec:
  7. entryPoints:
  8. - web
  9. routes:
  10. - match: Host(`example.com`) && PathPrefix(`/foo`)
  11. kind: Rule
  12. services:
  13. - name: svc1
  14. namespace: default
  15. - name: svc2
  16. namespace: default

K8s Service

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: svc1
  5. namespace: default
  6. spec:
  7. ports:
  8. - name: http
  9. port: 80
  10. selector:
  11. app: traefiklabs
  12. task: app1
  13. ---
  14. apiVersion: v1
  15. kind: Service
  16. metadata:
  17. name: svc2
  18. namespace: default
  19. spec:
  20. ports:
  21. - name: http
  22. port: 80
  23. selector:
  24. app: traefiklabs
  25. task: app2

Weighted Round Robin

More information in the dedicated Weighted Round Robin service load balancing section.

Declaring and Using Weighted Round Robin

IngressRoute

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: ingressroutebar
  5. namespace: default
  6. spec:
  7. entryPoints:
  8. - web
  9. routes:
  10. - match: Host(`example.com`) && PathPrefix(`/foo`)
  11. kind: Rule
  12. services:
  13. - name: wrr1
  14. namespace: default
  15. kind: TraefikService

Weighted Round Robin

  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: svc1
  10. port: 80
  11. weight: 1
  12. - name: wrr2
  13. kind: TraefikService
  14. weight: 1
  15. - name: mirror1
  16. kind: TraefikService
  17. weight: 1
  18. ---
  19. apiVersion: traefik.containo.us/v1alpha1
  20. kind: TraefikService
  21. metadata:
  22. name: wrr2
  23. namespace: default
  24. spec:
  25. weighted:
  26. services:
  27. - name: svc2
  28. port: 80
  29. weight: 1
  30. - name: svc3
  31. port: 80
  32. weight: 1

K8s Service

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: svc1
  5. namespace: default
  6. spec:
  7. ports:
  8. - name: http
  9. port: 80
  10. selector:
  11. app: traefiklabs
  12. task: app1
  13. ---
  14. apiVersion: v1
  15. kind: Service
  16. metadata:
  17. name: svc2
  18. namespace: default
  19. spec:
  20. ports:
  21. - name: http
  22. port: 80
  23. selector:
  24. app: traefiklabs
  25. task: app2
  26. ---
  27. apiVersion: v1
  28. kind: Service
  29. metadata:
  30. name: svc3
  31. namespace: default
  32. spec:
  33. ports:
  34. - name: http
  35. port: 80
  36. selector:
  37. app: traefiklabs
  38. task: app3

Mirroring

More information in the dedicated mirroring service section.

Declaring and Using Mirroring

IngressRoute

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: ingressroutebar
  5. namespace: default
  6. spec:
  7. entryPoints:
  8. - web
  9. routes:
  10. - match: Host(`example.com`) && PathPrefix(`/foo`)
  11. kind: Rule
  12. services:
  13. - name: mirror1
  14. namespace: default
  15. kind: TraefikService

Mirroring k8s Service

  1. # Mirroring from a k8s Service
  2. apiVersion: traefik.containo.us/v1alpha1
  3. kind: TraefikService
  4. metadata:
  5. name: mirror1
  6. namespace: default
  7. spec:
  8. mirroring:
  9. name: svc1
  10. port: 80
  11. mirrors:
  12. - name: svc2
  13. port: 80
  14. percent: 20
  15. - name: svc3
  16. kind: TraefikService
  17. percent: 20

Mirroring Traefik Service

  1. # Mirroring from a Traefik Service
  2. apiVersion: traefik.containo.us/v1alpha1
  3. kind: TraefikService
  4. metadata:
  5. name: mirror1
  6. namespace: default
  7. spec:
  8. mirroring:
  9. name: wrr1
  10. kind: TraefikService
  11. mirrors:
  12. - name: svc2
  13. port: 80
  14. percent: 20
  15. - name: svc3
  16. kind: TraefikService
  17. percent: 20

K8s Service

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: svc1
  5. namespace: default
  6. spec:
  7. ports:
  8. - name: http
  9. port: 80
  10. selector:
  11. app: traefiklabs
  12. task: app1
  13. ---
  14. apiVersion: v1
  15. kind: Service
  16. metadata:
  17. name: svc2
  18. namespace: default
  19. spec:
  20. ports:
  21. - name: http
  22. port: 80
  23. selector:
  24. app: traefiklabs
  25. task: app2

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 (service@provider) 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).

Stickiness and load-balancing

As explained in the section about Sticky sessions, for stickiness to work all the way, it must be specified at each load-balancing level.

For instance, in the example below, there is a first level of load-balancing because there is a (Weighted Round Robin) load-balancing of the two whoami services, and there is a second level because each whoami service is a replicaset and is thus handled as a load-balancer of servers.

Stickiness on two load-balancing levels

IngressRoute

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: ingressroutebar
  5. namespace: default
  6. spec:
  7. entryPoints:
  8. - web
  9. routes:
  10. - match: Host(`example.com`) && PathPrefix(`/foo`)
  11. kind: Rule
  12. services:
  13. - name: wrr1
  14. namespace: default
  15. kind: TraefikService

Weighted Round Robin

  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: whoami1
  10. kind: Service
  11. port: 80
  12. weight: 1
  13. sticky:
  14. cookie:
  15. name: lvl2
  16. - name: whoami2
  17. kind: Service
  18. weight: 1
  19. port: 80
  20. sticky:
  21. cookie:
  22. name: lvl2
  23. sticky:
  24. cookie:
  25. name: lvl1

K8s Service

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: whoami1
  5. spec:
  6. ports:
  7. - protocol: TCP
  8. name: web
  9. port: 80
  10. selector:
  11. app: whoami1
  12. ---
  13. apiVersion: v1
  14. kind: Service
  15. metadata:
  16. name: whoami2
  17. spec:
  18. ports:
  19. - protocol: TCP
  20. name: web
  21. port: 80
  22. selector:
  23. app: whoami2

Deployment (to illustrate replicas)

  1. kind: Deployment
  2. apiVersion: apps/v1
  3. metadata:
  4. namespace: default
  5. name: whoami1
  6. labels:
  7. app: whoami1
  8. spec:
  9. replicas: 2
  10. selector:
  11. matchLabels:
  12. app: whoami1
  13. template:
  14. metadata:
  15. labels:
  16. app: whoami1
  17. spec:
  18. containers:
  19. - name: whoami1
  20. image: traefik/whoami
  21. ports:
  22. - name: web
  23. containerPort: 80
  24. ---
  25. kind: Deployment
  26. apiVersion: apps/v1
  27. metadata:
  28. namespace: default
  29. name: whoami2
  30. labels:
  31. app: whoami2
  32. spec:
  33. replicas: 2
  34. selector:
  35. matchLabels:
  36. app: whoami2
  37. template:
  38. metadata:
  39. labels:
  40. app: whoami2
  41. spec:
  42. containers:
  43. - name: whoami2
  44. image: traefik/whoami
  45. ports:
  46. - name: web
  47. containerPort: 80

To keep a session open with the same server, the client would then need to specify the two levels within the cookie for each request, e.g. with curl:

  1. curl -H Host:example.com -b "lvl1=default-whoami1-80; lvl2=http://10.42.0.6:80" http://localhost:8000/foo

assuming 10.42.0.6 is the IP address of one of the replicas (a pod then) of the whoami1 service.

Kind IngressRouteTCP

IngressRouteTCP is the CRD implementation of a Traefik TCP router.

Register the IngressRouteTCP kind in the Kubernetes cluster before creating IngressRouteTCP objects.

IngressRouteTCP Attributes

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRouteTCP
  3. metadata:
  4. name: ingressroutetcpfoo
  5. spec:
  6. entryPoints: # [1]
  7. - footcp
  8. routes: # [2]
  9. - match: HostSNI(`*`) # [3]
  10. services: # [4]
  11. - name: foo # [5]
  12. port: 8080 # [6]
  13. weight: 10 # [7]
  14. terminationDelay: 400 # [8]
  15. tls: # [9]
  16. secretName: supersecret # [10]
  17. options: # [11]
  18. name: opt # [12]
  19. namespace: default # [13]
  20. certResolver: foo # [14]
  21. domains: # [15]
  22. - main: example.net # [16]
  23. sans: # [17]
  24. - a.example.net
  25. - b.example.net
  26. passthrough: false # [18]
RefAttributePurpose
[1]entryPointsList of entrypoints names
[2]routesList of routes
[3]routes[n].matchDefines the rule corresponding to an underlying router
[4]routes[n].servicesList of Kubernetes service definitions (See below for ExternalName Service setup)
[5]services[n].nameDefines the name of a Kubernetes service
[6]services[n].portDefines the port of a Kubernetes service
[7]services[n].weightDefines the weight to apply to the server load balancing
[8]services[n].terminationDelaycorresponds to the deadline that the proxy sets, after one of its connected peers indicates it has closed the writing capability of its connection, to close the reading capability as well, hence fully terminating the connection.
It is a duration in milliseconds, defaulting to 100. A negative value means an infinite deadline (i.e. the reading capability is never closed).
[9]tlsDefines TLS certificate configuration
[10]tls.secretNameDefines the secret name used to store the certificate (in the IngressRoute namespace)
[11]tls.optionsDefines the reference to a TLSOption
[12]options.nameDefines the TLSOption name
[13]options.namespaceDefines the TLSOption namespace
[14]tls.certResolverDefines the reference to a CertResolver
[15]tls.domainsList of domains
[16]domains[n].mainDefines the main domain name
[17]domains[n].sansList of SANs (alternative domains)
[18]tls.passthroughIf true, delegates the TLS termination to the backend

Declaring an IngressRouteTCP

IngressRouteTCP

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRouteTCP
  3. metadata:
  4. name: ingressroutetcpfoo
  5. spec:
  6. entryPoints:
  7. - footcp
  8. routes:
  9. # Match is the rule corresponding to an underlying router.
  10. - match: HostSNI(`*`)
  11. services:
  12. - name: foo
  13. port: 8080
  14. terminationDelay: 400
  15. weight: 10
  16. - name: bar
  17. port: 8081
  18. terminationDelay: 500
  19. weight: 10
  20. tls:
  21. certResolver: foo
  22. domains:
  23. - main: example.net
  24. sans:
  25. - a.example.net
  26. - b.example.net
  27. options:
  28. name: opt
  29. namespace: default
  30. secretName: supersecret
  31. passthrough: false

TLSOption

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: TLSOption
  3. metadata:
  4. name: opt
  5. namespace: default
  6. spec:
  7. minVersion: VersionTLS12

Secret

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: supersecret
  5. data:
  6. tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
  7. tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=

Using Kubernetes ExternalName Service

Traefik backends creation needs a port to be set, however Kubernetes ExternalName Service could be defined without any port. Accordingly, Traefik supports defining a port in two ways:

  • only on IngressRouteTCP service
  • on both sides, you’ll be warned if the ports don’t match, and the IngressRouteTCP service port is used

Thus, in case of two sides port definition, Traefik expects a match between ports.

Examples

IngressRouteTCP

  1. ---
  2. apiVersion: traefik.containo.us/v1alpha1
  3. kind: IngressRouteTCP
  4. metadata:
  5. name: test.route
  6. namespace: default
  7. spec:
  8. entryPoints:
  9. - foo
  10. routes:
  11. - match: HostSNI(`*`)
  12. kind: Rule
  13. services:
  14. - name: external-svc
  15. port: 80
  16. ---
  17. apiVersion: v1
  18. kind: Service
  19. metadata:
  20. name: external-svc
  21. namespace: default
  22. spec:
  23. externalName: external.domain
  24. type: ExternalName

ExternalName Service

  1. ---
  2. apiVersion: traefik.containo.us/v1alpha1
  3. kind: IngressRouteTCP
  4. metadata:
  5. name: test.route
  6. namespace: default
  7. spec:
  8. entryPoints:
  9. - foo
  10. routes:
  11. - match: HostSNI(`*`)
  12. kind: Rule
  13. services:
  14. - name: external-svc
  15. ---
  16. apiVersion: v1
  17. kind: Service
  18. metadata:
  19. name: external-svc
  20. namespace: default
  21. spec:
  22. externalName: external.domain
  23. type: ExternalName
  24. ports:
  25. - port: 80

Both sides

  1. ---
  2. apiVersion: traefik.containo.us/v1alpha1
  3. kind: IngressRouteTCP
  4. metadata:
  5. name: test.route
  6. namespace: default
  7. spec:
  8. entryPoints:
  9. - foo
  10. routes:
  11. - match: HostSNI(`*`)
  12. kind: Rule
  13. services:
  14. - name: external-svc
  15. port: 80
  16. ---
  17. apiVersion: v1
  18. kind: Service
  19. metadata:
  20. name: external-svc
  21. namespace: default
  22. spec:
  23. externalName: external.domain
  24. type: ExternalName
  25. ports:
  26. - port: 80

Kind IngressRouteUDP

IngressRouteUDP is the CRD implementation of a Traefik UDP router.

Register the IngressRouteUDP kind in the Kubernetes cluster before creating IngressRouteUDP objects.

IngressRouteUDP Attributes

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRouteUDP
  3. metadata:
  4. name: ingressrouteudpfoo
  5. spec:
  6. entryPoints: # [1]
  7. - fooudp
  8. routes: # [2]
  9. - services: # [3]
  10. - name: foo # [4]
  11. port: 8080 # [5]
  12. weight: 10 # [6]
RefAttributePurpose
[1]entryPointsList of entrypoints names
[2]routesList of routes
[3]routes[n].servicesList of Kubernetes service definitions
[4]services[n].nameDefines the name of a Kubernetes service
[6]services[n].portDefines the port of a Kubernetes service
[7]services[n].weightDefines the weight to apply to the server load balancing

Declaring an IngressRouteUDP

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRouteUDP
  3. metadata:
  4. name: ingressrouteudpfoo
  5. spec:
  6. entryPoints:
  7. - fooudp
  8. routes:
  9. - services:
  10. - name: foo
  11. port: 8080
  12. weight: 10
  13. - name: bar
  14. port: 8081
  15. weight: 10

Kind: TLSOption

TLSOption is the CRD implementation of a Traefik “TLS Option”.

Register the TLSOption kind in the Kubernetes cluster before creating TLSOption objects or referencing TLS options in the IngressRoute / IngressRouteTCP objects.

TLSOption Attributes

TLSOption

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: TLSOption
  3. metadata:
  4. name: mytlsoption
  5. namespace: default
  6. spec:
  7. minVersion: VersionTLS12 # [1]
  8. maxVersion: VersionTLS13 # [1]
  9. curvePreferences: # [3]
  10. - CurveP521
  11. - CurveP384
  12. cipherSuites: # [4]
  13. - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  14. - TLS_RSA_WITH_AES_256_GCM_SHA384
  15. clientAuth: # [5]
  16. secretNames: # [6]
  17. - secretCA1
  18. - secretCA2
  19. clientAuthType: VerifyClientCertIfGiven # [7]
  20. sniStrict: true # [8]
RefAttributePurpose
[1]minVersionDefines the minimum TLS version that is acceptable
[2]maxVersionDefines the maximum TLS version that is acceptable
[3]cipherSuiteslist of supported cipher suites for TLS versions up to TLS 1.2
[4]curvePreferencesList of the elliptic curves references that will be used in an ECDHE handshake, in preference order
[5]clientAuthdetermines the server’s policy for TLS Client Authentication
[6]clientAuth.secretNameslist of names of the referenced Kubernetes Secrets (in TLSOption namespace)
[7]clientAuth.clientAuthTypedefines the client authentication type to apply. The available values are: NoClientCert, RequestClientCert, VerifyClientCertIfGiven and RequireAndVerifyClientCert
[8]sniStrictif true, Traefik won’t allow connections from clients connections that do not specify a server_name extension

Declaring and referencing a TLSOption

TLSOption

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: TLSOption
  3. metadata:
  4. name: mytlsoption
  5. namespace: default
  6. spec:
  7. minVersion: VersionTLS12
  8. sniStrict: true
  9. cipherSuites:
  10. - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  11. - TLS_RSA_WITH_AES_256_GCM_SHA384
  12. clientAuth:
  13. secretNames:
  14. - secretCA1
  15. - secretCA2
  16. clientAuthType: VerifyClientCertIfGiven

IngressRoute

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

Secrets

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: secretCA1
  5. namespace: default
  6. data:
  7. tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
  8. ---
  9. apiVersion: v1
  10. kind: Secret
  11. metadata:
  12. name: secretCA2
  13. namespace: default
  14. data:
  15. tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=

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 (middlewarename@provider) 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.

Kind: TLSStore

TLSStore is the CRD implementation of a Traefik “TLS Store”.

Register the TLSStore kind in the Kubernetes cluster before creating TLSStore objects or referencing TLS stores in the IngressRoute / IngressRouteTCP objects.

Default TLS Store

Traefik currently only uses the TLS Store named “default”. This means that if you have two stores that are named default in different kubernetes namespaces, they may be randomly chosen. For the time being, please only configure one TLSSTore named default.

TLSStore Attributes

TLSStore

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: TLSStore
  3. metadata:
  4. name: default
  5. namespace: default
  6. spec:
  7. defaultCertificate:
  8. secretName: mySecret # [1]
RefAttributePurpose
[1]secretNameThe name of the referenced Kubernetes Secret that holds the default certificate for the store.

Declaring and referencing a TLSStore

TLSStore

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: TLSStore
  3. metadata:
  4. name: default
  5. namespace: default
  6. spec:
  7. defaultCertificate:
  8. secretName: supersecret

IngressRoute

  1. apiVersion: traefik.containo.us/v1alpha1
  2. kind: IngressRoute
  3. metadata:
  4. name: ingressroutebar
  5. spec:
  6. entryPoints:
  7. - web
  8. routes:
  9. - match: Host(`example.com`) && PathPrefix(`/stripit`)
  10. kind: Rule
  11. services:
  12. - name: whoami
  13. port: 80
  14. tls:
  15. store:
  16. name: default

Secret

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: supersecret
  5. data:
  6. tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
  7. tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=

Further

Also see the full example with Let’s Encrypt.