CKAD Exam preparation -Application Design and Build -Part4

Balasekar Natarajan
5 min readJan 1, 2022

Certified Kubernetes Application Developer Exam prepartion, in continution to part3, we will progress on understanding utilization of persistent and ephemeral volumes

Utilize persistent and ephemeral volumes

Persistent Volumes

A PersistentVolume (PV) is a piece of storage in the cluster that has been provisioned by an administrator or dynamically provisioned using Storage Classes.

A PersistentVolumeClaim (PVC) is a request for storage by a User. Pods consume node resources and PVC consume PV resources. Similary pod request specific CPU & Memory, PVC can request specific size and access mode (ReadWriteOnce, ReadOnlyMany and ReadWriteMany)

PV Lifecycle

Provision

The provision could be static or dynamic. In static provision, the administrator create real storage which is available in the cluster for use. They exist in kubenetes API. In dynamic provision, when there is no static PV matching the PVC request, the cluster would provision volume based on the StorageClass.

Binding

Binding is a one-to-one mapping between the PVC and PV regardless of the provision types. PVC is not bound unless the matchin PV is available in the cluster.

Using

Pod uses claims as volumes. The user claims the Volumes by using persistentVolumeClaim section in a Pod’s volumes block.

Reclaiming

When the PVC is no more used, the user can delete the PVC objects to reclaim the resources based on the reclaim policy such as Retain, Delete, Recycle. The Retain allows manual reclamation, the PV is not avaiable for new claim. The Delete allows deletion of K8s resource and associated storage. Recycle allows for storage to be scrubbed. Recyle policy is deprecated and Delete is default policy.

Create hostPath PV

Both local, hostPath could be created as PV and later can be allocated to user as PersistentVolumeClaim

HostPath volumes pose security risk and usually not advised. Instead local PV could be used.

$ kubectl run nginx --image nginx --dry-run -o yaml > hostpathPod.yaml//Edit the hostpathPod.yaml
--- hostpathPod.yaml---
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
volumes:
- name: host-path-vol
hostPath:
path: /test-pd
type: DirectoryOrCreate

containers:
- image: nginx
name: nginx
resources: {}
volumeMounts:
- mountPath: /data
name: host-path-vol

dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}

Here in volumes section, hostPath is declared to be created on node’s /test-pd path, which is used by pod to mount to /data

There are various types allowed on the hostPath such as DirectoryOrCreate, Directory, FileOrCreate, File, Socket, etc

Create local PV

A local volume represents a mounted local storage device such as a disk, partition or directory. Note, local PV required nodeAffinity spec and /data-pd existing on the host.

---local-pv.yaml---
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /data-pd
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- minikube

Create PVC for the PV

---local-pvc.yaml---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: example-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi

Create pod to use the PVC

---local-pv-pod.yaml---
$ kubectl run nginx-local-pv --image nginx -o yaml --dry-run > local-pv-pod.yaml
// edit yaml to add the claim details
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx-local-pv
name: nginx-local-pv
spec:
volumes:
- name: nginxclaim
persistentVolumeClaim:
claimName: example-claim
containers:
- image: nginx
name: nginx-local-pv
resources: {}
volumeMounts:
- name: nginxclaim
mountPath: /data
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
$ kubectl create -f local-pv-pod.yaml

Ephemeral Volumes

Ephemeral volumes are created and deleted along with the pod and does not care about long persistence across pod restart or deletion.

Usually ephemeral volume specs are within the pod spec that make pod deployment easy.

Some of them are

  • emptydir
  • secret
  • configmap
  • and other long list here

Creata emptyDir Volume:

$ kubectl run ng-emptydir --image nginx -o yaml --dry-run > ng-emptydir-pod.yaml// edit the template to add the empty directory
---ng-emptydir-pod.yaml---
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: ng-emptydir
name: ng-emptydir
spec:
containers:
- image: nginx
name: ng-emptydir
resources: {}
volumeMounts:
- name: sample-vol
mountPath: /data
dnsPolicy: ClusterFirst
restartPolicy: Always
volumes:
- name: sample-vol
emptyDir: {}
status: {}
$ kubectl create -f ng-emptydir-pod.yaml
$ kubectl describe pod ng-emptydir // check for volume mounts in the description

Create Secret Volume

Creating volumes from secret can be of two ways, 1. Applying the entire contents of the secret to folder 2. Setting only the specific keys from the secret. The below is of approach 1. For Approach 2, spec.volumes.secret.items[] can be used. The secret also supports permissions

//Create the secret
$ kubectl create secret generic volsecret --from-literal=pass=password
---secret-vol-pod.yaml---
Version: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: ng
name: ng
spec:
volumes:
- name: mysecretvol
secret:
secretName: volsecret
containers:
- image: nginx
name: ng
resources: {}
volumeMounts:
- name: mysecretvol
mountPath: "/etc/foo"
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
// create the pod
$ k create -f secret-vol-pod.yaml
// exec into the pod to list and describe the file content
$ k exec -it ng -- sh
# ls /etc/foo/pass // to check the file location
# cat /etc/foo/pass // to check the file content

Create configMap volumes

Similar to the secret volumes, configmap could also be configured as volumes,permission could be set and specific keys from the map can be mapped onto the volume mount files.

$ kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
// create pod template and add config map volume config
---ng-config-pod.yaml---
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: ng-config
name: ng-config
spec:
volumes:
- name: myconfigvol
configMap:
name: my-config
containers:
- image: nginx
name: ng-config
resources: {}
volumeMounts:
- name: myconfigvol
mountPath: "etc/config"
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
---
$ kubectl exec -it ng-config -- ls /etc/config
// key1 key2 should be the output of the above command

Support commands

$ kubectl explain pod.spec.volumes 
$ kubectl explain pod.spec.containers.volumeMounts --recursive=true
// Above commands helps debug/getting necessary field names if there are issues while setting the deployments.

Bookmarks

  1. https://kubernetes.io/docs/concepts/storage/volumes/#emptydir
  2. https://kubernetes.io/docs/concepts/storage/volumes/#configmap
  3. https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod
  4. https://kubernetes.io/docs/concepts/storage/volumes/#local

--

--

Balasekar Natarajan

I am a Software Engineer, Vivid Technical & Technology story reader. My interest are Cloud, Containerization, Linux and yet to read longlist. Views are my own.