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: ingressrouteudps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteUDP
plural: ingressrouteudps
singular: ingressrouteudp
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: tlsstores.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSStore
plural: tlsstores
singular: tlsstore
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
- ingressrouteudps
- tlsoptions
- tlsstores
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: apps/v1
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.2
args:
- --log.level=DEBUG
- --api
- --api.insecure
- --entrypoints.web.address=:80
- --entrypoints.tcpep.address=:8000
- --entrypoints.udpep.address=:9000/udp
- --providers.kubernetescrd
ports:
- name: web
containerPort: 80
- name: admin
containerPort: 8080
- name: tcpep
containerPort: 8000
- name: udpep
containerPort: 9000
---
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
- protocol: TCP
port: 8000
name: tcpep
targetPort: 8000
---
apiVersion: v1
kind: Service
metadata:
name: traefikudp
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: UDP
port: 9000
name: udpep
targetPort: 9000
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
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: ingressroute.tcp
namespace: default
spec:
entryPoints:
- tcpep
routes:
- match: HostSNI(`bar`)
kind: Rule
services:
- name: whoamitcp
port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteUDP
metadata:
name: ingressroute.udp
namespace: default
spec:
entryPoints:
- fooudp
routes:
- kind: Rule
services:
- name: whoamiudp
port: 8080
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoami
namespace: default
labels:
app: myapp
name: whoami
spec:
replicas: 2
selector:
matchLabels:
app: myapp
task: whoami
template:
metadata:
labels:
app: myapp
task: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: myapp
task: whoami
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoamitcp
namespace: default
labels:
app: myapp
name: whoamitcp
spec:
replicas: 2
selector:
matchLabels:
app: myapp
task: whoamitcp
template:
metadata:
labels:
app: myapp
task: whoamitcp
spec:
containers:
- name: whoamitcp
image: traefik/whoamitcp
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: whoamitcp
namespace: default
spec:
ports:
- protocol: TCP
port: 8080
selector:
app: myapp
task: whoamitcp
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoamiudp
namespace: default
labels:
app: myapp
name: whoamiudp
spec:
replicas: 2
selector:
matchLabels:
app: myapp
task: whoamiudp
template:
metadata:
labels:
app: myapp
task: whoamiudp
spec:
containers:
- name: whoamiudp
image: traefik/whoamiudp
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: whoamiudp
namespace: default
spec:
ports:
- port: 8080
selector:
app: myapp
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:
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 |
IngressRouteUDP | UDP Routing | UDP router |
TLSOptions | Allows to configure some parameters of the TLS connection | TLSOptions |
TLSStores | Allows to configure the default TLS store | TLSStores |
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.example.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: example.net # [16]
sans: # [17]
- a.example.net
- b.example.net
Ref | Attribute | Purpose |
---|---|---|
[1] | entryPoints |
List of entry points names |
[2] | routes |
List of routes |
[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 (See below for ExternalName Service setup) |
[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.example.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: example.net
sans:
- a.example.net
- b.example.net
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.
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
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: external-svc
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: default
spec:
externalName: external.domain
type: ExternalName
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: external-svc
---
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: default
spec:
externalName: external.domain
type: ExternalName
ports:
- port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: external-svc
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: default
spec:
externalName: external.domain
type: ExternalName
ports:
- 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
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(`example.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. 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:
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(`example.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: myapp
task: app1
---
apiVersion: v1
kind: Service
metadata:
name: svc2
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: myapp
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(`example.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: myapp
task: app1
---
apiVersion: v1
kind: Service
metadata:
name: svc2
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: myapp
task: app2
---
apiVersion: v1
kind: Service
metadata:
name: svc3
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: myapp
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(`example.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: myapp
task: app1
---
apiVersion: v1
kind: Service
metadata:
name: svc2
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: myapp
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
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`example.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: whoami1
kind: Service
port: 80
weight: 1
sticky:
cookie:
name: lvl2
- name: whoami2
kind: Service
weight: 1
port: 80
sticky:
cookie:
name: lvl2
sticky:
cookie:
name: lvl1
apiVersion: v1
kind: Service
metadata:
name: whoami1
spec:
ports:
- protocol: TCP
name: web
port: 80
selector:
app: whoami1
---
apiVersion: v1
kind: Service
metadata:
name: whoami2
spec:
ports:
- protocol: TCP
name: web
port: 80
selector:
app: whoami2
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: default
name: whoami1
labels:
app: whoami1
spec:
replicas: 2
selector:
matchLabels:
app: whoami1
template:
metadata:
labels:
app: whoami1
spec:
containers:
- name: whoami1
image: traefik/whoami
ports:
- name: web
containerPort: 80
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: default
name: whoami2
labels:
app: whoami2
spec:
replicas: 2
selector:
matchLabels:
app: whoami2
template:
metadata:
labels:
app: whoami2
spec:
containers:
- name: whoami2
image: traefik/whoami
ports:
- name: web
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:
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
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: example.net # [16]
sans: # [17]
- a.example.net
- b.example.net
passthrough: false # [18]
Ref | Attribute | Purpose |
---|---|---|
[1] | entryPoints |
List of entrypoints names |
[2] | routes |
List of routes |
[3] | routes[n].match |
Defines the rule corresponding to an underlying router |
[4] | routes[n].services |
List of Kubernetes service definitions (See below for ExternalName Service setup) |
[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: example.net
sans:
- a.example.net
- b.example.net
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=
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
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: HostSNI(`*`)
kind: Rule
services:
- name: external-svc
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: default
spec:
externalName: external.domain
type: ExternalName
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: HostSNI(`*`)
kind: Rule
services:
- name: external-svc
---
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: default
spec:
externalName: external.domain
type: ExternalName
ports:
- port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: HostSNI(`*`)
kind: Rule
services:
- name: external-svc
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: default
spec:
externalName: external.domain
type: ExternalName
ports:
- 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
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteUDP
metadata:
name: ingressrouteudpfoo
spec:
entryPoints: # [1]
- fooudp
routes: # [2]
- services: # [3]
- name: foo # [4]
port: 8080 # [5]
weight: 10 # [6]
Ref | Attribute | Purpose |
---|---|---|
[1] | entryPoints |
List of entrypoints names |
[2] | routes |
List of routes |
[3] | routes[n].services |
List of Kubernetes service definitions |
[4] | 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 |
Declaring an IngressRouteUDP
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteUDP
metadata:
name: ingressrouteudpfoo
spec:
entryPoints:
- fooudp
routes:
- services:
- name: foo
port: 8080
weight: 10
- name: bar
port: 8081
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
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(`example.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.
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
apiVersion: traefik.containo.us/v1alpha1
kind: TLSStore
metadata:
name: default
namespace: default
spec:
defaultCertificate:
secretName: mySecret # [1]
Ref | Attribute | Purpose |
---|---|---|
[1] | secretName |
The name of the referenced Kubernetes Secret that holds the default certificate for the store. |
Declaring and referencing a TLSStore
apiVersion: traefik.containo.us/v1alpha1
kind: TLSStore
metadata:
name: default
namespace: default
spec:
defaultCertificate:
secretName: supersecret
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
spec:
entryPoints:
- web
routes:
- match: Host(`example.com`) && PathPrefix(`/stripit`)
kind: Rule
services:
- name: whoami
port: 80
tls:
store:
name: default
apiVersion: v1
kind: Secret
metadata:
name: supersecret
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
Further¶
Also see the full example with Let's Encrypt.