Hello! Welcome back to our module on Persistent Storage Fundamentals.
In our last lesson, we explored the crucial relationship between Pods, PersistentVolumeClaims (PVCs), and PersistentVolumes (PVs). You learned that a Pod requests storage by referencing a PVC, which in turn gets bound to a PV representing the actual storage resource. This abstraction is key to decoupling applications from infrastructure.
Today, we'll get our hands dirty and implement the first part of this model. Our learning outcome is to create a hostPath PersistentVolume for local development. We'll focus on the administrator's role: provisioning a piece of storage and making it available to the cluster. While in your production work with EKS, AKS, or GKE you'd typically use PVs backed by cloud storage (like AWS EBS or Azure Disk), the hostPath type is an excellent way to learn the mechanics on a local cluster like Minikube or Kind.
1. The Need for Node-Level Persistence
Before we build a full PersistentVolume, let's solidify why we need storage that outlives a Pod. You've seen that volumes like emptyDir are tied to the Pod's lifecycle—if the Pod is deleted, the data is gone. The next logical step is to store data directly on the node's filesystem.
The video 'Kubernetes Volumes Simplified' does a great job of demonstrating this exact problem. It first shows the limitation of an emptyDir volume when a Pod is deleted, and then introduces hostPath as the direct solution.
Watch from 12:09 to 16:50. The first part (until 14:03) shows data loss with emptyDir when a Pod is deleted. The second part (from 14:03) demonstrates how a hostPath volume solves this by persisting the data on the node itself.
As the video shows, a hostPath volume mounts a file or directory from the host node's filesystem directly into your Pod. This is a significant step up from emptyDir because the data remains on the node even if the Pod is deleted and recreated.
However, using hostPath directly inside a Pod manifest has major drawbacks for anything beyond simple testing:
- Node Dependency: The Pod is now tied to a specific node. If the node goes down, the data is inaccessible.
- Manual Management: You have to manually manage which directories on which nodes are used by which Pods.
- Security: Granting Pods access to the host filesystem can introduce security vulnerabilities.
This is where the PV/PVC abstraction comes in. Instead of a Pod directly mounting a hostPath, an administrator creates a PersistentVolume of type hostPath. This formalizes the piece of node storage as a cluster-wide resource.
2. Creating a hostPath PersistentVolume
Creating a hostPath PV is a two-step process:
- Prepare the Node: You need to create the directory on the node that will serve as the storage.
- Define the PV Object: You create a
PersistentVolumemanifest in YAML that tells Kubernetes about this directory.
Let's walk through this using the official Kubernetes documentation as our guide.
Step A: Prepare the Node's Filesystem
First, you need to SSH into your Kubernetes node (e.g., with minikube ssh) and create the directory that will back our volume.
Configure a Pod to Use a PersistentVolume for Storage
The official guide 'Configure a Pod to Use a PersistentVolume for Storage' provides the exact commands for this preparation step. We will follow it to create a directory and a test file inside it.
Please follow the instructions in the section 'Create an index.html file on your Node'. This involves creating a /mnt/data directory on your node and placing a simple index.html file inside it.
This manual preparation is specific to hostPath. For cloud-based storage, this step is replaced by provisioning a resource like an EBS volume or an Azure Disk.
Step B: Define and Create the PV Manifest
Now that the physical storage location exists on the node, we need to create a Kubernetes API object to represent it. This is our PersistentVolume.
Configure a Pod to Use a PersistentVolume for Storage
Let's continue with the same official guide to see the YAML manifest for our hostPath PV.
Now, read the section 'Create a PersistentVolume'. Study the YAML file (pv-volume.yaml) provided. We will break down its key fields next.
Let's dissect the spec of that PersistentVolume manifest:
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
storageClassName: manual: This is a crucial field for binding. APersistentVolumeClaimcan request a specificstorageClassName, and Kubernetes will only bind it to a PV of the same class. Using a name likemanualsignifies that this PV was created by an administrator by hand.capacity.storage: 10Gi: This declares how much storage this PV represents. This is used by Kubernetes to match it against a PVC's request for storage.accessModes: This defines how the volume can be mounted.ReadWriteOnce(RWO) means it can be mounted as read-write by a single node. Other common modes areReadOnlyMany(ROX) andReadWriteMany(RWX).hostPath.path: "/mnt/data": This is the core of our configuration. It tells Kubernetes that this PV is backed by the/mnt/datadirectory on the host node.
To see another practical demonstration of creating a hostPath PV manifest, you can watch this short clip.
Day 29/40 Kubernetes Volume Simplified | Persistent Volume, Persistent Volume Claim & Storage Class
The video 'Day 29/40 Kubernetes Volume Simplified' by Tech Tutorials with Piyush provides a concise walkthrough of creating a hostPath PV manifest, explaining the same key fields.
Watch from 16:58 to 18:49. Notice how the YAML structure is identical to the one in the documentation, reinforcing the standard practice.
Now, create the PersistentVolume in your cluster using the command from the documentation:
kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
3. Verify the PersistentVolume
After applying the manifest, you can verify that your PV exists and is ready to be claimed.
Run the following command:
kubectl get pv task-pv-volume
You should see output similar to this:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Available manual 4s
The most important field to notice here is STATUS: Available. This means our PV has been successfully provisioned and is waiting for a PersistentVolumeClaim to come and bind to it.
Test your understanding!
You need to provision a new hostPath PV for a special logging Pod that requires 500Mi of storage from a directory located at /var/log/app-data on the node. The storage should be mountable as read-write only by a single node.
Which fields in the PersistentVolume spec would you need to set, and what would their values be?
Show answer
You would set the following fields in the spec:
capacity.storage:500MiaccessModes:[ "ReadWriteOnce" ]hostPath.path:"/var/log/app-data"
You would also likely set a storageClassName, for example storageClassName: manual-logging, to distinguish it from other types of storage.
Conclusion
Congratulations! You have successfully created a hostPath PersistentVolume. You've taken a directory on a node and represented it as a formal, cluster-level storage resource.
Key Takeaways:
- A
hostPathvolume mounts a directory from the host node into a Pod, allowing data to persist beyond the Pod's lifecycle. - Creating a
hostPathPersistentVolume is the administrator's way of making this node-level storage available to the cluster in a managed way. - The PV manifest defines key properties like
capacity,accessModes, and the actualhostPath.path. - A newly created PV will have the status
Available, indicating it's ready to be bound by a PVC.
Next Up:
We have the "supply" side of our storage equation ready. In the next lesson, we will act as the developer and create a PersistentVolumeClaim (PVC) to request storage from the PV we just made. We will then mount that claim into a Pod, completing the full Pod -> PVC -> PV workflow.