In this practical exercise, I worked with Google Cloud Platform (GCP), Google Kubernetes Engine (GKE), Kubernetes StorageClass, PersistentVolume (PV), PersistentVolumeClaim (PVC), and Pod storage.
The main goal was to understand how Kubernetes can dynamically create persistent storage and attach that storage to a Pod.
š Architecture
The complete flow of this practical is:
Google Cloud
ā
ā¼
Google Kubernetes Engine (GKE)
ā
ā¼
Standard Kubernetes Cluster
ā
āāāāāāāāāāāāāāāāā
ā ā
ā¼ ā¼
StorageClass PVC
"fast" "claim1"
ā ā
āāāāāāāāā¬āāāāāāāā
ā¼
Dynamic Provisioning
ā
ā¼
Google Persistent Disk
ā
ā¼
PersistentVolume
ā
ā¼
Pod
"webpod"
ā
ā¼
Nginx
1. Create a GKE Standard Cluster
First, I created a Standard GKE cluster in Google Cloud.
After connecting Cloud Shell to the cluster, I verified the Kubernetes nodes:
kubectl get nodes
Example output:
NAME STATUS ROLES AGE
gke-mycluster-default-pool-... Ready <none> ...
gke-mycluster-default-pool-... Ready <none> ...
gke-mycluster-default-pool-... Ready <none> ...
All three nodes were in the:
Ready
state.
This confirmed that my Kubernetes cluster was working properly.
2. Check Kubernetes Resources
Next, I checked the resources in the cluster:
kubectl get all
Then I checked whether any PersistentVolumes existed:
kubectl get pv
PVCs:
kubectl get pvc
Pods:
kubectl get pod
Initially, there were no PVs, PVCs, or application Pods because I had not created them yet.
3. Check StorageClasses
I then checked the available StorageClasses:
kubectl get sc
A GKE cluster already provides StorageClasses. In my practical, I wanted to create my own StorageClass called:
fast
The purpose of the StorageClass is to tell Kubernetes how to dynamically provision storage.
4. Create a PersistentVolumeClaim
I created a PVC configuration file:
vim pvc-dynamic.yaml
The configuration was:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: claim1
spec:
storageClassName: fast
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
What does this mean?
The PVC is requesting:
- PVC name:
claim1 - StorageClass:
fast - Storage:
1Gi - Access mode:
ReadWriteOnce
The important part is:
storageClassName: fast
This tells Kubernetes:
“Use the StorageClass named
fastto provide my storage.”
5. Create the StorageClass
Next, I created:
vim sc.yaml
with:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
Here:
name: fast
creates a StorageClass named fast.
And:
provisioner: kubernetes.io/gce-pd
tells Kubernetes to use the Google Compute Engine Persistent Disk provisioner.
The parameter:
type: pd-ssd
requests an SSD-backed Persistent Disk.
Important: For current GKE clusters, Google recommends the GKE Persistent Disk CSI driver (
pd.csi.storage.gke.io) rather than the olderkubernetes.io/gce-pdprovisioner. Your exercise demonstrates the older provisioner concept, while your current cluster also showedstandard-rwousing the CSI driver.
6. Dynamic Provisioning
This is the most important concept in this practical.
Normally, we could manually create:
PersistentVolume ā PersistentVolumeClaim ā Pod
But with dynamic provisioning, Kubernetes can automatically create the PersistentVolume when the PVC requests storage through a StorageClass.
The process is:
PVC claim1
ā
ā¼
StorageClass fast
ā
ā¼
Provisioner
ā
ā¼
Google Persistent Disk
ā
ā¼
PersistentVolume
ā
ā¼
PVC becomes Bound
So we don’t have to manually create a PV YAML file for this dynamic provisioning exercise.
7. Check PV and PVC
After creating the StorageClass and PVC, I checked:
kubectl get pv
and:
kubectl get pvc
The PVC should eventually become:
STATUS: Bound
For example:
NAME STATUS VOLUME CAPACITY
claim1 Bound pvc-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 1Gi
This means Kubernetes successfully created storage for the PVC.
8. Create a Pod Using the PVC
Next, I created:
vim pod-pv.yaml
with the following configuration:
apiVersion: v1
kind: Pod
metadata:
name: webpod
spec:
volumes:
- name: vol1
persistentVolumeClaim:
claimName: claim1
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: vol1
Here the Pod is called:
webpod
and it uses the PVC:
claim1
The PVC is mounted inside the Nginx container at:
/usr/share/nginx/html
9. Apply the Pod Configuration
I applied the configuration:
kubectl apply -f pod-pv.yaml
Then checked the Pod:
kubectl get pod
To continuously watch the Pod status, I used:
kubectl get pod -w
Eventually, the Pod should become:
webpod 1/1 Running
10. Describe the Pod
To understand how the storage was attached to the Pod, I used:
kubectl describe pod webpod
This command is useful for troubleshooting because it shows information such as:
- Pod status
- Node
- Containers
- Volumes
- Volume mounts
- Events
- Scheduling information
The volume section shows that the Pod is using the PVC claim1.
11. Check the PVC
I also checked:
kubectl get pvc
The PVC should show:
claim1 Bound
The relationship is:
Pod
ā
ā¼
PVC: claim1
ā
ā¼
PV
ā
ā¼
Google Persistent Disk
12. Delete the Resources
After completing the practical, I practiced deleting the resources.
First, I attempted to delete the PVC:
kubectl delete pvc claim1
Then checked:
kubectl get pods
Next, I deleted the Pod:
kubectl delete pod webpod
Then:
kubectl get pods
Finally, I deleted the PVC:
kubectl delete pvc claim1
and checked:
kubectl get pvc
Then:
kubectl get pv
13. Delete the StorageClass
Finally, I checked the StorageClasses:
kubectl get sc
Then deleted my custom StorageClass:
kubectl delete sc fast
And verified:
kubectl get sc
The custom fast StorageClass was removed.
š Complete Practical Flow
The entire practical can be summarized as:
Google Cloud
ā
ā¼
GKE Standard Cluster
ā
ā¼
Create StorageClass
"fast"
ā
ā¼
Create PVC "claim1"
1Gi storage
ā
ā¼
Dynamic Provisioning
ā
ā¼
Google Persistent Disk
ā
ā¼
PersistentVolume
ā
ā¼
PVC ā Bound
ā
ā¼
Create Pod "webpod"
ā
ā¼
Nginx
ā
ā¼
Mount PVC at /usr/share/nginx/html
šÆ What I Learned
From this practical, I learned:
- How to create and work with a GKE Standard cluster.
- How to check Kubernetes nodes using
kubectl get nodes. - What a PersistentVolume (PV) is.
- What a PersistentVolumeClaim (PVC) is.
- How a StorageClass works.
- How dynamic volume provisioning works.
- How to request storage using a PVC.
- How Kubernetes automatically provisions persistent storage.
- How to mount a PVC inside an Nginx Pod.
- How to inspect a Pod using
kubectl describe. - How to delete Pods, PVCs, PVs, and StorageClasses.
ā Key Concept

The most important thing I learned is:
A PVC requests storage, while a StorageClass defines how Kubernetes should dynamically create that storage.
This makes Kubernetes storage much easier to manage because applications can request storage without manually creating every PersistentVolume.