📜 ⬆️ ⬇️

Traefik as Ingress Controller for K8S

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 manages outbound 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, the Ingress controller is already deployed to the wizard. However, if you have loaded the cluster yourself, for example from kops to AWS, 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 tools 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 NodePort or 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 bundle will resolve all traffic.


Traefik components


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


Create:



Namespace


Create a namespace:


 kubectl create namespace traefik 

Tls secret


(note. Trans. - in the example below, the author for some reason duplicates the same config, the actual config, see the README-file, presented at 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 80 and 443 .


EntryPoint http listens :80 and has no additional rules


EntryPoint https listens to :443 and contains a rule for connecting TLS certificates.


EntryPoint traefik listens :8080 and uses basic-authentication. The username is admin , the password is admin .


Determining the corresponding endpoint Ingress in Kubernetes is done by setting the publishService and must consist of the namespace value and the service name for Traefik. In this case, it is traefik / traefik .


ping or health checks will use entryPoint http .


api or dashboard / ui will use the entryPoint traefik .


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


ClusterRole


The service account for Traefik must have permission to update the Ingress status field. 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 volumes for 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 args section, which is necessary for Traefik to work:


 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 the services defines Loadbalancer for entryPoints http and 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 https . To use SSL, we need to redirect traffic to the port :8080 , on which the Dashboard runs. 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 the 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 be fully operational, you need to create a traefik-ui.example.com DNS record that points to your ELB.


Would it be great if this (automatic translation of the DNS records) was done automatically? 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.


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


')

Source: https://habr.com/ru/post/427655/


All Articles