Traefik as Ingress Controller for K8S

Original author: Dusan Susic
  • Transfer

It's no secret that K8S has a great community and generally good documentation. In it you can easily find the answer to many questions. But like any other documentation, it cannot cover absolutely everything. In this article I will try to provide detailed instructions on how to deploy and configure Traefik for use as an Ingress controller.


image


What is Ingress?


Ingress is an API object that controls external access to services in a cluster, mainly via HTTP / HTTPS. In order for the Ingress resource to work, you need an Ingress controller. If you are using GCE, then the Ingress controller is already deployed to the wizard. However, if you have loaded the cluster yourself, for example from kopsAWS, you need to deploy the Ingress controller yourself. On minikube, this is solved by including the Ingress add-in.


Ingress controllers


The role of the Ingress Controller can be performed by NGINX Ingress Controller, Kong, Octavia Ingress Controller, etc. In this article we will look at a tool like Traefik and see how you can use it as an Ingress Controller for services in a cluster.


What for?


Why use the Ingress controller if you can provide access to each service through NodePortor LoadBalancer? In short, it allows you to get one central point for proxying all traffic. That is, using the Ingress controller, you only need one LoadBalancer for Traefik and nothing else. This bunch will settle all traffic.


Traefik components


Traefik announced support for Kubernetes Ingress in version 1.4. However, the recently released Traefik 1.7 has an option publishedService,that can update the field statusin Ingress, which was not the case in previous versions. Below is a list of components that will be required for work.


Create:


  • namespace
  • service account
  • TLS secret
  • cluster role
  • cluster role binding
  • configmap
  • deployment
  • service for http and https
  • service for Traefik dashboard
  • Ingress

Namespace


Create a namespace:


kubectl create namespacetraefik

Tls secret


(note. Trans. - in the example below, the author for some reason duplicates the same config, the actual config is found in the README file provided by the link below)


First create a certificate:


openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./tls.key -out ./tls.crt -subj "/CN=*.example.com"

Create a TLS certificate:


openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./tls.key -out ./tls.crt -subj "/CN=*.example.com"

Create Secret:


kubectl create secret tls traefik-ui-tls-cert --key ./tls.key --cert ./tls.crt

For convenience, I made a README file with these commands and uploaded it to my GitHub .


ConfigMap


---
apiVersion: v1
kind: ConfigMap
metadata:
 name: traefik-configmap
 namespace: traefik
data:
 traefik.toml: |
   defaultEntryPoints = ["http","https"]
   [entryPoints]
     [entryPoints.http]
     address = ":80"
     [entryPoints.https]
     address = ":443"
       [entryPoints.https.tls]
         [[entryPoints.https.tls.certificates]]
         CertFile = "/ssl/tls.crt"
         KeyFile = "/ssl/tls.key"
     [entryPoints.traefik]
       address = ":8080"
       [entryPoints.traefik.auth.basic]
       users = ["admin:$apr1$zjjGWKW4$W2JIcu4m26WzOzzESDF0W/"]
   [kubernetes]
     [kubernetes.ingressEndpoint]
       publishedService = "traefik/traefik"
   [ping]
   entryPoint = "http"
   [api]
   entryPoint = "traefik"

By default, the EntryPoints are ports 80and 443.


EntryPoint is httplistening :80and has no additional rules.


EntryPoint httpslistens :443and contains a rule for connecting TLS certificates.


EntryPoint traefiklistens :8080and uses basic-authentication. Username - admin, password - admin.


Determining the corresponding endpoint Ingress in Kubernetes is done by setting publishServiceand must consist of a value namespaceand a name servicefor Traefik. In this case it is traefik / traefik.


pingor a health check will use entryPoint http.


apior dashboard / ui will use entryPoint traefik.


Please note that you can define additional entryPoints with indication of the port. This port can proxy traffic to any port, instead of dynamic ports and NodePort.


Clusterraole


Service account for Traefik must have permission to update the field Ingress status. This is an important parameter, and it is not yet presented in the official documentation of Traefik :


---
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

The last 6 lines are very important for correct operation.


Deployment


Deployment is pretty simple and straightforward. Let's take a quick look at the main blocks:


volumes:
 - name: traefik-ui-tls-cert
   secret:
     secretName: traefik-ui-tls-cert
 - name: traefik-configmap
   configMap:
     name: traefik-configmap

Define volumesfor ConfigMap and Secret, which can then be used in volumeMounts.


volumeMounts:
 - mountPath: "/ssl"
   name: "traefik-ui-tls-cert"
 - mountPath: "/config"
   name: "traefik-configmap"

A health check is performed on port 80, as defined in the ConfigMap.


Open the ports for all entryPoints specified in the configuration file:


ports:
 - name: http
   containerPort: 80
 - name: https
   containerPort: 443
 - name: dashboard
   containerPort: 8080

I remind you that some examples and documentation on the Internet are outdated, so do not miss the section argsnecessary for the work of Traefik:


args:
- --logLevel=INFO
- --configfile=/config/traefik.toml

Do not pass additional flags and arguments, such as -api, -ping or -kubernetes, because this will override the settings specified in the config file.


Service


The first of these services defines Loadbalancer for entryPoints httpand https. If you look at the Security Group (Ingress) for LoadBalancer, you will see ports 80 and 443 are open there. K8s will create LoadBalancer and connect to the nodes that Traefik is running on. If you want to create an internal ELB, like me, you need to define annotations:


---
kind: Service
apiVersion: v1
metadata:
 name: traefik
 namespace: traefik
 annotations: {}
   # service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
spec:
 selector:
   k8s-app: traefik-ingress
 ports:
 - protocol: TCP
   port: 80
   name: http
 - protocol: TCP
   port: 443
   name: https
 type: LoadBalancer

Service (for Dashboard)


Now the fun part! Since Dashboard uses basic authentication, I needed it https. To use SSL, we need to redirect traffic to the port :8080on which the Dashboard is running. As you can see, it is very simple. All the magic happens in Ingress.


---
kind: Service
apiVersion: v1
metadata:
 name: traefik-dashboard
 namespace: traefik
spec:
 selector:
   k8s-app: traefik-ingress
 ports:
 - port: 8080
   name: dashboard

Ingress (for Dashboard)


The magic lies in the fact that proxying protected traffic to Dashboard is done through Traefik itself. Traefik in Ingress is managed using Traefik annotations :


---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: traefik-dashboard-ingress
 namespace: traefik
 annotations:
   kubernetes.io/ingress.class: traefik
   traefik.ingress.kubernetes.io/frontend-entry-points: http,https
   traefik.ingress.kubernetes.io/redirect-entry-point: https
   traefik.ingress.kubernetes.io/redirect-permanent: "true"
spec:
 rules:
 - host: traefik-ui.example.com
   http:
     paths:
     - path: /
       backend:
         serviceName: traefik-dashboard
         servicePort: 8080

It took only 4 simple and understandable annotations.


Of course, to ensure full functionality, you need to create a DNS record traefik-ui.example.comthat will point to your ELB.


Would it be great if this (automatic translation is meant to create DNS records)? Not a problem, I will write about the automatic creation of DNS-records in the next article.


Links


Ready deployment.yaml file can be downloaded in my Github repository . If during the setup process you have any difficulties, do not hesitate to ask.


Translation from the translator


Read other articles on our blog:


Stateful backups in Kubernetes


Backup a large number of heterogeneous web-projects


Telegram-bot for Redmine. How to simplify the life of yourself and people


Also popular now: