Overview
In this lab, you set up PersistentVolumes and PersistentVolumeClaims. PersistentVolumes are storage that is available to a Kubernetes cluster. PersistentVolumeClaims enable Pods to access PersistentVolumes. Without PersistentVolumeClaims Pods are mostly ephemeral, so you should use PersistentVolumeClaims for any data that you expect to survive Pod scaling, updating, or migrating.
Objectives
In this lab, you learn how to perform the following tasks:
- Create manifests for PersistentVolumes (PVs) and PersistentVolumeClaims (PVCs) for Google Cloud persistent disks (dynamically created or existing)
- Mount Google Cloud persistent disk PVCs as volumes in Pods
- Use manifests to create StatefulSets
- Mount Google Cloud persistent disk PVCs as volumes in StatefulSets
- Verify the connection of Pods in StatefulSets to particular PVs as the Pods are stopped and restarted
Lab setup
Access the lab
For each lab, you get a new Google Cloud project and set of resources for a fixed time at no cost.
-
Click the Start Lab button. If you need to pay for the lab, a pop-up opens for you to select your payment method.
On the left is the Lab Details panel with the following:
- The Open Google Cloud console button
- Time remaining
- The temporary credentials that you must use for this lab
- Other information, if needed, to step through this lab
-
Click Open Google Cloud console (or right-click and select Open Link in Incognito Window if you are running the Chrome browser).
The lab spins up resources, and then opens another tab that shows the Sign in page.
Tip: Arrange the tabs in separate windows, side-by-side.
Note: If you see the Choose an account dialog, click Use Another Account.
-
If necessary, copy the Username below and paste it into the Sign in dialog.
{{{user_0.username | "Username"}}}
You can also find the Username in the Lab Details panel.
-
Click Next.
-
Copy the Password below and paste it into the Welcome dialog.
{{{user_0.password | "Password"}}}
You can also find the Password in the Lab Details panel.
-
Click Next.
Important: You must use the credentials the lab provides you. Do not use your Google Cloud account credentials.
Note: Using your own Google Cloud account for this lab may incur extra charges.
-
Click through the subsequent pages:
- Accept the terms and conditions.
- Do not add recovery options or two-factor authentication (because this is a temporary account).
- Do not sign up for free trials.
After a few moments, the Google Cloud console opens in this tab.
Note: To view a menu with a list of Google Cloud products and services, click the Navigation menu at the top-left, or type the service or product name in the Search field.
Activate Google Cloud Shell
Google Cloud Shell is a virtual machine that is loaded with development tools. It offers a persistent 5GB home directory and runs on the Google Cloud.
Google Cloud Shell provides command-line access to your Google Cloud resources.
-
In Cloud console, on the top right toolbar, click the Open Cloud Shell button.

-
Click Continue.
It takes a few moments to provision and connect to the environment. When you are connected, you are already authenticated, and the project is set to your PROJECT_ID. For example:

