Traefik & Kubernetes¶
The Kubernetes Ingress Controller, The Custom Resource Way.
Configuration Examples¶
Configuring KubernetesCRD and Deploying/Exposing Services
# All resources definition must be declared
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: traefikservices.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TraefikService
plural: traefikservices
singular: traefikservice
scope: Namespaced
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- middlewares
- ingressroutes
- traefikservices
- ingressroutetcps
- tlsoptions
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: default
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.1
args:
- --log.level=DEBUG
- --api
- --api.insecure
- --entrypoints.web.address=:80
- --providers.kubernetescrd
ports:
- name: web
containerPort: 80
- name: admin
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: TCP
port: 80
name: web
targetPort: 80
- protocol: TCP
port: 8080
name: admin
targetPort: 8080
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: myingressroute
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`foo`) && PathPrefix(`/bar`)
kind: Rule
services:
- name: whoami
port: 80
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: whoami
namespace: default
labels:
app: containous
name: whoami
spec:
replicas: 2
selector:
matchLabels:
app: containous
task: whoami
template:
metadata:
labels:
app: containous
task: whoami
spec:
containers:
- name: containouswhoami
image: containous/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: containous
task: whoami
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:
Kind | Purpose | Concept Behind |
---|---|---|
IngressRoute | HTTP Routing | HTTP router |
Middleware | Tweaks the HTTP requests before they are sent to your service | HTTP Middlewares |
TraefikService | Abstraction for HTTP loadbalancing/mirroring | HTTP service |
IngressRouteTCP | TCP Routing | TCP router |
TLSOptions | Allows to configure some parameters of the TLS connection | TLSOptions |
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
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: foo
namespace: bar
spec:
entryPoints: # [1]
- foo
routes: # [2]
- kind: Rule
match: Host(`test.domain.com`) # [3]
priority: 10 # [4]
middlewares: # [5]
- name: middleware1 # [6]
namespace: default # [7]
services: # [8]
- kind: Service
name: foo
namespace: default
passHostHeader: true
port: 80
responseForwarding:
flushInterval: 1ms
scheme: https
sticky:
cookie:
httpOnly: true
name: cookie
secure: true
sameSite: none
strategy: RoundRobin
weight: 10
tls: # [9]
secretName: supersecret # [10]
options: # [11]
name: opt # [12]
namespace: default # [13]
certResolver: foo # [14]
domains: # [15]
- main: foo.com # [16]
sans: # [17]
- a.foo.com
- b.foo.com
Ref | Attribute | Purpose |
---|---|---|
[1] | entryPoints |
List of entry points name |
[2] | routes |
List of route |
[3] | routes[n].match |
Defines the rule corresponding to an underlying router. |
[4] | routes[n].priority |
Disambiguate rules of the same length, for route matching |
[5] | routes[n].middlewares |
List of reference to Middleware |
[6] | middlewares[n].name |
Defines the Middleware name |
[7] | middlewares[n].namespace |
Defines the Middleware namespace |
[8] | routes[n].services |
List of any combination of TraefikService and reference to a Kubernetes service |
[9] | tls |
Defines TLS certificate configuration |
[10] | tls.secretName |
Defines the secret name used to store the certificate (in the IngressRoute namespace) |
[11] | tls.options |
Defines the reference to a TLSOption |
[12] | options.name |
Defines the TLSOption name |
[13] | options.namespace |
Defines the TLSOption namespace |
[14] | tls.certResolver |
Defines the reference to a CertResolver |
[15] | tls.domains |
List of domains |
[16] | domains[n].main |
Defines the main domain name |
[17] | domains[n].sans |
List of SANs (alternative domains) |
Declaring an IngressRoute
# All resources definition must be declared
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: testName
namespace: default
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`test.domain.com`)
middlewares:
- name: middleware1
namespace: default
priority: 10
services:
- kind: Service
name: foo
namespace: default
passHostHeader: true
port: 80
responseForwarding:
flushInterval: 1ms
scheme: https
sticky:
cookie:
httpOnly: true
name: cookie
secure: true
strategy: RoundRobin
weight: 10
tls:
certResolver: foo
domains:
- main: foo.com
sans:
- a.foo.com
- b.foo.com
options:
name: opt
namespace: default
secretName: supersecret
# All resources definition must be declared
# Prefixing with /foo
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: middleware1
namespace: default
spec:
addPrefix:
prefix: /foo
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: opt
namespace: default
spec:
minVersion: VersionTLS12
apiVersion: v1
kind: Secret
metadata:
name: supersecret
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
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.
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
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: stripprefix
namespace: foo
spec:
stripPrefix:
prefixes:
- /stripit
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
spec:
entryPoints:
- web
routes:
- match: Host(`bar.com`) && PathPrefix(`/stripit`)
kind: Rule
services:
- name: whoami
port: 80
middlewares:
- name: stripprefix
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.
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
/IngressRouteTCP
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:
Service
(default value): to reference a Kubernetes ServiceTraefikService
: to reference another Traefik Service
TraefikService
object allows to use any (valid) combinations of:
- servers load balancing.
- services Weighted Round Robin load balancing.
- services mirroring.
Server Load Balancing¶
More information in the dedicated server load balancing section.
Declaring and Using Server Load Balancing
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`bar.com`) && PathPrefix(`/foo`)
kind: Rule
services:
- name: svc1
namespace: default
- name: svc2
namespace: default
apiVersion: v1
kind: Service
metadata:
name: svc1
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: containous
task: app1
---
apiVersion: v1
kind: Service
metadata:
name: svc2
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: containous
task: app2
Weighted Round Robin¶
More information in the dedicated Weighted Round Robin service load balancing section.
Declaring and Using Weighted Round Robin
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`bar.com`) && PathPrefix(`/foo`)
kind: Rule
services:
- name: wrr1
namespace: default
kind: TraefikService
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
name: wrr1
namespace: default
spec:
weighted:
services:
- name: svc1
port: 80
weight: 1
- name: wrr2
kind: TraefikService
weight: 1
- name: mirror1
kind: TraefikService
weight: 1
---
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
name: wrr2
namespace: default
spec:
weighted:
services:
- name: svc2
port: 80
weight: 1
- name: svc3
port: 80
weight: 1
apiVersion: v1
kind: Service
metadata:
name: svc1
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: containous
task: app1
---
apiVersion: v1
kind: Service
metadata:
name: svc2
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: containous
task: app2
---
apiVersion: v1
kind: Service
metadata:
name: svc3
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: containous
task: app3
Mirroring¶
More information in the dedicated mirroring service section.
Declaring and Using Mirroring
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`bar.com`) && PathPrefix(`/foo`)
kind: Rule
services:
- name: mirror1
namespace: default
kind: TraefikService
# Mirroring from a k8s Service
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
name: mirror1
namespace: default
spec:
mirroring:
name: svc1
port: 80
mirrors:
- name: svc2
port: 80
percent: 20
- name: svc3
kind: TraefikService
percent: 20
# Mirroring from a Traefik Service
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
name: mirror1
namespace: default
spec:
mirroring:
name: wrr1
kind: TraefikService
mirrors:
- name: svc2
port: 80
percent: 20
- name: svc3
kind: TraefikService
percent: 20
apiVersion: v1
kind: Service
metadata:
name: svc1
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: containous
task: app1
---
apiVersion: v1
kind: Service
metadata:
name: svc2
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: containous
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
).
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
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: ingressroutetcpfoo
spec:
entryPoints: # [1]
- footcp
routes: # [2]
- match: HostSNI(`*`) # [3]
services: # [4]
- name: foo # [5]
port: 8080 # [6]
weight: 10 # [7]
TerminationDelay: 400 # [8]
tls: # [9]
secretName: supersecret # [10]
options: # [11]
name: opt # [12]
namespace: default # [13]
certResolver: foo # [14]
domains: # [15]
- main: foo.com # [16]
sans: # [17]
- a.foo.com
- b.foo.com
passthrough: false # [18]
Ref | Attribute | Purpose |
---|---|---|
[1] | entryPoints |
List of entrypoints name |
[2] | routes |
List of route |
[3] | routes[n].match |
Defines the rule corresponding to an underlying router. |
[4] | routes[n].services |
List of any combination of TraefikService and reference to a Kubernetes service |
[5] | services[n].name |
Defines the name of a Kubernetes service |
[6] | services[n].port |
Defines the port of a Kubernetes service |
[7] | services[n].weight |
Defines the weight to apply to the server load balancing |
[8] | services[n].TerminationDelay |
corresponds 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] | tls |
Defines TLS certificate configuration |
[10] | tls.secretName |
Defines the secret name used to store the certificate (in the IngressRoute namespace) |
[11] | tls.options |
Defines the reference to a TLSOption |
[12] | options.name |
Defines the TLSOption name |
[13] | options.namespace |
Defines the TLSOption namespace |
[14] | tls.certResolver |
Defines the reference to a CertResolver |
[15] | tls.domains |
List of domains |
[16] | domains[n].main |
Defines the main domain name |
[17] | domains[n].sans |
List of SANs (alternative domains) |
[18] | tls.passthrough |
If true , delegates the TLS termination to the backend |
Declaring an IngressRouteTCP
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: ingressroutetcpfoo
spec:
entryPoints:
- footcp
routes:
# Match is the rule corresponding to an underlying router.
- match: HostSNI(`*`)
services:
- name: foo
port: 8080
TerminationDelay: 400
weight: 10
- name: bar
port: 8081
TerminationDelay: 500
weight: 10
tls:
certResolver: foo
domains:
- main: foo.com
sans:
- a.foo.com
- b.foo.com
options:
name: opt
namespace: default
secretName: supersecret
passthrough: false
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: opt
namespace: default
spec:
minVersion: VersionTLS12
apiVersion: v1
kind: Secret
metadata:
name: supersecret
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
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
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: mytlsoption
namespace: default
spec:
minVersion: VersionTLS12 # [1]
maxVersion: VersionTLS13 # [1]
curvePreferences: # [3]
- CurveP521
- CurveP384
cipherSuites: # [4]
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_RSA_WITH_AES_256_GCM_SHA384
clientAuth: # [5]
secretNames: # [6]
- secretCA1
- secretCA2
clientAuthType: VerifyClientCertIfGiven # [7]
sniStrict: true # [8]
Ref | Attribute | Purpose |
---|---|---|
[1] | minVersion |
Defines the minimum TLS version that is acceptable |
[2] | maxVersion |
Defines the maximum TLS version that is acceptable |
[3] | cipherSuites |
list of supported cipher suites for TLS versions up to TLS 1.2 |
[4] | curvePreferences |
List of the elliptic curves references that will be used in an ECDHE handshake, in preference order |
[5] | clientAuth |
determines the server's policy for TLS Client Authentication |
[6] | clientAuth.secretNames |
list of names of the referenced Kubernetes Secrets (in TLSOption namespace) |
[7] | clientAuth.clientAuthType |
defines the client authentication type to apply. The available values are: NoClientCert , RequestClientCert , VerifyClientCertIfGiven and RequireAndVerifyClientCert |
[8] | sniStrict |
if true , Traefik won't allow connections from clients connections that do not specify a server_name extension |
Declaring and referencing a TLSOption
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: mytlsoption
namespace: default
spec:
minVersion: VersionTLS12
sniStrict: true
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_RSA_WITH_AES_256_GCM_SHA384
clientAuth:
secretNames:
- secretCA1
- secretCA2
clientAuthType: VerifyClientCertIfGiven
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
spec:
entryPoints:
- web
routes:
- match: Host(`bar.com`) && PathPrefix(`/stripit`)
kind: Rule
services:
- name: whoami
port: 80
tls:
options:
name: mytlsoption
namespace: default
apiVersion: v1
kind: Secret
metadata:
name: secretCA1
namespace: default
data:
tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
---
apiVersion: v1
kind: Secret
metadata:
name: secretCA2
namespace: default
data:
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.
Further¶
Also see the full example with Let's Encrypt.