Kubernetes Ingress (Traefik)

by Anish

Posted on Wednesday January 23, 2019



Kubernetes is the great way to manage docker service in the orchestration way, the service which are created need to be exposed to external clients, which can be done in many ways, This tutorial explains how to use Traefik as an Ingress controller for a Kubernetes cluster

Exposing services to external clients

In kubernetes these are the defined way to make service accessible externally we better known as

  • Node port : Exposes the service on each Node's IP at a static port (the NodePort)
  • Loadbalancer; Exposes the service externally using a cloud provider's load balancer. NodePort and ClusterIP services, to which the external load balancer will route, are automatically created.
  • Ingress Resource : This operates on the at the application layer7, in TCP/IP stack, the HTTP level and offer more feature than layer4 service.

This tutorial is dedicated to use Ingress Resource using the Traefik Kubernetes Ingress Controller

if you have not setup the traefik yet in k8 cluster then, Click here to Setup Traefik in k8 cluster

About Traefik

Traefik is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. Traefik integrates with your existing infrastructure components and configures itself automatically and dynamically. Pointing Traefik at your orchestrator should be the only configuration step you need.

enter image description here

Traefik Ingresses operate at the application layer of the network stack (HTTP) and can provide features such as cookie-based session affinity and the like, which services can't.

The Example Application

We are going here to setup three sample nginx cheese web application, the docker images are located here .

  1. Docker image: errm/cheese:wensleydale
  2. Docker image: errm/cheese:cheddar
  3. Docker image: errm/cheese:stilton

enter image description here

What is Name based routing ?

The Name-Based Routing performs routing by name and support routing HTTP traffic to multiple host names at the same IP address but different domain names , lets start by launching the pods for the cheese websites.

Deployment of Cheese Web Application

[email protected]:# kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-deployments.yaml
deployment.extensions/stilton created
deployment.extensions/cheddar created
deployment.extensions/wensleydale created

To provide some explanations about the file content:

  • We define a deployment (kind: Deployment)
  • The name of the object is "stilton" (name: stilton)
  • We want one replica (replicas: 2)
  • It will deploy pods that have the label app:cheese (selector: matchLabels: app:cheese)
  • Then we define the pods (template: ...)
  • The Pods will have the cheese label (metadata:labels:app:cheese)
  • The Pods will host a container using the image tag errm/cheese:stilton (image: errm/cheese:stilton)
  • The same deployment is repeated for cheddar and wensleydale

Make sure all the deployment pods are up and running

[email protected]:/home/ansible# kubectl get pods
cheddar-6c895c7cc7-2qztp 1/1 Running 0  7m
cheddar-6c895c7cc7-mzq9v 1/1 Running 0  7m
stilton-7989d7c86f-62wrt 1/1 Running 0  7m
stilton-7989d7c86f-fjttz 1/1 Running 0  7m
wensleydale-58784fc6f7-f8szd 1/1 Running 0  7m
wensleydale-58784fc6f7-prb8z 1/1 Running 0  7m

Service Cheese Web Application

Next we need to setup a Service for each of the cheese pods.

[email protected]:# kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-services.yaml
service/stilton created
service/cheddar created
service/wensleydale created

All the

[email protected]:/home/ansible# kubectl get svc
cheddar ClusterIP <none>  80/TCP  30s
kubernetes  ClusterIP  <none>  443/TCP 1h
stilton ClusterIP  <none>  80/TCP  30s
wensleydale ClusterIP <none>  80/TCP  30s

At this point, we have deployment and Service ready in the K8 cluster, and we're about to define the ingress rules so that the world can eat the required service.

apiVersion: extensions/v1beta1
kind: Ingress
  name: cheese
    kubernetes.io/ingress.class: traefik
  - host: stilton.minikube
      - path: /
          serviceName: stilton
          servicePort: http
  - host: cheddar.minikube
      - path: /
          serviceName: cheddar
          servicePort: http
  - host: wensleydale.minikube
      - path: /
          serviceName: wensleydale
          servicePort: http

To provide some explanations about the file content:

  • We define a Ingress (kind: Ingress)
  • The name of the object is "cheese" (name: cheese)
  • Then we define the rules (rules: ...)
  • For each service there is hostname defined for example the hostname stilton.minikube is mapped to stilton service.
  • The rules are repeated for each service.
  • Let's apply this rule in k8 cluster
[email protected]:/home/ansible# kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-ingress.yaml
ingress.extensions/cheese created

Verify the Ingress, all the hosts can be accessed with the ingress port 80

[email protected]:/home/ansible# kubectl get ingress
cheese  stilton.minikube,cheddar.minikube,wensleydale.minikube 80  31s

Now visit the Traefik dashboard and you should see a frontend for each host. Along with a backend listing for each service with a server set up for each pod.

enter image description here

Open the webbrowser and start eating your faviourite cheese

What is PATH based routing

Path based routing differ from Name based routing in a sense, we don't have multiple domains names, all the URI is distinguished and routed from the PATH prefix under a single domain, for example the above cheese application can be access through the single URI.

enter image description here

Let's create the PATH base routing for the cheese application

[email protected]:/home/ansible# kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheeses-ingress.yaml
ingress.extensions/cheeses created

View the Ingress, as you can notices the newly created ingress cheeses can be accessed through the hostname cheeses.minikube

[email protected]:/home/ansible# kubectl get ingress

cheese  stilton.minikube,cheddar.minikube,wensleydale.minikube 80  13m
cheeses cheeses.minikube 80  1m

You should now be able to visit the websites in your browser.

Final Note

  • The above traefik installation is not secure, and shouldn't be used for production, for production setting refer the helm stable/trafeik charts, for example the below chart value will set traefik in SSL mode, and set the BASIC AUTH enabled
helm install stable/traefik --name traefik --set dashboard.enabled=true,dashboard.domain=dashboard.traefik,rbac.enabled=true,dashboard.auth.basic.traefik='$apr1$vUmd7ddA$CoklUZpHBbRzvnZUz6eFY.',ssl.enabled=true,ssl.enforced=true --namespace kube-system
  • It is advisable to install the traefik in the kube-system namespace
  • Always measure your resource needs, and adjust requests and limits accordingly.

Thanks Happy traefiking, do poke me for any problems

Video Demo

Thanku for reading !!! Give a Share for Support

Asking for donation sound bad to me, so i'm raising fund from The Modern Cryptography CookBook for Just $9. Leanpub books Discount coupon first 100 reader. No hurry read the sample chapters here then decide.

Alternatively to support you can buy My all four Cryptography book Just $10.99

  • The Modern Cryptography Book.
  • Go lang Cryptography for developers
  • Python Cryptography
  • Cryptography for JavaScript Developer

python Cryptography Topics
For Coffee/ Beer/ Amazon Bill and further development of the project Support by Purchasing, The Modern Cryptography CookBook for Just $9 Coupon Price

Cryptography for Python Developers

Cryptography for JavaScript Developers

Go lang ryptography for Developers