Helm Charts worden regelmatig geüpdatet waardoor namen en posities van variabelen kunnen veranderen. Hierdoor kunnen wij niet garanderen dat elk artikel altijd volledig up to date is. Mocht je merken dat bepaalde informatie niet meer klopt, dan vernemen we dat graag van je.
Traefik is een populaire open-source reverse proxy en loadbalancer, ontworpen voor microservices en containerized applicaties. Traefik kan automatisch de services ontdekken die in een Kubernetes-cluster draaien en het verkeer naar deze services routeren met behulp van verschillende load balancing-algoritmes.
Traefik opereert als toegangspoort voor andere services binnen je cluster. Met Traefik kun je meerdere applicaties op een Kubernetes-cluster hosten waarvan het verkeer verloopt via Traefik. Traefik kan dan als één enkele loadbalancer functioneren voor al deze applicaties en bovendien Let's Encrypt SSL-certificaten verstrekken.
In deze handleiding laten we zien hoe je Traefik installeert en gebruikt. Hierbij maken we gebruik van een eigen (sub)domeinnaam (optioneel) om Traefik aan te koppelen en beveiligen die met een SSL-certificaat. Om in te loggen op het Traefik-dashboard stellen we een gebruikersnaam- en wachtwoord in.
Voor deze handleiding heb je nodig:
- Kubectl en een succesvolle verbinding met je Kubernetes-cluster, zie onze Kubectl-handleiding.
- De Helm-package manager. Installeer Helm via onze Helm installatiehandleiding als je dat nog niet gedaan hebt.
- Een TransIP API private key. Schakel de API in en genereer een Key Pair zoals beschreven in deze handleiding.
Traefik installeren
Stap 1
Voeg de officiële Traefik repository toe en update je Helm-repositories om die te kunnen gebruiken:
helm repo add traefik https://helm.traefik.io/traefik helm repo update
Stap 2
Traefik kan Let's Encrypt-certificaten genereren voor applicaties die via Traefik communiceren. In deze handleiding gaan we ervan uit dat je dit ook voor jouw use case wilt gebruiken. Hiervoor gebruik je een ACME DNS-challengeprovider. Via onze API ondersteunen wij deze optie. Let wel dat de provider die je kiest deze functionaliteit moet ondersteunen en dat de domeinen die je gebruikt zijn geregistreerd bij die provider in het account dat je voor deze handleiding gebruikt.
Maak een directory aan waarin je je TransIP API key gaat opslaan, bijvoorbeeld:
mkdir transipMaak vervolgens een bestand in de zojuist aangemaakte directory met daarin een private key van jouw account voor de TransIP API, bijvoorbeeld:
cat << EOF > transip/transip.key
-----BEGIN PRIVATE KEY-----
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDKoaYJtbVnJw58
PYGH8WIJ7ZjWd2lke0IbMV+dNGs=
-----END PRIVATE KEY-----
EOFIn dit voorbeeld is maar een klein fragment van een private key opgenomen. Jouw private key zal een stuk langer zijn.
Stap 3
Maak een namespace aan voor Traefik binnen je cluster:
kubectl create ns traefik
Stap 4
Genereer een secret op basis van jouw API private key die door Traefik gebruikt kan worden om met de TransIP API te communiceren. Vervang hier eventueel de volgende gegevens:
- -n traefik: Gebruik de naam van de namespace die je in stap 3 hebt aangemaakt.
- transip/transip.key: Verander naar de directory en bestandsnaam die je in stap 2 hebt aangemaakt.
kubectl create -n traefik secret generic transip-key --from-file transip/transip.key
Stap 5
Over secrets gesproken: als je Traefik configureert om via het publieke internet beschikbaar te zijn, zit daar standaard geen wachtwoord en/of gebruikersnaam op. Hiervoor maken we nog een secret aan met daarin een gebruikersnaam en wachtwoord om in te loggen in het Traefik-dashboard.
Genereer met htpasswd een gebruikersnaam en wachtwoord:
htpasswd -nb <gebruikersnaam> <wachtwoord> >> htpasswd.txtDe inhoud van het htpasswd.txt-bestand ziet er ongeveer als volgt uit:
demogebruiker:$2a$13$2QBmxHS5a1hWU9aeyJ.DPNWRFjXcNRNTjcu56QTLhZS.yGebruik je Windows om deze stappen te doorlopen? Gebruik dan onze htpasswd tool en genereer een htpasswd gebruikersnaam en wachtwoord. Sla de output op in een bestand in de folder waarin je de commando's in deze handleiding doorloopt, bijvoorbeeld c:\Users\Administrator\kubernetes\htpasswd.txt
Genereer vervolgens de secret op basis van de inhoud van het zojuist aangemaakte bestand:
kubectl create secret generic traefik-dashboard-basicauth --from-file=users=htpasswd.txt -n traefik
Stap 6
Voor de installatie van Traefik gebruik je in de volgende stap de officiële Helm Chart. In een aanvullend .yaml-bestand maak je een paar aanpassingen; maak hiervoor een .yaml-bestand aan, bijvoorbeeld:
nano traefik.yamlGeef het bestand de inhoud hieronder, waarbij je een aantal waarden aanpast:
- example@transip.nl: Verander naar jouw e-mailadres
- jouwaccount: Verander jouwaccount naar de naam van jouw TransIP-account.
- /transip/transip.key: Verander (indien nodig) naar de directory en bestandsnaam die je in stap 2 hebt aangemaakt.
- traefik.transip.nl: Verander naar het (sub)domein waar je Traefik aan wil koppelen.
deployment:
initContainers:
- name: volume-permissions
image: busybox:latest
command: ["sh", "-c", "touch /data/acme.json; chmod -v 600 /data/acme.json"]
volumeMounts:
- mountPath: /data
name: data
podSecurityContext:
fsGroup: 65532
fsGroupChangePolicy: "OnRootMismatch"
additionalArguments:
- "--certificatesresolvers.myresolver.acme.email=shagting@transip.nl"
- "--certificatesresolvers.myresolver.acme.dnschallenge.provider=transip"
- "--certificatesresolvers.myresolver.acme.dnschallenge.propagation.delayBeforeChecks=120"
- "--certificatesresolvers.myresolver.acme.storage=/data/acme.json"
- "--providers.kubernetescrd.namespaces="
env:
- name: TRANSIP_ACCOUNT_NAME
value: testtransip
- name: TRANSIP_PRIVATE_KEY_PATH
value: /transip/transip.key
volumes:
- name: transip-key
mountPath: "/transip"
type: secret
persistence:
enabled: true
size: 128Mi
ports:
websecure:
tls:
enabled: true
expose:
default: true
exposedPort: 443
ingressRoute:
dashboard:
enabled: true
entryPoints:
- websecure
matchRule: Host(`traefik.supporttest.nl`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
tls:
certResolver: myresolver
middlewares:
- name: "dashboard-auth"
namespace: "traefik"
extraObjects:
- apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: dashboard-auth
namespace: traefik
spec:
basicAuth:
secret: "traefik-dashboard-basicauth"
podAnnotations:
prometheus.io/port: "8082"
prometheus.io/scrape: "true"
providers:
kubernetesGateway:
enabled: true
kubernetesIngress:
publishedService:
enabled: true
priorityClassName: "system-cluster-critical"
image:
registry: docker.io
repository: traefik
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"Toelichting op code
Voor een volledig overzicht van de beschikbare opties, zie de officiële Helm-chart. In a nutshell komen de verschillende onderdelen op het volgende neer:
- deployment.initcontainers: Traefik is out-of-the-box geconfigureerd om geen rechten te hebben om SSL-certificaten weg te schrijven in het standaard daarvoor bedoelde bestand /data/acme.json. Dit onderdeel zorgt ervoor dat Traefik lees- en schrijfrechten krijgt door met een chmod-commando de rechten aan te passen.
- podsecuritycontext: Zorgt ervoor dat ieder volume de juiste eigenaar heeft (65532)
- additionalArguments: De opgegeven waarden geven aan naar welk mailadres meldingen m.b.t. het genereren van SSL-certificaten worden gestuurd, dat je TransIP's systemen (via onze API) gebruikt om Let's Encrypt-certificaten te genereren, hoe vaak ze vernieuwd worden, waar ze opgeslagen worden, en dat Traefik alle namespaces in de gaten houdt en kan gebruiken.
- env: Informatie met betrekking tot jouw TransIP API-gegevens (uit stap 2 en 4).
- volumes: Hier configureer je aanvullende volumes (een soort van schijf); in dit geval het volume /transip om je API-gegevens in op te slaan.
- persistence: Controleert of je het volume dat gebruikt wordt om de SSL-certificaten in op te slaan (/data) bewaard als je je Traefik-installatie verwijdert. In dit .yaml-bestand is deze optie ingeschakeld.
- ports: De configuratie m.b.t. het gebruik van Traefik via SSL (of het gebruikt kan worden, op welke poort, etc).
- ingressRoute: Een IngressRoute zorgt ervoor dat binnenkomende netwerkverzoeken bij de juiste services terecht komen.
- extraObjects: Voeg aanvullende onderdelen toe aan je Traefik setup. In deze setup voeg je een Middleware toe die ervoor zorgt dat als je in je browser naar het Traefik-dashboard gaat je een vraag om een wachtwoord krijgt zoals vastgelegd in de traefik-dashboard-basicauth secret (die je in stap 5 hebt aangemaakt).
- podAnnotations: aanvullende labels om aan de Traefik-pod te koppelen, in dit geval om het gebruik van Prometheus i.c.m. Traefik mogelijk te maken.
- providers: Schakel a) de optie in om Traefik als Gateway te gebruiken in plaats van de traditionele EoL Nginx Ingress en b) de optie in voor Traefik om Kubernetes Ingress resources te ontdekken. Standaard staat deze optie aan in de officiële Helm Chart. We hebben hem hier toch opgenomen, mocht Traefik op een latere datum besluiten deze optie standaard uit te zetten.
- priorityClassName: Stelt een priority class in voor Traefik. Stel dat Kubernetes om wat voor reden dan ook moet kiezen welke Pods het voorrang geeft bij het aanmaken daarvan, dan krijgt een Pod met priority voorrang.
- image: Welke image gebruikt wordt voor het aanmaken van de Traefik-deployment.
- tolerations: Bepaalde pods mogen niet op een node met een taint worden geplaatst (i.e. gescheduled), tenzij de pod een 'toleration' heeft voor die specifieke taint, zie ons artikel over taints & tolerations.
Stap 7
Installeer de Traefik Helm Chart met het commando hieronder.
helm install -f traefik.yaml traefik traefik/traefik -n traefik
- helm install: Installeert de Helm Chart.
- -f traefik.yaml: Het bestand uit stap 6 waarmee we de installatie aanpassen.
- traefik: De naam van de Helm 'release', te controleren met het commando 'helm list'.
- traefik/traefik: Respectievelijk de naam van de repository en te installeren Helm Chart.
- -n traefik: De namespace waarin de Helm release wordt geïnstalleerd, zie stap 3.
Je krijgt nu een bevestiging te zien die er ongeveer als volgt uitziet:
NAME: traefik
LAST DEPLOYED: Wed Feb 12 09:22:05 2025
NAMESPACE: traefik
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
traefik with docker.io/traefik:v3.3.3 has been deployed successfully on traefik namespace !
🚨 When enabling persistence for certificates, permissions on acme.json can be
lost when Traefik restarts. You can ensure correct permissions with an
initContainer. See https://github.com/traefik/traefik-helm-chart/blob/master/EXAMPLES.md#use-traefik-native-lets-encrypt-integration-without-cert-managerDe waarschuwing kun je negeren: dit issue heb je getackeld in het begin van het traefik.yaml-bestand dat je in de vorige stap hebt aangemaakt.
Traefik is nu succesvol aangemaakt, maar.. hoe kom je nu verder? Dat brengt ons nu eerst bij de Traefik-dashboard, zie de volgende paragraaf.
Het Traefik-dashboard
Traefik komt met een webinterface waarmee je inzage krijgt in de status van je Kubernetes-cluster en het verkeer dat door je cluster verwerkt wordt. Het toont informatie over de routers en services die gebruikt worden om verkeer te verwerken en de gebruikte loadbalancing algoritmes. Het dashboard geeft je ook de mogelijkheid om logs en metrics te bekijken die door Traefik gegenereerd worden. Het dashboard is dus een handige tool voor het monitoren en troubleshooten van Traefik.
Stap 1
Om gebruik te maken van het Traefik-dashboard achterhaal je eerst het externe IP-adres van je Traefik-LoadBalancer (automatisch aangemaakt):
kubectl get svc -n traefikIn de output zie je onder ‘external-IP’ een adres dat lijkt op: 86-105-245-108.haip.transip.net. Noteer de getallen en zet de streepjes om in punten, oftewel: 86.105.245.108.
Stap 2
Wil je Traefik aan een (sub)domein koppelen? Maak dan eerst een A-record aan voor je domeinnaam, zie deze handleiding, bijvoorbeeld met de naam ‘traefik’ en geef die als waarde het IP-adres uit de vorige stap.
Stap 3
Aan het begin van dit artikel hebben we je verteld dat je de TransIP-api gebruikt en daar een key voor nodig hebt. Bij het aanmaken van de API-key heb je een optie gekregen om de key enkel te kunnen gebruiken voor whitelisted IP-adressen. Indien je hiervoor gekozen hebt, voeg dan ook het IP-adres uit stap 1 toe aan je API-whitelist, zie nogmaals onze API-handleiding.
Het kan even duren voor de DNS- en API-wijzigingen zijn opgepikt. Wanneer deze verwerkt zijn, kun je de Traefik-dashboard bekijken in een browser vanaf je subdomein, bijvoorbeeld https://traefik.voorbeeld.nl/dashboard/ of anders rechtstreeks via het IP-adres op https://<ip-adres>/dashboard/. Wanneer om een gebruikersnaam en wachtwoord wordt gevraagd, gebruik je die uit stap 5 van het vorige onderdeel.
Je configuratie aanpassen
Het is wenselijk om het publieke IP-adres van je loadbalancer te behouden wanneer je wijzigingen doorvoert op de configuratie van Traefik. Verwijder daarom bij wijzigingen waar mogelijk niet je gehele Traefik-installatie, maar voer eventuele wijzigingen door in traefik.yaml en update je Helm-installatie met:
helm upgrade -f traefik.yaml traefik traefik/traefik -n traefik
Wel of geen Cert-manager
Traefik kan prima Let's Encrypt-certificaten genereren. Gebruik je voor jouw use-case echter Cert-manager? Dan zijn er een paar aanpassingen nodig in het .yaml-bestand uit stap 6 van de installatie en configuratie van Traefik. Pas traefik.yaml aan zodat het eruitziet als hieronder (verwijder het deployment.initcontainers deel enkel als je voor jouw project /data niet nodig hebt):
podSecurityContext:
fsGroup: 65532
fsGroupChangePolicy: "OnRootMismatch"
persistence:
enabled: true
size: 128Mi
ports:
websecure:
tls:
enabled: true
expose:
default: true
exposedPort: 443
ingressRoute:
dashboard:
enabled: true
entryPoints:
- websecure
matchRule: Host(`traefik.supporttest.nl`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
tls:
secretName: traefik-dashboard-tls
middlewares:
- name: "dashboard-auth"
namespace: "traefik"
extraObjects:
- apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: dashboard-auth
namespace: traefik
spec:
basicAuth:
secret: "traefik-dashboard-basicauth"
podAnnotations:
prometheus.io/port: "8082"
prometheus.io/scrape: "true"
providers:
kubernetesGateway:
enabled: true
kubernetesIngress:
publishedService:
enabled: true
priorityClassName: "system-cluster-critical"
image:
registry: docker.io
repository: traefik
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"Gebruik daarnaast een los .yaml-bestand (of neem de configuratie op in je bestaande .yaml) om het aan te vragen certificaat te definiëren, bijvoorbeeld certificate.yaml:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: demo-cert
namespace: demo-setup
spec:
secretName: demo-setup-tls
issuerRef:
name: letsencrypt-issuer
kind: ClusterIssuer
dnsNames:
- demo.voorbeeld.nlWijzig uiteraard wel de name, namespace, secretName, issuerRef.name en dnsNames naar die voor jouw project.
Pas tot slot de configuratie toe:
helm upgrade -f traefik.yaml traefik traefik/traefik -n traefik
kubectl apply -f certificate.yaml
Voorbeeld van het gebruik van Traefik
Je kunt Traefik nu gebruiken om verkeer via de Gateway API naar je deployments te routeren. Hieronder laten we als voorbeeld zien hoe je een eenvoudige Nginx-applicatie ontsluit via een Traefik Gateway en HTTPRoute, inclusief een HTTP->HTTPS redirect zonder redirect-loops. Let op: neem dit niet één op één over, maar pas o.a. namespaces, hostnames en secret-namen aan voor jouw use case (bijv. nginx.voorbeeld.nl).
Nginx-deployment en service:
In het voorbeeld hieronder configureer je een eenvoudige Nginx-setup die verkeer ontvangt op poort 80.
apiVersion: v1
kind: Namespace
metadata:
name: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:stable-alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: nginx
spec:
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
Certificate (cert-manager):
Cert-manager maakt een TLS Secret aan (bijv. nginx-voorbeeld-nl-tls). Deze Secret koppel je daarna aan de HTTPS-listener in de Gateway via tls.certificateRefs.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: nginx-cert
namespace: nginx
spec:
secretName: nginx-voorbeeld-nl-tls
issuerRef:
name: letsencrypt-issuer
kind: ClusterIssuer
dnsNames:
- nginx.voorbeeld.nl
Gateway:
De Gateway definieert de “ingang” van je cluster voor deze hostname. De HTTPS-listener gebruikt het certificaat uit de Secret die cert-manager aanmaakt. Let op: in veel Traefik Helm installs staan de entryPoints intern op 8000/8443; zorg dat je listener-poorten overeenkomen met jouw Traefik entryPoints.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: nginx-gateway
namespace: nginx
spec:
gatewayClassName: traefik
listeners:
- name: web
protocol: HTTP
port: 8000
hostname: nginx.voorbeeld.nl
allowedRoutes:
namespaces:
from: Same
- name: websecure
protocol: HTTPS
port: 8443
hostname: nginx.voorbeeld.nl
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: nginx-voorbeeld-nl-tls
allowedRoutes:
namespaces:
from: Same
HTTPRoute (redirect HTTP -> HTTPS):
Om HTTP automatisch naar HTTPS te redirecten zonder redirect-loops, gebruik je een aparte HTTPRoute die alleen aan de HTTP-listener hangt (sectionName: web) en een RequestRedirect filter toepast.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: nginx-route-redirect
namespace: nginx
spec:
parentRefs:
- name: nginx-gateway
sectionName: web
hostnames:
- nginx.voorbeeld.nl
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
HTTPRoute (HTTPS naar de service):
Deze route hangt aan de HTTPS-listener (sectionName: websecure) en stuurt verkeer door naar de Nginx-service.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: nginx-route
namespace: nginx
spec:
parentRefs:
- name: nginx-gateway
sectionName: websecure
hostnames:
- nginx.voorbeeld.nl
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: nginx
port: 80Pas de resources toe en controleer de status:
kubectl apply -f nginx-deployment-service.yaml
kubectl apply -f nginx-certificate.yaml
kubectl apply -f nginx-gateway.yaml
kubectl apply -f nginx-httproute-redirect.yaml
kubectl apply -f nginx-httproute.yaml
kubectl get certificate -n nginx
kubectl describe gateway nginx-gateway -n nginx
kubectl describe httproute nginx-route-redirect -n nginx
kubectl describe httproute nginx-route -n nginx
Daarmee zijn we aan het eind gekomen van onze handleiding over de installatie en het gebruik van Traefik in Kubernetes.