K8S storage
- RNREDDY

- Aug 30
- 4 min read
Kubernetes Storage Lab Concepts – Best Practices (for Certification)

1. Understand the Storage Types
Type | Description | Example Use Case |
emptyDir | Ephemeral storage, tied to Pod lifecycle | Temporary cache/logs |
hostPath | Mounts a file/dir from host node | Debugging (not for production) |
PersistentVolume (PV) | Cluster-managed storage abstraction | Long-term app data (e.g., DBs) |
PersistentVolumeClaim (PVC) | Pod request for storage | How apps get storage access |
ConfigMap/Secret Volumes | Projected volumes for config/secrets | Injecting app configs, passwords |
Kubernetes emptyDir Volume
The emptyDir volume in Kubernetes is a temporary directory that gets created when a Pod is assigned to a Node. It is empty when the Pod starts, and deleted when the Pod is removed from the node.
What is emptyDir?
An emptyDir volume is a temporary storage that’s created when a Pod is scheduled on a node. It’s:
Initially empty
Shared across all containers in the Pod
Deleted when the Pod is removed from the node
Can be backed by disk or RAM (medium: Memory)
Use Case:
Share data between multiple containers in a Pod
Temporary scratch space for processing (e.g., log files, caches)
Log aggregation: One container writes logs, another reads and forwards them.
In-memory processing: Use RAM-backed storage for fast data access.
Batch jobs: Temporary staging area for intermediate files.
Init containers: Pass setup files to main containers.
Step 1: Define a Pod with an emptyDir Volume
apiVersion: v1
kind: Pod
metadata:
name: emptydir-demo
spec:
volumes:
- name: shared-data
emptyDir: {} # creates the temporary storage
containers:
- name: writer
image: busybox
command: [ "sh", "-c", "while true; do echo $(date) >> /cache/timestamp.txt; sleep 3600; done" ]
volumeMounts:
- name: shared-data
mountPath: /cache
- name: reader
image: busybox
command: [ "sh", "-c", "tail -f /cache/timestamp.txt" ]
volumeMounts:
- name: shared-data
mountPath: /cache
kubectl apply -f emptydir.yaml
Check Pod Status
kubectl get pods
Get Logs from Reader
kubectl logs emptydir-demo -c reader
Check the Storage (inside pod)
kubectl exec -it emptydir-demo -c writer -- sh
ls /cache
cat /cache/timestamp.txt
Exit
Verify Sharing
kubectl exec -it emptydir-demo -c reader -- sh
cat /cache/timestamp.txt
Example2:
apiVersion: v1
kind: Pod
metadata:
name: log-aggregator
spec:
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- name: log-volume
mountPath: /var/log/nginx
- name: log-reader
image: busybox
args: ["/bin/sh", "-c", "tail -n+1 -F /var/log/nginx/access.log"]
volumeMounts:
- name: log-volume
mountPath: /var/log/nginx
volumes:
- name: log-volume
emptyDir: {}
Full Flow Explained:
Two containers:
nginx (generates logs)
log-reader (reads and tails logs)
Shared Volume:
An emptyDir named log-volume
Mounted to both containers at /var/log/nginx
Full Flow Explained
1. nginx container:
Uses nginx:alpine image
Writes access logs to /var/log/nginx/access.log
Mounts the shared log-volume to /var/log/nginx
2. log-reader container:
Uses busybox
Runs this command:
tail -n+1 -F /var/log/nginx/access.log
Continuously reads (tails) the shared log file
Also mounts the same log-volume at /var/log/nginx
Volume: emptyDir
volumes:
- name: log-volume
emptyDir: {}
Created when the Pod starts
Shared between both containers
Deleted automatically when the Pod is removed
kubectl apply -f log-aggregator.yaml
Trigger traffic to generate logs:
kubectl exec -it log-aggregator -c nginx -- wget localhost
View logs:
kubectl logs log-aggregator -c log-reader
What is hostPath?
hostPath is a volume type in Kubernetes that mounts a file or directory from the host node's filesystem directly into a Pod.
It’s useful for accessing node-level files, logs, or sockets.
Caution
hostPath ties your Pod to a specific node, breaking portability.
Can be a security risk if not used carefully.
Use only in development, monitoring, or specific admin tasks.
Use Case | Description |
🔍 Accessing host logs | Monitor /var/log/ from within a Pod |
📁 Persisting data on host | Save files directly on host storage |
📦 Docker socket sharing | Access Docker daemon via /var/run/docker.sock |
⚙️ Custom configuration files | Mount node-specific config into Pod |
🧪 Testing non-cloud volumes | Simulate shared local disks for tests |
Example 1: Mount /var/log to read host logs
apiVersion: v1
kind: Pod
metadata:
name: hostpath-logs
spec:
containers:
- name: log-reader
image: busybox
command: ["/bin/sh", "-c", "sleep 3600"]
volumeMounts:
- name: host-logs
mountPath: /hostlogs
volumes:
- name: host-logs
hostPath:
path: /var/log
type: Directory
What Is a StorageClass in Kubernetes?
A StorageClass in Kubernetes defines how storage is dynamically provisioned for a PersistentVolumeClaim (PVC). It contains details like the provisioner (the plugin responsible for creating storage), parameters (such as storage type, size, filesystem), and reclaim policy. Essentially, it lets you abstract and automate the creation of storage, based on desired characteristics.
Static vs. Dynamic Provisioning
Dynamic Provisioning: PVC automatically creates a PV using a StorageClass.
Static Provisioning: An existing PV is manually created and bound to a PVC. You still can use a StorageClass to signal intended usage, even though the PV already exists
Create a Static Persistent Volume (PV)
# pv-local.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /mnt/mydata
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- minikube-server # <-- mee node name ikkada pettaali
Create a PVC (Persistent Volume Claim)
# pvc-local.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: local-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-storage
resources:
requests:
storage: 5Gi
Use it in a Pod
# pod-using-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-pvc-demo
spec:
containers:
- name: busybox
image: busybox
command: [ "sleep", "3600" ]
volumeMounts:
- name: mydata
mountPath: /data
volumes:
- name: mydata
persistentVolumeClaim:
claimName: local-pvc
Verify Inside Pod
kubectl exec -it pod-pvc-demo -- sh
/ # df -h /data



Comments