In the previous post, Learn Kubernetes part 2 – NGINX Ingress Controller, we have deployed a web application and exposed it via the kubernetes/ingress-nginx ingress controller.
In this exercise we will use Traefik, another popular proxy server. Traefik is widely used for multiple reasons: it is easier to configure, can automatically generate and renew SSL certificates using Let’s Encrypt. We will also use most of the scripts from the prior exercise.
Create the Traefik Role Based Access Control with ClusterRoleBinding. This will allow Traefik to serve all namespaces of the cluster. To restrict the Traefik to one namespace only, use the “namespace-specific RoleBindings”.
traefik-rbac.yaml (Based on https://docs.traefik.io/user-guide/kubernetes/)
---
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
---
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: kube-system
Deploy Traefik with a deployment. This introduces a few more network hops, but follows the Kubernetes best practices guidelines and provides more flexibility.
traefik-deployment.yaml (Based on https://docs.traefik.io/user-guide/kubernetes/)
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
namespace: kube-system
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: traefik-ingress-controller
namespace: kube-system
labels:
k8s-app: traefik-ingress-lb
spec:
replicas: 1
selector:
matchLabels:
k8s-app: traefik-ingress-lb
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: traefik
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
- name: admin
containerPort: 8080
args:
- --api
- --kubernetes
- --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
name: web
- protocol: TCP
port: 8080
name: admin
type: NodePort
Create the resources
Launch the scripted resources
kubectl apply -f .
Check the Traefik pods. List the pods in the kube-system namespace, and make sure the “traefik-ingress-controller” is running.
kubectl --namespace=kube-system get pods
Expose the Traefik Web UI with a service
To be able to access the Traefik Web UI we will create a service and an ingress to expose it outside of the cluster.
ui.yaml (Based on https://docs.traefik.io/user-guide/kubernetes/)
---
apiVersion: v1
kind: Service
metadata:
name: traefik-web-ui
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- name: web
port: 80
targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-web-ui
namespace: kube-system
spec:
rules:
- host: traefik-ui.minikube
http:
paths:
- path: /
backend:
serviceName: traefik-web-ui
servicePort: web
Create the resources
Launch the scripted resources
kubectl apply -f .
Check the ingress
List the cluster ingresses
kubectl get ingress --all-namespaces
NAMESPACE NAME HOSTS ADDRESS PORTS AGE kube-system traefik-web-ui traefik-ui.minikube 80 53s
Access the Kubernetes cluster via Traefik
To be able to access the traefik-ui.minikube host we need to modify the /etc/hosts file. Add the host to the file with the localhost IP address.
echo "127.0.0.1 traefik-ui.minikube" | sudo tee -a /etc/hosts
==================================
app1-frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1-frontend-deployment
spec:
replicas: 3
selector:
matchLabels:
app: app1-frontend-template-label
template:
metadata:
labels:
app: app1-frontend-template-label
spec:
containers:
- name: app1-frontend-container-label
image: nginx:1.7.9
ports:
- containerPort: 80
app1-frontend-service.yaml
apiVersion: v1
kind: Service
metadata:
name: app1-frontend-service
spec:
selector:
app: app1-frontend-template-label
ports:
- protocol: TCP
port: 8080
targetPort: 80