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