Traefik & Kubernetes with Ingress¶
Routing Configuration¶
The Kubernetes Ingress provider watches for incoming ingresses events, such as the example below, and derives the corresponding dynamic configuration from it, which in turn will create the resulting routers, services, handlers, etc.
Configuration Example¶
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: example.com
http:
paths:
- path: /bar
pathType: Exact
backend:
service:
name: whoami
port:
number: 80
- path: /foo
pathType: Exact
backend:
service:
name: whoami
port:
number: 80Annotations¶
Referencing resources in annotations
In an annotation, when referencing a resource defined by another provider, the provider namespace syntax must be used.
On Ingress¶
| Annotation | Description | Value |
|---|---|---|
traefik.ingress.kubernetes.io/router.entrypoints |
See entry points for more information. | ep1,ep2 |
traefik.ingress.kubernetes.io/router.middlewares |
See middlewares overview for more information. | auth@file,default-prefix@kubernetescrd |
traefik.ingress.kubernetes.io/router.priority |
See priority for more information. | "42" |
traefik.ingress.kubernetes.io/router.rulesyntax |
See rule syntax for more information. Deprecated: RuleSyntax option is deprecated and will be removed in the next major version. Please do not use this field and rewrite the router rules to use the v3 syntax. |
"v2" |
traefik.ingress.kubernetes.io/router.pathmatcher |
Overrides the default router rule type used for a path. Only path-related matcher name should be specified: Path, PathPrefix or PathRegexp.Default: PathPrefix |
Path |
traefik.ingress.kubernetes.io/router.tls |
Enables TLS for the router. | "true" |
traefik.ingress.kubernetes.io/router.tls.certresolver |
Specifies the certificate resolver to use for TLS certificates. | myresolver |
traefik.ingress.kubernetes.io/router.tls.domains.n.main |
Defines the main domain for TLS certificate (where n is the domain index). | example.org |
traefik.ingress.kubernetes.io/router.tls.domains.n.sans |
Defines the Subject Alternative Names (SANs) for TLS certificate (where n is the domain index). | test.example.org,dev.example.org |
traefik.ingress.kubernetes.io/router.tls.options |
See TLS options for more information. | foobar@file |
traefik.ingress.kubernetes.io/router.observability.accesslogs |
Controls whether the router produces access logs. See observability for more information. |
true |
traefik.ingress.kubernetes.io/router.observability.metrics |
Controls whether the router produces metrics. See observability for more information. |
true |
traefik.ingress.kubernetes.io/router.observability.tracing |
Controls whether the router produces traces. See observability for more information. |
true |
On Service¶
| Annotation | Description | Value |
|---|---|---|
traefik.ingress.kubernetes.io/service.nativelb |
Controls, when creating the load-balancer, whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. The Kubernetes Service itself does load-balance to the pods. Please note that, by default, Traefik reuses the established connections to the backends for performance purposes. This can prevent the requests load balancing between the replicas from behaving as one would expect when the option is set. Default: false |
"true" |
traefik.ingress.kubernetes.io/service.nodeportlb |
Controls, when creating the load-balancer, whether the LB's children are directly the nodes internal IPs using the nodePort when the service type is NodePort. It allows services to be reachable when Traefik runs externally from the Kubernetes cluster but within the same network of the nodes. Default: false |
"true" |
traefik.ingress.kubernetes.io/service.serversscheme |
Overrides the default scheme. | h2c |
traefik.ingress.kubernetes.io/service.serverstransport |
See ServersTransport for more information. | foobar@file |
traefik.ingress.kubernetes.io/service.passhostheader |
Controls whether to forward the Host header to the backend. | "true" |
traefik.ingress.kubernetes.io/service.sticky.cookie |
Enables sticky sessions using cookies. See sticky sessions for more information. |
"true" |
traefik.ingress.kubernetes.io/service.sticky.cookie.name |
Defines the cookie name for sticky sessions. See sticky sessions for more information. |
foobar |
traefik.ingress.kubernetes.io/service.sticky.cookie.secure |
Sets the Secure flag on the sticky session cookie. See sticky sessions for more information. |
"true" |
traefik.ingress.kubernetes.io/service.sticky.cookie.samesite |
Sets the SameSite attribute on the sticky session cookie. See sticky sessions for more information. |
"none" |
traefik.ingress.kubernetes.io/service.sticky.cookie.domain |
Sets the Domain attribute on the sticky session cookie, defining the host to which the cookie will be sent. See sticky sessions for more information. |
"foo.com" |
traefik.ingress.kubernetes.io/service.sticky.cookie.httponly |
Sets the HttpOnly flag on the sticky session cookie. See sticky sessions for more information. |
"true" |
traefik.ingress.kubernetes.io/service.sticky.cookie.maxage |
Sets the Max-Age attribute (in seconds) on the sticky session cookie. See sticky sessions for more information. |
42 |
traefik.ingress.kubernetes.io/service.sticky.cookie.path |
Sets the Path attribute on the sticky session cookie, defining the path that must exist in the requested URL. See sticky sessions for more information. |
/foobar |
TLS¶
Enabling TLS via HTTP Options on Entrypoint¶
TLS can be enabled through the HTTP options of an Entrypoint:
# Static configuration
--entryPoints.websecure.address=:443
--entryPoints.websecure.http.tls# Static configuration
entryPoints:
websecure:
address: ':443'
http:
tls: {}# Static configuration
[entryPoints.websecure]
address = ":443"
[entryPoints.websecure.http.tls]This way, any Ingress attached to this Entrypoint will have TLS termination by default.
Configuring Kubernetes Ingress Controller with TLS on Entrypoint
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
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: defaultapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
rules:
- host: example.com
http:
paths:
- path: /bar
pathType: Exact
backend:
service:
name: whoami
port:
number: 80
- path: /foo
pathType: Exact
backend:
service:
name: whoami
port:
number: 80apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
---
apiVersion: apps/v1
kind: Deployment
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:v3.6
args:
- --entryPoints.websecure.address=:443
- --entryPoints.websecure.http.tls
- --providers.kubernetesingress
ports:
- name: websecure
containerPort: 443
---
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: TCP
port: 443
name: websecure
targetPort: 443apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
labels:
app: traefiklabs
name: whoami
spec:
replicas: 2
selector:
matchLabels:
app: traefiklabs
task: whoami
template:
metadata:
labels:
app: traefiklabs
task: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- name: http
port: 80
selector:
app: traefiklabs
task: whoamiEnabling TLS via Annotations¶
To enable TLS on the underlying router created from an Ingress, one should configure it through annotations:
traefik.ingress.kubernetes.io/router.tls: "true"
For more options, please refer to the available annotations.
Configuring Kubernetes Ingress Controller with TLS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: example.com
http:
paths:
- path: /bar
pathType: Exact
backend:
service:
name: whoami
port:
number: 80
- path: /foo
pathType: Exact
backend:
service:
name: whoami
port:
number: 80Certificates Management¶
Using a secret
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: foo
namespace: production
spec:
rules:
- host: example.net
http:
paths:
- path: /bar
pathType: Exact
backend:
service:
name: service1
port:
number: 80
# Only selects which certificate(s) should be loaded from the secret, in order to terminate TLS.
# Doesn't enable TLS for that ingress (hence for the underlying router).
# Please see the TLS annotations on ingress made for that purpose.
tls:
- secretName: supersecretapiVersion: v1
kind: Secret
metadata:
name: supersecret
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=TLS certificates can be managed in Secrets objects.
Info
Only TLS certificates provided by users can be stored in Kubernetes Secrets. Let's Encrypt certificates cannot be managed in Kubernetes Secrets yet.
Communication Between Traefik and Pods¶
Routing directly to Kubernetes services
To route directly to the Kubernetes service,
one can use the traefik.ingress.kubernetes.io/service.nativelb annotation on the Kubernetes service.
It controls, when creating the load-balancer,
whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP.
One alternative is to use an ExternalName service to forward requests to the Kubernetes service through DNS.
To do so, one must allow external name services.
Traefik automatically requests endpoint information based on the service provided in the ingress spec. Although Traefik will connect directly to the endpoints (pods), it still checks the service port to see if TLS communication is required.
There are 3 ways to configure Traefik to use HTTPS to communicate with pods:
- If the service port defined in the ingress spec is
443(note that you can still usetargetPortto use a different port on your pod). - If the service port defined in the ingress spec has a name that starts with
https(such ashttps-api,https-webor justhttps). - If the service spec includes the annotation
traefik.ingress.kubernetes.io/service.serversscheme: https.
If either of those configuration options exist, then the backend communication protocol is assumed to be TLS, and will connect via TLS automatically.
Info
Please note that by enabling TLS communication between traefik and your pods,
you will have to have trusted certificates that have the proper trust chain and IP subject name.
If this is not an option, you may need to skip TLS certificate verification.
See the insecureSkipVerify TLSOption setting for more details.
Global Default Backend Ingresses¶
Ingresses can be created that look like the following:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cheese
spec:
defaultBackend:
service:
name: stilton
port:
number: 80This ingress follows the Global Default Backend property of ingresses. This will allow users to create a "default router" that will match all unmatched requests.
Info
Due to Traefik's use of priorities, you may have to set this ingress priority lower than other ingresses in your environment, to avoid this global ingress from satisfying requests that could match other ingresses.
To do this, use the traefik.ingress.kubernetes.io/router.priority annotation (as seen in Annotations on Ingress) on your ingresses accordingly.
Using Traefik OSS in Production?
If you are using Traefik at work, consider adding enterprise-grade API gateway capabilities or commercial support for Traefik OSS.
Adding API Gateway capabilities to Traefik OSS is fast and seamless. There's no rip and replace and all configurations remain intact. See it in action via this short video.