gcloud is the command-line tool for Google Cloud. It comes pre-installed on Cloud Shell and supports tab-completion.
- You can list the active account name with this command:
gcloud auth list
Output:
Credentialed accounts:
- @.com (active)
Example output:
Credentialed accounts:
- google1623327_student@qwiklabs.net
- You can list the project ID with this command:
gcloud config list project
Output:
[core]
project =
Example output:
[core]
project = qwiklabs-gcp-44776a13dea667a6
Note:
Full documentation of gcloud is available in the
gcloud CLI overview guide
.
Task 1. Create PVs and PVCs
In this task, you create a PVC, which triggers Kubernetes to automatically create a PV.
Connect to the lab GKE cluster
- In Cloud Shell, type the following command to set the environment variable for the zone and cluster name:
export my_region={{{project_0.default_region|Region}}}
export my_cluster=autopilot-cluster-1
- Configure tab completion for the kubectl command-line tool:
source <(kubectl completion bash)
- Configure access to your cluster for kubectl:
gcloud container clusters get-credentials $my_cluster --region $my_region
Create and apply a manifest with a PVC
Most of the time, you don't need to directly configure PV objects or create Compute Engine persistent disks. Instead, you can create a PVC, and Kubernetes automatically provisions a persistent disk for you.
Let's creates a 30 gigabyte PVC called hello-web-disk
that can be mounted as a read-write volume on a single node at a time.
- Create and open a file called
pvc-demo.yaml
with nano using the following command:
nano pvc-demo.yaml
- Once nano has opened, paste the following into the
pvc-demo.yaml
file:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hello-web-disk
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 30Gi
-
Press Ctrl+O, and then press Enter to save your edited file.
-
Press Ctrl+X to exit the nano text editor.
-
To show that you currently have no PVCs, execute the following command:
kubectl get persistentvolumeclaim
Output:
No resources found in default namespace.
- To create the PVC, execute the following command:
kubectl apply -f pvc-demo.yaml
- To show your newly created PVC, execute the following command:
kubectl get persistentvolumeclaim
Partial output:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
hello-web-disk Pending standard-rwo unset 15s
Note: The status will remain pending until after the next step.
Click Check my progress to verify the objective.
Create PVs and PVCs
Task 2. Mount and verify Google Cloud persistent disk PVCs in Pods
In this task, you attach your persistent disk PVC to a Pod. You mount the PVC as a volume as part of the manifest for the Pod.
Mount the PVC to a Pod
Create a manifest file pod-volume-demo.yaml
to deploy an nginx container, attache the pvc-demo-volume
to the Pod and mount that volume to the path /var/www/html
inside the nginx container. Files saved to this directory inside the container will be saved to the persistent volume and persist even if the Pod and the container are shutdown and recreated.
- Create and open a file called
pod-volume-demo.yaml
with nano using the following command:
nano pod-volume-demo.yaml
- Once nano has opened, paste the following into the
pod-volume-demo.yaml
file:
kind: Pod
apiVersion: v1
metadata:
name: pvc-demo-pod
spec:
containers:
- name: frontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: pvc-demo-volume
volumes:
- name: pvc-demo-volume
persistentVolumeClaim:
claimName: hello-web-disk
-
Press Ctrl+O, and then press Enter to save your edited file.
-
Press Ctrl+X to exit the nano text editor.
-
To create the Pod with the volume, execute the following command:
kubectl apply -f pod-volume-demo.yaml
- List the Pods in the cluster:
kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
pvc-demo-pod 0/1 ContainerCreating 0 18s
If you do this quickly after creating the Pod, you will see the status listed as "ContainerCreating" while the volume is mounted before the status changes to "Running".
- To verify the PVC is accessible within the Pod, you must gain shell access to your Pod. To start the shell session, execute the following command:
kubectl exec -it pvc-demo-pod -- sh
- To create a simple text message as a web page in the Pod enter the following commands:
echo Test webpage in a persistent volume!>/var/www/html/index.html
chmod +x /var/www/html/index.html
- Verify the text file contains your message:
cat /var/www/html/index.html
Output:
Test webpage in a persistent volume!
- Enter the following command to leave the interactive shell on the nginx container:
exit
Test the persistence of the PV
You will now delete the Pod from the cluster, confirm that the PV still exists, then redeploy the Pod and verify the contents of the PV remain intact.
- Delete the pvc-demo-pod:
kubectl delete pod pvc-demo-pod
- List the Pods in the cluster:
kubectl get pods
Output:
No resources found in default namespace.
There should be no Pods on the cluster.
- To show your PVC, execute the following command:
kubectl get persistentvolumeclaim
Partial output:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
hello-web-disk Bound pvc-8...34 30Gi RWO standard-rwo unset 22m
Your PVC still exists, and was not deleted when the Pod was deleted.
- Redeploy the pvc-demo-pod:
kubectl apply -f pod-volume-demo.yaml
- List the Pods in the cluster:
kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
pvc-demo-pod 1/1 Running 0 15s
The Pod will deploy and the status will change to "Running" faster this time because the PV already exists and does not need to be created.
- To verify the PVC is still accessible within the Pod, you must gain shell access to your Pod. To start the shell session, execute the following command:
kubectl exec -it pvc-demo-pod -- sh
- To verify that the text file still contains your message execute the following command:
cat /var/www/html/index.html
Output:
Test webpage in a persistent volume!
The contents of the persistent volume were not removed, even though the Pod was deleted from the cluster and recreated.
- Enter the following command to leave the interactive shell on the nginx container:
exit
Click Check my progress to verify the objective.
Mount and verify Google Cloud persistent disk PVCs in Pods
Task 3. Create StatefulSets with PVCs
In this task, you use your PVC in a StatefulSet. A StatefulSet is like a Deployment, except that the Pods are given unique identifiers.
Release the PVC
- Before you can use the PVC with the statefulset, you must delete the Pod that is currently using it. Execute the following command to delete the Pod:
kubectl delete pod pvc-demo-pod
- Confirm the Pod has been removed:
kubectl get pods
Output:
No resources found in default namespace.
Create a StatefulSet
Let's create a manifest file statefulset-demo.yaml
that creates a StatefulSet that includes a LoadBalancer service and three replicas of a Pod containing an nginx container and a volumeClaimTemplate for 30 gigabyte PVCs with the name hello-web-disk
. The nginx containers mount the PVC called hello-web-disk
at /var/www/html
as in the previous task.
- Create and open a file called
statefulset-demo.yaml
with nano using the following command:
nano statefulset-demo.yaml
- Once nano has opened, paste the following into the
statefulset-demo.yaml
file:
kind: Service
apiVersion: v1
metadata:
name: statefulset-demo-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
type: LoadBalancer
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: statefulset-demo
spec:
selector:
matchLabels:
app: MyApp
serviceName: statefulset-demo-service
replicas: 3
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app: MyApp
spec:
containers:
- name: stateful-set-container
image: nginx
ports:
- containerPort: 80
name: http
volumeMounts:
- name: hello-web-disk
mountPath: "/var/www/html"
volumeClaimTemplates:
- metadata:
name: hello-web-disk
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 30Gi
-
Press Ctrl+O, and then press Enter to save your edited file.
-
Press Ctrl+X to exit the nano text editor.
- To create the StatefulSet with the volume, execute the following command:
kubectl apply -f statefulset-demo.yaml
Output:
service "statefulset-demo-service" created
statefulset.apps "statefulset-demo" created
You now have a statefulset running behind a service named statefulset-demo-service
.
Verify the connection of Pods in StatefulSets
- Use "kubectl describe" to view the details of the StatefulSet:
kubectl describe statefulset statefulset-demo
Note the event status at the end of the output. The service and statefulset created successfully.
Normal SuccessfulCreate 10s statefulset-controller
Message: create Claim hello-web-disk-statefulset-demo-0 Pod statefulset-demo-0 in StatefulSet statefulset-demo success
Normal SuccessfulCreate 10s statefulset-controller
Message: create Pod statefulset-demo-0 in StatefulSet statefulset-demo successful
- List the Pods in the cluster:
kubectl get pods
Output:
NAME READY STATUS RESTARTS AGE
statefulset-demo-0 1/1 Running 0 6m
statefulset-demo-1 1/1 Running 0 3m
statefulset-demo-2 1/1 Running 0 2m
- To list the PVCs, execute the following command:
kubectl get pvc
Output:
NAME STATUS VOLUME CAPACITY ACCESS
hello-web-disk Bound pvc-86117ea6-...34 30Gi RWO
hello-web-disk-st...-demo-0 Bound pvc-92d21d0f-...34 30Gi RWO
hello-web-disk-st...-demo-1 Bound pvc-9bc84d92-...34 30Gi RWO
hello-web-disk-st...-demo-2 Bound pvc-a526ecdf-...34 30Gi RWO
The original hello-web-disk is still there and you can now see the individual PVCs that were created for each Pod in the new statefulset Pod.
- Use "kubectl describe" to view the details of the first PVC in the StatefulSet:
kubectl describe pvc hello-web-disk-statefulset-demo-0
Click Check my progress to verify the objective.
Create StatefulSets with PVCs
Task 4. Verify the persistence of Persistent Volume connections to Pods managed by StatefulSets
In this task, you verify the connection of Pods in StatefulSets to particular PVs as the Pods are stopped and restarted.
- To verify that the PVC is accessible within the Pod, you must gain shell access to your Pod. To start the shell session, execute the following command:
kubectl exec -it statefulset-demo-0 -- sh
- Verify that there is no
index.html
text file in the /var/www/html
directory:
cat /var/www/html/index.html
- To create a simple text message as a web page in the Pod enter the following commands:
echo Test webpage in a persistent volume!>/var/www/html/index.html
chmod +x /var/www/html/index.html
- Verify the text file contains your message:
cat /var/www/html/index.html
Output:
Test webpage in a persistent volume!
- Enter the following command to leave the interactive shell on the nginx container:
exit
- Delete the Pod where you updated the file on the PVC:
kubectl delete pod statefulset-demo-0
- List the Pods in the cluster:
kubectl get pods
You will see that the StatefulSet is automatically restarting the statefulset-demo-0
Pod.
Note: You need to wait until the Pod status shows that it is running again.
- Connect to the shell on the new
statefulset-demo-0
Pod:
kubectl exec -it statefulset-demo-0 -- sh
- Verify that the text file still contains your message:
cat /var/www/html/index.html
Output:
Test webpage in a persistent volume!
The StatefulSet restarts the Pod and reconnects the existing dedicated PVC to the new Pod, ensuring that the data for that Pod is preserved.
- Enter the following command to leave the interactive shell on the nginx container:
exit
End your lab
When you have completed your lab, click End Lab. Google Cloud Skills Boost removes the resources you’ve used and cleans the account for you.
You will be given an opportunity to rate the lab experience. Select the applicable number of stars, type a comment, and then click Submit.
The number of stars indicates the following:
- 1 star = Very dissatisfied
- 2 stars = Dissatisfied
- 3 stars = Neutral
- 4 stars = Satisfied
- 5 stars = Very satisfied
You can close the dialog box if you don't want to provide feedback.
For feedback, suggestions, or corrections, please use the Support tab.
Copyright 2022 Google LLC All rights reserved. Google and the Google logo are trademarks of Google LLC. All other company and product names may be trademarks of the respective companies with which they are associated.