How to Install Traefik as an Ingress Controller in Kubernetes
Hi everyone. Today I want to show how to install traefik as an Ingress Controller in your own on-premise kubernetes cluster.
Traefik can run in Kubernetes in 2 modes:
kubernetesingress- it watches the standard objects withkind: Ingressand builds routes based on themkubernetescrd- to describe routes, you have to createkind: IngressRouteobjects. This approach is more flexible, but if you ever switch to another Ingress Controller, you will have to rewrite your Ingress rules completely. Besides, from the kubernetes point of view, this kind of deployment is not an Ingress Controller, but that doesn't matter much to us. What matters is that we get the same result.
We will deploy both. On top of that, we'll also hook up Let's Encrypt.
Here is the plan: we'll put a label on one of the cluster nodes and use it in a nodeSelector to pick the node where our daemonset will run. This daemonset will run with hostNetwork: true so that we can open ports 80 and 443. The dedicated node won't be directly reachable from the internet; only ports 80 and 443 will be "forwarded" to it.
So, let's label our node:
kubectl label nodes k8s-us1804-a traefik=true
Describe all the resources traefik needs:
# All resources definition must be declared
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressrouteudps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteUDP
plural: ingressrouteudps
singular: ingressrouteudp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsstores.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSStore
plural: tlsstores
singular: tlsstore
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: traefikservices.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TraefikService
plural: traefikservices
singular: traefikservice
scope: Namespaced
Grant permissions to the service account:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- middlewares
- ingressroutes
- traefikservices
- ingressroutetcps
- ingressrouteudps
- tlsoptions
- tlsstores
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
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: default
And start our traefik:
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
---
apiVersion: v1
kind: ConfigMap
metadata:
name: traefikconfig
data:
traefik.yaml: |-
api:
dashboard: true
entryPoints:
web:
address: ":80"
forwardedHeaders:
insecure: true
websecure:
address: ":443"
forwardedHeaders:
insecure: true
providers:
kubernetesingress: {}
kubernetescrd: {}
certificatesResolvers:
letsencrypt:
acme:
email: vitaliy@leschenko.by
storage: /acme/acme.json
caserver: https://acme-v02.api.letsencrypt.org/directory
httpChallenge:
entryPoint: web
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: traefik
labels:
app: traefik
spec:
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
hostNetwork: true
serviceAccountName: traefik-ingress-controller
nodeSelector:
kubernetes.io/os: linux
traefik: "true"
volumes:
- name: acme
hostPath:
path: /acme
- name: config
configMap:
name: traefikconfig
containers:
- name: traefik
image: traefik:v2.2
volumeMounts:
- name: acme
mountPath: /acme
- name: config
mountPath: /traefik
args:
- --configFile=/traefik/traefik.yaml
- --log.level=DEBUG
ports:
- name: web
containerPort: 80
- name: https
containerPort: 443
- name: admin
containerPort: 8080
As a bonus, let's create a rule for traefik's own dashboard:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
spec:
entryPoints:
- websecure
routes:
- match: Host(`traefik.vitaliy.org`)
kind: Rule
services:
- name: api@internal
kind: TraefikService
middlewares:
- name: auth
tls:
certResolver: letsencrypt
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: auth
spec:
basicAuth:
secret: authsecret
---
# A file containing test/test and test2/test2
apiVersion: v1
kind: Secret
metadata:
name: authsecret
namespace: default
data:
users: |2
dGVzdDokYXByMSRINnVza2trVyRJZ1hMUDZld1RyU3VCa1RycUU4d2ovCnRlc3QyOiRhcHIxJGQ5
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
That's it. In a few seconds you can open https://traefik.vitaliy.org.
Only registered users can leave a comment.
Sign in or register to leave a comment.