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].