Persistent volume type: HOST PATH

  • the correct choice for databases, such as MySQL;
  • mounts a volume (file or directory) from the host node’s file-system into the Pod;
  • accessible from all pods in the same node;
  • not accessible from other nodes of the cluster;
  • if the node crashes the data is lost.

Create the nginx-deployment-hostpath.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-instance
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-instance
  template:
    metadata:
      labels:
        app: nginx-instance
    spec:
      containers:
      - name: nginx-instance
        image: nginx
        imagePullPolicy: Always
        ports:
        - containerPort: 80
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
      volumes:
      - name: www
        hostPath:
          path: /mnt/data

The page may say it is forbidden because the mounted directory (/usr/share/nginx/html) inside the pod is empty. The source where the data is physically being stored (/mnt/data) in the host node is.

Create the nginx-loadbalancer.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-loadbalancer
  annotations:
    service.beta.kubernetes.io/linode-loadbalancer-throttle: "5"
  labels:
    app: nginx-loadbalancer
spec:
  type: LoadBalancer
  selector:
    app: nginx-instance
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
  sessionAffinity: None

Setting up

export KUBECONFIG=kube1-kubeconfig.yaml
kubectl apply -f nginx-deployment-hostpath.yaml
kubectl apply -f nginx-loadbalancer.yaml 
kubectl get services

Get the public IP of the load balancer and enter on the browser.

Get the name of the pods and create a file inside the mounted volume using one of the pods (the bold parts represents the random part appended to the name):

kubectl get pods
kubectl exec -ti nginx-deployment-6fb5f9998b-qngbk -- /bin/bash -c "echo 'TEST 1' > /usr/share/nginx/html/index.html"

To get a shell inside the pod issue:

kubectl exec -ti nginx-deployment-6fb5f9998b-qngbk -- /bin/bash

Persistent volume type: NFS

  • mounts a shared directory from the FNS Server’s file-system into the Pod;
  • accessible from all pods in the same network, no matter the node or cluster;
  • not inside the cluster, has to be set up manually;
  • if the node or cluster crashes the data remains;
  • manual backup and management on the NFS Server.

Configuring an Ubuntu NFS server (one virtual machine that is outside the Kubernetes cluster).

sudo apt-get update
sudo apt-get install nfs-kernel-server rpcbind -y
sudo ufw allow nfs
sudo nano /etc/exports

Append:

/files *(rw,sync,no_subtree_check,insecure)

The configuration above is very insecure and vulnerable, use it only for proof of concept. At least replace the * with the IP of the Kubernetes. For example, 192.168.1.7 or 192.168.1.0/24.

And activate the NFS shares and check:

sudo exportfs -ra

Create the nginx-deployment-nfs.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-instance
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-instance
  template:
    metadata:
      labels:
        app: nginx-instance
    spec:
      containers:
      - name: nginx-instance
        image: nginx
        imagePullPolicy: Always
        ports:
        - containerPort: 80
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html/
      volumes:
      - name: www
        persistentVolumeClaim:
          claimName: www-pvc

Create the nginx-nfs-pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: www-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.1.1
    path: "/data/share"

Replace the Server’s IP (192.168.1.1) and the Path (/data/share) with the correct ones.

Create the nginx-nfs-pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: www-pvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 10Gi

Create the nginx-loadbalancer.yaml same as the example before.

Apply everything:

export KUBECONFIG=kube1-kubeconfig.yaml
kubectl apply -f nginx-nfs-pv.yaml
kubectl apply -f nginx-nfs-pvc.yaml
kubectl apply -f nginx-deployment-nfs.yaml
kubectl apply -f nginx-loadbalancer.yaml
kubectl get services

Get the public IP of the load balancer and enter on the browser.


Persistent volume type: Linode Block Storage (Volume)

  • it is a drive that can be mounted into the Pods of the same Cluster;
  • physically localised outside the cluster but is created through the kubectl;
  • if the node or cluster crashes the data remains;
  • can also be attached to a virtual machine if not attached to a node.

Create the nginx-deployment-vol.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-instance
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-instance
  template:
    metadata:
      labels:
        app: nginx-instance
    spec:
      containers:
      - name: nginx-instance
        image: nginx
        imagePullPolicy: Always
        ports:
        - containerPort: 80
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html/
      volumes:
      - name: www
        persistentVolumeClaim:
          claimName: www-pvc

Create the nginx-vol-pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: www-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: linode-block-storage

Create the nginx-loadbalancer.yaml same as the example before.

The linode-block-storage is limited to ReadWriteOnce and needs to be from 10Gi to 10240Gi.

  • ReadWriteOnce – Can only be attached to one node.
  • ReadWriteMany – Can be attached to many nodes and can be used with NFS for example.

Apply everything:

export KUBECONFIG=kube1-kubeconfig.yaml
kubectl apply -f nginx-vol-pvc.yaml
kubectl apply -f nginx-deployment-vol.yaml
kubectl apply -f nginx-loadbalancer.yaml
kubectl get services

The block storage will be created automatically.

Get the public IP of the load balancer and enter on the browser.


OTHER POSTS

Minikube on Ubuntu 22.04 [Link].

MicroK8s on Ubuntu 22.04 [Link].

K3s on Ubuntu 22.04 [Link].

Kubernetes Persistent Volumes [Link].

Kubernetes Cheat Sheet [Link].

Kubernetes Dashboard [Link].