Data Smith

The Data Blog

Musings and ramblings on a variety of topics.

Kubernetes for Websites

Using Kubernetes for Websites, and what an absolute joy it is.

Greg Smith

3 minute read

I want to use this post to describe how to deploy a website on your kubernetes cluster. Once more even though we could do this via the Dashboard I think it is better to learn Kubernetes via the CLI and it is also good practice to understand the YAML spec that is used extensively to configure Kubernetes deployments.

To create a website within Kubernetes we need three separate elements. A Deployment that describes the number and type of docker containers that we want to deploy. A Service to create an identifier by which we will connect to the Deployment internally and finally an Ingress to describe how we will expose the service so that we can connect to it externally.

Below is a config file to create:

  • A Deployment called datasmith-site which will create a single replica on an nginx container using internal Port 80 and using an NFS volume from my internal NAS which will be mounted within the container at /usr/share/html.
  • A Service called datasmith-service which we can use to reference this deployment running on Port 80.
  • An Ingress called datasmith-ingress that allows us to connect to the service if we get a request for “data-smith.ca” on Port 80
apiVersion: apps/v1
kind: Deployment
metadata:
  name: datasmith-site
  labels:
    app: datasmith-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: datasmith-nginx
  template:
    metadata:
      labels:
        app: datasmith-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: datasmith-volume
          mountPath: /usr/share/nginx/html
          subPath: data-smith.ca
      volumes:
      - name: datasmith-volume
        nfs:
          server: diskstation.local
          path: /volume1/pi-config
---
apiVersion: v1
kind: Service
metadata:
  name: datasmith-service
spec:
  selector:
    app: datasmith-nginx
  ports:
    - protocol: TCP
      port: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: datasmith-ingress
  annotations:
    kubernetes.io/ingress.class: "traefik"
spec:
  rules:
  - host: data-smith.ca
    http:
      paths:
      - backend:
          serviceName: datasmith-service
          servicePort: 80
pi@pi-proxy:~ $

Once we understand the 3 basic elements then to deploy data-smith.ca is really simple.

kubectl create -f data-smith.yml
deployment.apps/datasmith-site created
service/datasmith-service created
ingress.networking.k8s.io/datasmith-ingress created

After a few minutes, we can check the status of the deployment using the following commands.

kubectl get deployments -o wide
NAME             READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES   SELECTOR
datasmith-site   1/1     1            1           54s   nginx        nginx    app=datasmith-nginx

Note how the deployment will show how many replicas have been requested and how many are currently available. Remember this is Kubernetes, if a replica fails for whatever reason a new replica will be started to replace it. As an admin/operator we do not need to do anything.

kubectl get services -o wide
NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE   SELECTOR
kubernetes          ClusterIP   10.43.0.1      <none>        443/TCP   51d   <none>
datasmith-service   ClusterIP   10.43.61.184   <none>        80/TCP    96s   app=datasmith-nginx

See how the service datasmith-service is being advertised on an internal Cluster IP addresses

kubectl get ingress -o wide
NAME                CLASS    HOSTS           ADDRESS      PORTS   AGE
datasmith-ingress   <none>   data-smith.ca   10.0.0.159   80      2m3s

The Ingress rule specifies the hosts that are allowed to use this rule and leverages the service to indentify where the container is running at the moment in my case the IP address of pi-node1.

kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP          NODE       NOMINATED NODE   READINESS GATES
datasmith-site-7ddb94564c-m5cjw   1/1     Running   0          33m   10.42.2.7   pi-node1   <none>           <none>

And that is basically it, now I am using my NAS, but it is worth noting that I have not mounted my NAS to any of the nodes in my cluster. This is all controlled by Kubernetes which will perform the mount when it create the Deployment. It is also worth noting that my NAS has a tendancy to go to sleep, which does mean if you are trying to reach my site, you might actually get a delay as my NAS spins up out of hibernation. I will look eventually look at other Volume options but first I want to move on to the thorny topic of dynamic IP addresses and creating a DynamicDNS deployment within Kubernetes.

Recent posts

About

This is my personal blog space that I use to write about the many different things that interest me. To find out a little more about me click on the link