Traefik is an ingress controller and reverse proxy for cloud environments and Kubernetes. It automatically discovers services, provides SSL/TLS termination, and offers advanced routing capabilities. Using Traefik in Kubernetes allows flexible traffic routing to services within the cluster.
values.yaml
file for customization or keep the default settings. Start the installation by clicking the Install button. Running
status:kubectl get pods -n traefik
By default, the installed Traefik configuration uses four entry points:
web
)websecure
)traefik
)metrics
)To work with Traefik, you need to create a Service
that will route traffic to your application:
apiVersion: v1
kind: Service
metadata:
name: example-service
namespace: default
spec:
selector:
app: example-app
ports:
- protocol: TCP
port: 80
targetPort: 80
This manifest creates the example-service
in the default
namespace, which:
app: example-app
.targetPort: 80
within the pods.Now, you can configure routing through Traefik using IngressRoute
:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: example-service-route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`service.example.com`)
kind: Rule
services:
- name: example-service
port: 80
In this manifest:
entryPoints: web
— specifies that routing occurs via HTTP (8000/tcp).match: Host('service.example.com')
— defines the routing rule based on the domain name.example-service
on port 80.Let's explore an example using Traefik. We will create two Nginx deployments that will work on two different domains — service1.example.com
and service2.example.com
. We will also configure a load balancer and routing through Traefik. Finally, we will configure SSL certificates using Traefik.
First, create the configmap-nginx.yaml
file, which defines HTML pages for each service:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-pages
namespace: default
data:
index1.html: |
<!DOCTYPE html>
<html>
<head><title>Service 1</title></head>
<body><h1>Service 1</h1></body>
</html>
index2.html: |
<!DOCTYPE html>
<html>
<head><title>Service 2</title></head>
<body><h1>Service 2</h1></body>
</html>
The service1-nginx.yaml
manifest describes the deployment for the first service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: service1
namespace: default
labels:
app: service1
spec:
replicas: 2
selector:
matchLabels:
app: service1
template:
metadata:
labels:
app: service1
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: html-volume
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: html-volume
configMap:
name: nginx-pages
items:
- key: index1.html
path: index.html
The service2-nginx.yaml
manifest describes the deployment for the second service:
apiVersion: apps/v1
kind: Deployment
metadata:
name: service2
namespace: default
labels:
app: service2
spec:
replicas: 2
selector:
matchLabels:
app: service2
template:
metadata:
labels:
app: service2
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: html-volume
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: html-volume
configMap:
name: nginx-pages
items:
- key: index2.html
path: index.html
Define the services that Traefik will route traffic to.
The service1-service.yaml
manifest:
apiVersion: v1
kind: Service
metadata:
name: service1
namespace: default
spec:
selector:
app: service1
ports:
- protocol: TCP
port: 80
targetPort: 80
This manifest creates the service1
service, which accepts HTTP requests on port 80 and redirects them to pods labeled app: service1
.
The service2-service.yaml
manifest:
apiVersion: v1
kind: Service
metadata:
name: service2
namespace: default
spec:
selector:
app: service2
ports:
- protocol: TCP
port: 80
targetPort: 80
The service1-ingressroute.yaml
manifest describes the route for the first service:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: service1-route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`service1.example.com`)
kind: Rule
services:
- name: service1
port: 80
This manifest defines an IngressRoute
for service1.example.com
. Let's break down its components:
entryPoints: web
— the route is available via HTTP (port 80, specified in the Traefik load balancer).match: Host('service1.example.com')
— this route is triggered when accessing service1.example.com
.name: service1
— the route forwards traffic to the service1
service.port: 80
— traffic is sent to port 80 inside the service1
Kubernetes service.The service2-ingressroute.yaml
manifest describes the route for the second service:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: service2-route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`service2.example.com`)
kind: Rule
services:
- name: service2
port: 80
Define the load balancer for Traefik in traefik-loadbalancer.yaml
:
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: traefik
spec:
type: LoadBalancer
selector:
app.kubernetes.io/name: traefik
ports:
- name: web
port: 80
targetPort: 8000
- name: websecure
port: 443
targetPort: 8443
Apply all manifests:
kubectl apply -f ./
After creating the load balancer, set its IP address as the A records for the domains. Now, the services are accessible at:
http://service1.example.com
http://service2.example.com
We have configured two services in Kubernetes using Traefik, ensuring routing and load balancing.
Traefik allows obtaining SSL certificates in two ways:
The choice depends on the cluster configuration. If other Ingress controllers are used, cert-manager
is recommended for centralized certificate management. If only Traefik is used in the cluster, you can utilize its built-in certificate retrieval feature.
To enable Let's Encrypt support, modify the Traefik configuration:
image:
registry: docker.io
deployment:
kind: Deployment
updateStrategy:
rollingUpdate:
maxUnavailable: 1
maxSurge: 0
additionalArguments:
- "--certificatesresolvers.le.acme.email=admin@example.com"
- "--certificatesresolvers.le.acme.storage=/data/acme.json"
- "--certificatesresolvers.le.acme.tlschallenge=true"
Changes made:
DaemonSet
. In this mode, it cannot obtain certificates using Traefik. Therefore, the deployment type is changed to Deployment
.additionalArguments
segment. Set your email for Let's Encrypt registration in --certificatesresolvers.le.acme.email
.After updating, ensure the configuration is correctly applied:
kubectl get pod -n traefik
Then, check for ACME parameters:
kubectl get pod <pod_name> -n traefik -o yaml | grep acme
The output should contain lines like:
- --certificatesresolvers.le.acme.email=admin@example.com
- --certificatesresolvers.le.acme.storage=/data/acme.json
- --certificatesresolvers.le.acme.tlschallenge=true
Create a middleware for automatic redirection from HTTP to HTTPS.
redirect-https.yaml:
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: redirect-to-https
namespace: default
spec:
redirectScheme:
scheme: https
permanent: true
Apply the manifest:
kubectl apply -f redirect-https.yaml
Update IngressRoute
to add middleware for redirecting HTTP to HTTPS.
The service1-ingressroute.yaml
manifest:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: service1-route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`service1.example.com`)
kind: Rule
middlewares:
- name: redirect-to-https
services:
- name: service1
port: 80
The service2-ingressroute.yaml
manifest:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: service2-route
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`service2.example.com`)
kind: Rule
middlewares:
- name: redirect-to-https
services:
- name: service2
port: 80
We have added the middleware redirect-to-https
to the routing manifests service1-ingressroute.yaml
, which automatically redirects HTTP requests to HTTPS.
Update the manifests:
kubectl apply -f service1-ingressroute.yaml
kubectl apply -f service2-ingressroute.yaml
Now we need to create separate IngressRoute
resources for HTTPS since standard HTTP routes do not handle TLS. For HTTPS to work, we need to specify a certResolver
, which will use Let's Encrypt to automatically obtain certificates.
In the new IngressRoute
, we specify the entryPoints: websecure
and the tls
parameter, which enables encryption support.
The service1-ingressroute-https.yaml
manifest:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: service1-route-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`service1.example.com`)
kind: Rule
services:
- name: service1
port: 80
tls:
certResolver: le
The service2-ingressroute-https.yaml
manifest:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: service2-route-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`service2.example.com`)
kind: Rule
services:
- name: service2
port: 80
tls:
certResolver: le
Apply the manifests for the new routes:
kubectl apply -f service1-ingressroute-https.yaml
kubectl apply -f service2-ingressroute-https.yaml
Verify certificate issuance with:
kubectl logs -n traefik -l app.kubernetes.io/name=traefik | grep acme
Now, services are accessible via HTTPS:
https://service1.example.com
https://service2.example.com
We have configured automatic SSL certificate issuance with Let's Encrypt in Traefik, ensuring secure connections to services.
Traefik provides a web interface that allows you to monitor the status of routes, services, middleware, and other resources managed by the Traefik instance. The dashboard helps diagnose issues, analyze traffic routing, and manage configuration.
By default, the Traefik dashboard is accessible without authentication, which poses a security risk since any user can view information about running services. To secure access, we will configure basic authentication using middleware
.
Generate a password hash:
mkpasswd -m bcrypt "password"
Encode the credentials in base64:
echo -n 'username:generated_hash' | base64
Define a secret in dashboard-secret.yaml
:
apiVersion: v1
kind: Secret
metadata:
name: dashboard-auth-secret
namespace: traefik
type: Opaque
data:
users: |
логин:base64_encoded_password
Apply the manifest:
kubectl apply -f dashboard-secret.yaml
Define middleware in dashboard-auth.yaml
:
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: dashboard-auth
namespace: traefik
spec:
basicAuth:
secret: dashboard-auth-secret
Apply the manifest:
kubectl apply -f dashboard-auth.yaml
Finally, define IngressRoute
for the dashboard in dashboard-ingress.yaml
:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: traefik
spec:
entryPoints:
- websecure
routes:
- match: Host(`dashboard.example.com`)
kind: Rule
middlewares:
- name: dashboard-auth
services:
- kind: TraefikService
name: api@internal
tls:
certResolver: le
This manifest defines a route for accessing the Traefik dashboard via HTTPS, applying basic authentication.
Parameters description:
entryPoints: websecure
— specifies that the route will only be accessible via HTTPS.match: Host(dashboard.example.com)
— directs requests received for dashboard.example.com
to the dashboard.middlewares
— applies the previously created dashboard-auth
middleware, which enables basic HTTP authentication.services
— directs requests to the built-in api@internal
service, responsible for displaying the dashboard.tls.certResolver: le
— enables automatic SSL certificate issuance via Let's Encrypt.Apply the manifest:
kubectl apply -f dashboard-ingress.yaml
Now, visit https://dashboard.example.com
. After authentication, you will see the Traefik dashboard.