Certified Kubernetes Administrator (CKA) : Part-2: Storage
Background
This blog is a part of a mini-series for preparing for the CKA exam. This blog would focus on the concepts related to storage.
How to read through the various blogs in this mini-series
Please feel free to go through all blogs (or) a particular blog, for a concept that You want to have a quick review. However, I would recommend going through the exam tips, as it may help You better organize Your time.
- Part-1 : Tips
- Part-2: Storage - You are reading this
- Part-3 to Part-8: would update the links here as I publish them
Environment
Examples are executed using Docker Desktop on Mac, with Kubernetes.
% kubectl get nodes
NAME STATUS ROLES AGE VERSION
docker-desktop Ready control-plane 4h33m v1.24.0
Storage Usecases
Although Kubernetes supports many types of volumes, I would discuss on three particular use cases that could probably come up in the exam. Since exam does not assume familiarity with a particular storage technology, focussing on these limited storage options may be fine.
- emtpydir volume mounted inside a pod
- hostpath volume mounted inside a pod
- Persistent Volume Claim used to provide storage to a pod
emptydir volume mounted inside a pod
- An emptydir volume lasts for the life of the Pod, even if the Container terminates and restarts.
- volumes are defined in the pod spec using volumes and containers.volumeMounts fields.
- The following yaml is available at the following link.
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}
- Create Pod using above yaml
- Now, describe the pod and check that volume is mounted:
% kubectl describe pod redis
...
Mounts:
/data/redis from redis-storage (rw)
...
hostPath volume mounted inside a pod
- storage is provided from the host node's filesystem
- update the volumes.hostPath.path to your local filesystem
apiVersion: v1
kind: Pod
metadata:
name: task-pv-hostpath
spec:
volumes:
- name: task-pv-hostpath
hostPath:
path: /Users/sriramcvn/k8s_hostpath
type: Directory
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-hostpath
- Create Pod using above yaml
- Now, describe the pod and check that volume is mounted:
% kubectl describe pod task-pv-hostpath
...
Mounts:
/usr/share/nginx/html from task-pv-hostpath (rw)
...
PersistentVolume used to provide storage for a Pod
- PersistentVolume related api objects abstracts how storage is provided from how it is consumed.
- we would first create a local storage class (notice the VolumeBindingMode setting - storage is not bound until pod is created)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
- then, we would create persistent volume
- update local.path to your local filesystem
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /Users/sriramcvn/k8s_local
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- docker-desktop
- then, we would create persistent volume claim
- storageClassName is used to map to the available persistent volumes
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: local-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- Check that storage is not yet bound as pod is not created
% kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-storage kubernetes.io/no-provisioner Delete WaitForFirstConsumer false 4s
% kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
local-pv 2Gi RWO Delete Available local-storage 5s
% kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
task-pv-claim Pending local-storage 5s
- Now create the pod using following yaml and check that volume is bound
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
% kubectl apply -f pv-pod.yml
pod/task-pv-pod created
% kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
local-pv 2Gi RWO Delete Bound default/task-pv-claim local-storage 63s
% kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
task-pv-claim Bound local-pv 2Gi RWO local-storage 41s