Use Traefik as a Kubernetes Ingress Controller for your App on Civo
In the previous tutorial I showed you how to provision a Kubernetes Cluster on Civo.
In this tutorial we will deploy a application to our Kubernetes cluster which will be using Traefik that is installed by default onto your Cluster.
Traefik
Traefik is a super awesome and modern reverse proxy for microservices. By default Traefik get's installed onto your cluster which listens on port 80 and 443. Therefore we can deploy a web application to our cluster and deploy a ingress controller that will reverse proxy our connection from port 80 on the load balancer to the port of our container.
Demo Application
I have a demo application that will return the hostname of the container that will answer the request available at ruanbekker/hostname which is a golang application that is on docker hub.
Deploy the Demo
The manifest that contains a service, ingress and a deployment is available here. We will need the DNS endpoint that Civo provisioned for us that we will provide in our Ingress, which you can obtain using:
$ civo kubernetes show ${your_cluster_name} | grep 'DNS'
DNS A record : 7d91b88e-5b83-4444-a253-3a0c07b3408b.k8s.civo.com
Let's break up our manifest, the first part is our service:
apiVersion: v1
kind: Service
metadata:
name: hostname-service
spec:
selector:
app: traefik
ports:
- protocol: TCP
port: 80
targetPort: 8000
name: web
Then we have our ingress where we will need to provide our unique DNS endpoint, and as you can see we are specifying port 80 that it will associate to on our service that we also specified from our previous section:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hostname-ingress
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: your-unique-id.k8s.civo.com
http:
paths:
- backend:
serviceName: hostname-service
servicePort: 80
The last section is our deployment, where we will specify our docker image, and how our deployment will look like, 1 replica, update strategy etc:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: traefik
name: hostname
spec:
replicas: 1
selector:
matchLabels:
app: traefik
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: traefik
spec:
containers:
- name: hostname-app
image: ruanbekker/hostname:latest
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /
port: 8000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
ports:
- containerPort: 8000
name: http
protocol: TCP
readinessProbe:
failureThreshold: 1
httpGet:
path: /
port: 8000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
terminationGracePeriodSeconds: 30
Once we have everything saved to disk, we can apply the deployment:
$ kubectl apply -f app.yaml
service/hostname-service created
ingress.extensions/hostname-ingress created
deployment.extensions/hostname created
View your Resources
Use kubectl to view all your resources:
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/hostname-77cbd5d4b9-xvn58 1/1 Running 0 43s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/hostname-service ClusterIP 192.168.199.215 <none> 80/TCP 44s
service/kubernetes ClusterIP 192.168.128.1 <none> 443/TCP 54m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/hostname 1/1 1 1 43s
NAME DESIRED CURRENT READY AGE
replicaset.apps/hostname-77cbd5d4b9 1 1 1 44s
As you can see our application is running with one pod, test the application by making a HTTP request to your custom DNS name, and you should see the pod name being returned:
$ curl http://7d91b88e-5b83-4444-a253-3a0c07b3408b.k8s.civo.com
Hostname: hostname-77cbd5d4b9-xvn58
Scale your Deployment:
As you can see we only have one replica in our deployment, scale your deployment to 3 replicas:
$ kubectl scale deployment.apps/hostname --replicas 3
deployment.apps/hostname scaled
View your pods:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hostname-77cbd5d4b9-n2pp6 1/1 Running 0 22s
hostname-77cbd5d4b9-nbdqw 1/1 Running 0 22s
hostname-77cbd5d4b9-xvn58 1/1 Running 0 5m15s
As all three pods are running, we can make three HTTP requests, and those requests will be round robin'd to each pod:
$ curl http://7d91b88e-5b83-4444-a253-3a0c07b3408b.k8s.civo.com
Hostname: hostname-77cbd5d4b9-n2pp6
$ curl http://7d91b88e-5b83-4444-a253-3a0c07b3408b.k8s.civo.com
Hostname: hostname-77cbd5d4b9-nbdqw
$ curl http://7d91b88e-5b83-4444-a253-3a0c07b3408b.k8s.civo.com
Hostname: hostname-77cbd5d4b9-xvn58
Pretty sweet right!
This is all for now, until next time!