Working with Volumes in Microk8s
Introduction
Hello 👋,
In this quick tutorial 💻 we’ll explore how to use Volumes and PersistentVolumes with hostpath storage in Microk8s.
We will deploy a simple nginx instance and mount a volume inside it that points to the ~/Downloads folder.
Let’s get started!
Note: The following image was generated with Stable Diffusion

How-To
You can follow along if you want to setup a quick deployment with a host path volume.
Persistent Volume
Let’s start by creating a Persistent Volume resource:
k apply -f persistent-volume.yamlapiVersion: v1kind: PersistentVolumemetadata: name: nuculabs-persistent-volume labels: app: nginx owner: dnutiu name: tutorial-volumespec: storageClassName: microk8s-hostpath # Exclusive to PVC claimRef: name: nuculabs-persistent-volume-claim namespace: default capacity: storage: 1Gi accessModes: - ReadWriteMany hostPath: path: "/home/denis/Downloads"After applying the file you should see:
➜ Downloads k apply -f persistent_volume.yml persistentvolume/nuculabs-persistent-volume created➜ Downloads k get pvNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEnuculabs-persistent-volume 1Gi RWX Retain Available default/nuculabs-persistent-volume-claim microk8s-hostpath 5sThe created persistent volume is exclusive to the PersistentVolumeClaim we’ll create next.
Persistent Volume Claim
To reserve the nuculabs-persistent-volume Persistent Volume we need to create a claim:
k apply -f persistent-volume-claim.yamlapiVersion: v1kind: PersistentVolumeClaimmetadata: name: nuculabs-persistent-volume-claim namespace: default labels: app: nginx owner: dnutiu name: tutorial-volumespec: storageClassName: "microk8s-hostpath" volumeName: nuculabs-persistent-volume accessModes: - ReadWriteMany resources: requests: storage: 500GiWe can ensure that the claim is bound to our PV by referencing the volumeName:
spec: storageClassName: "microk8s-hostpath" volumeName: nuculabs-persistent-volumeor by using the matchLabels selector:
spec: storageClassName: "microk8s-hostpath" selector: matchLabels: app: nginx owner: dnutiu name: tutorial-volumeTo verify that the volume is bound run:
k get pvNAME STATUS CLAIM nuculabs-persistent-volume ... Bound default/nuculabs-persistent-volume-claim It should list the volume name along with the Bound status.
If you’re following along, congrats for making it this far! 😁

Deployment
Finally, let’s create our nginx deployment that contains the mounted volume.
k apply -f nginx-deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deployment labels: app: nginxspec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 volumeMounts: - mountPath: "/data" name: data-volume volumes: - name: "data-volume" persistentVolumeClaim: claimName: nuculabs-persistent-volume-claimWe mount the volume to the nginx container with:
volumeMounts: - mountPath: "/data" name: data-volumeThen we add volumes to the spec and map “data-volume” to our PVC:
volumes: - name: "data-volume" persistentVolumeClaim: claimName: nuculabs-persistent-volume-claimThat’s it! 🎉
If you want to verify that the volume is mounted correctly you can SSH into the nginx pod and navigate to the /data directory.
Thanks for reading! 📚