Traefik Kubernetes Setup

guides/traefik/traefik.png

Helm

Add repo

1helm repo add traefik https://helm.traefik.io/traefik

Update repo

1helm repo update

Create our namespace

1kubectl create namespace traefik

Get all namespaces

1kubectl get namespaces

We should see

NAME              STATUS   AGE
default           Active   21h
kube-node-lease   Active   21h
kube-public       Active   21h
kube-system       Active   21h
metallb-system    Active   21h
traefik           Active   12s

Values

 1globalArguments:
 2  - "--global.sendanonymoususage=false"
 3  - "--global.checknewversion=false"
 4
 5additionalArguments:
 6  - "--serversTransport.insecureSkipVerify=true"
 7  - "--log.level=INFO"
 8
 9deployment:
10  enabled: true
11  replicas: 3
12  annotations: {}
13  podAnnotations: {}
14  additionalContainers: []
15  initContainers: []
16
17ports:
18  web:
19    redirectTo: websecure
20  websecure:
21    tls:
22      enabled: true
23      
24ingressRoute:
25  dashboard:
26    enabled: false
27
28providers:
29  kubernetesCRD:
30    enabled: true
31    ingressClass: ingress-class-name
32  kubernetesIngress:
33    enabled: true
34    publishedService:
35      enabled: false
36
37rbac:
38  enabled: true
39
40service:
41  enabled: true
42  type: LoadBalancer
43  annotations: {}
44  labels: {}
45  spec:
46    loadBalancerIP: 10.10.1.60 # this should be an IP in the MetalLB range
47  loadBalancerSourceRanges: []
48  externalIPs: []

Install

1helm install --namespace=traefik traefik traefik/traefik --values=values.yaml

Check the status of the traefik ingress controller service

1kubectl get svc --all-namespaces -o wide

We should see traefik with the specified IP

NAMESPACE        NAME              TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE   SELECTOR
          443/TCP                      16h   <none>
          53/UDP,53/TCP,9153/TCP       16h   k8s-app=kube-dns
          443/TCP                      16h   k8s-app=metrics-server
          443/TCP                      16h   component=controller
traefik          traefik           LoadBalancer   10.43.156.161   192.168.30.80   80:30358/TCP,443:31265/TCP   22s   app.kubernetes.io/instance=traefik,app.kubernetes.io/name=traefik

Ger all pods in traefik namespace

1kubectl get pods --namespace traefik

We should see pods in the traefik namespace

NAME                       READY   STATUS    RESTARTS   AGE
traefik-76474c4d47-l5z74   1/1     Running   0          11m
traefik-76474c4d47-xb282   1/1     Running   0          11m
traefik-76474c4d47-xx5lw   1/1     Running   0          11m

middleware

default-headers.yml

 1apiVersion: traefik.containo.us/v1alpha1
 2kind: Middleware
 3metadata:
 4  name: default-headers
 5  namespace: default
 6spec:
 7  headers:
 8    browserXssFilter: true
 9    contentTypeNosniff: true
10    forceSTSHeader: true
11    stsIncludeSubdomains: true
12    stsPreload: true
13    stsSeconds: 15552000
14    customFrameOptionsValue: SAMEORIGIN
15    customRequestHeaders:
16      X-Forwarded-Proto: https

Apply middleware

1kubectl apply -f default-headers.yaml

Get middleware

1kubectl get middleware

We should see our headers

NAME              AGE
default-headers   25s
dashboard

Install htpassword

1sudo apt-get update
2sudo apt-get install apache2-utils

Generate a credential / password that’s base64 encoded

1htpasswd -nb username password | openssl base64

secret-dashboard.yaml

1apiVersion: v1
2kind: Secret
3metadata:
4  name: traefik-dashboard-auth
5  namespace: traefik
6type: Opaque
7data:
8  users: <FROM HTPASSWORD>

Apply secret

1kubectl apply -f secret-dashboard.yaml

Get secret

1kubectl get secrets --namespace traefik

dashboard-auth-middleware.yaml

1apiVersion: traefik.containo.us/v1alpha1
2kind: Middleware
3metadata:
4  name: traefik-dashboard-basicauth
5  namespace: traefik
6spec:
7  basicAuth:
8    secret: traefik-dashboard-auth

Apply middleware

1kubectl apply -f dashboard-auth-middleware.yaml

ingress.yaml

 1apiVersion: traefik.containo.us/v1alpha1
 2kind: IngressRoute
 3metadata:
 4  name: traefik-dashboard
 5  namespace: traefik
 6  annotations: 
 7    kubernetes.io/ingress.class: ingress-class-name
 8spec:
 9  entryPoints:
10    - websecure
11  routes:
12    - match: Host(`traefik.domain.name`)
13      kind: Rule
14      middlewares:
15        - name: traefik-dashboard-basicauth
16          namespace: traefik
17      services:
18        - name: api@internal
19          kind: TraefikService
20  tls:
21    secretName: secret-tls

Apply dashboard

1kubectl apply -f ingress.yaml

Visit https://traefik.domain.name

Sample Workload

deployment.yaml

 1kind: Deployment
 2apiVersion: apps/v1
 3metadata:
 4  name: nginx-test-deployment
 5  namespace: default
 6  labels:
 7    app: test
 8spec:
 9  replicas: 3
10  progressDeadlineSeconds: 600
11  revisionHistoryLimit: 2
12  strategy:
13    type: Recreate
14  selector:
15    matchLabels:
16      app: test
17  template:
18    metadata:
19      labels:
20        app: test
21    spec:
22      containers:
23      - name: nginx-test
24        image: nginx

service.yaml

 1apiVersion: v1
 2kind: Service
 3metadata:
 4  name: nginx-test-service
 5  namespace: default
 6spec:
 7  selector:
 8    app: test
 9  ports:
10  - name: http
11    targetPort: 80
12    port: 80

ingress.yaml

 1apiVersion: traefik.containo.us/v1alpha1
 2kind: IngressRoute
 3metadata:
 4  name: nginx-test-ingress
 5  namespace: default
 6  annotations: 
 7    kubernetes.io/ingress.class: ingress-class-name
 8spec:
 9  entryPoints:
10    - websecure
11  routes:
12    - match: Host(`test.domain.name`)
13      kind: Rule
14      services:
15        - name: test
16          port: 80
17      middlewares:
18        - name: default-headers
19  tls:
20    secretName: secret-tls
1kubectl apply -f deployment.yaml
2kubectl apply -f service.yaml
3kubectl apply -f ingress.yaml