Traefik is a simple and eficient load balancer that can be used at any environment, but if is used with docker or kubernetes can use the service discovery funcionality to allow you the deploy your services and it automaticaly discover all of your replicas and where are running
Used with kubernetes, acts as a ingress controller ( version 1.7 ), so you can use the standard ingress manifest to deploy your services
- Service discovery
- Path routing
- Letsencrypt integration
At the last post k3s introduction I told that I was not going to install traefik because is more dificult to make changes on it, so now we are going to learn how to install and use it.
At this point I indicate that to facilitate the dns resolution of the differents deployments we are going to use the nip.io domain, to allow us to call every deployment with dns its name and for that the ingress manifest must have a domain name.
First we are going to install traefik 1.7 at our kubernetes cluster. We can do that with 2 approaches
- As a Deployment so you can choose how many replicas are running at the cluster.
- As a DaemonSet so one replica of traefik is running at every node of your cluster.
If you have a large cluster, with high number of requests, you must use DaemonSet because traefik is going to suppport all the requests of your applications, but if you have a small cluster, is possible that you prefer to use Deployment with 1 or 2 replicas. In any case the installation process is the same.
# Create clusterRole
kubectl apply -f https://vmalaga.no-ip.org/examples/traefik/traefik-rbac.yaml
# Install traefik
kubectl apply -f https://vmalaga.no-ip.org/examples/traefik/traefik-ds.yaml
The main diference of my DaemonSet with the one provided by traefik is that with are going to use the NET_BIND_SERVICE capability that permit us to bind at 80 and 443 ports, and use the https entrypoint.
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik:v1.7
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
hostPort: 80
- name: https
containerPort: 443
hostPort: 443
- name: admin
containerPort: 8080
hostPort: 8080
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
args:
- --api
- --kubernetes
- --logLevel=INFO
- --defaultentrypoints=http,https
- --entrypoints=Name:https Address::443 TLS
- --entrypoints=Name:http Address::80
- --insecureSkipVerify=true
Next we need a SSL certificate to use the https entrypoint, so we are going to use cert-manager to generate a certificate, change 192.168.1.222 with the ip of your server
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: traefik-cert
namespace: kube-system
spec:
secretName: traefik-cert-tls
issuerRef:
name: ca-issuer
kind: ClusterIssuer
commonName: traefik.192.168.1.222.nip.io
organization:
- Tutorial CA
dnsNames:
- traefik.192.168.1.222.nip.io
kubectl apply -f https://vmalaga.no-ip.org/examples/traefik/traefik-cert.yaml
Now we have a secret with the ca.crt, tls.crt and tls.key
kubectl -n kube-system describe secrets traefik-cert-tls
Name: traefik-cert-tls
Namespace: kube-system
Labels: <none>
Annotations: cert-manager.io/alt-names: traefik.192.168.1.222.nip.io
cert-manager.io/certificate-name: traefik-cert
cert-manager.io/common-name: traefik.192.168.1.222.nip.io
cert-manager.io/ip-sans:
cert-manager.io/issuer-group:
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: ca-issuer
cert-manager.io/uri-sans:
Type: kubernetes.io/tls
Data
====
ca.crt: 1688 bytes
tls.crt: 1489 bytes
tls.key: 1679 bytes
Now we need to expose traefik port as NodePort, the Spec externalTrafficPolicy: Local allow as to provide the x-forwarder headers at our backends
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
namespace: kube-system
spec:
externalTrafficPolicy: Local
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
targetPort: 80
name: web
- protocol: TCP
port: 443
targetPort: 443
name: secure
- protocol: TCP
port: 8080
targetPort: 8080
name: admin
type: NodePort
And last, the ingress with the important annotations:
- kubernetes.io/ingress.class: “traefik”
- traefik.ingress.kubernetes.io/ssl-redirect: “true”
- tls.secretName: traefik-cert-tls - the secret generated with the certificate request.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-dashboard-ingress
namespace: kube-system
annotations:
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: traefik.192.168.1.222.nip.io
http:
paths:
- path: /
backend:
serviceName: traefik-ingress-service
servicePort: 8080
tls:
- secretName: traefik-cert-tls
kubectl apply -f https://vmalaga.no-ip.org/examples/traefik/traefik-service-ingress.yaml
kubectl -n kube-system get service,ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kube-dns ClusterIP 10.43.0.10 <none> 53/UDP,53/TCP,9153/TCP 36d
service/metrics-server ClusterIP 10.43.141.121 <none> 443/TCP 36d
service/traefik-ingress-service NodePort 10.43.197.168 <none> 80:32667/TCP,443:32691/TCP,8080:31330/TCP 36d
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.extensions/traefik-dashboard-ingress <none> traefik.192.168.1.222.nip.io 80, 443 36d
If everything went well, you should be able to see the Trafik admin interface at https://traefik.192.168.1.222.nip.io/dashboard/