PV PVC's on GKE clusters
The steps to create Storage objects, in general:
- Create a Disk
- Create a Persistent Volume (PV) on the disk.
- Create a Persistent Volume Claim (PVC) against the Persistent Volume (PV).
Note: In GKE, it is also possible to create PVC's directly using those default Storage Classes (without creating disks & PV's).
Set the "project" property by:
gcloud config set project handy-freedom-363504
Create Disks:
gcloud compute disks create gke-pv --zone=us-west4-b --size=11GB
WARNING: You have selected a disk size of under [200GB]. This may result in poor I/O performance. For more information, see: https://developers.google.com/compute/docs/disks#performance.
Created [https://www.googleapis.com/compute/v1/projects/handy-freedom-363504/zones/us-west4-b/disks/gke-pv].
NAME: gke-pv
ZONE: us-west4-b
SIZE_GB: 11
TYPE: pd-standard
STATUS: READY
New disks are unformatted. You must format and mount a disk before it
can be used. You can find instructions on how to do this at:
https://cloud.google.com/compute/docs/disks/add-persistent-disk#formatting
List Disks:
gcloud compute disks list
apiVersion: v1
kind: PersistentVolume
metadata:
name: app-storage
spec:
storageClassName: "apps"
capacity:
storage: 10
accessModes:
- ReadWriteOnce
claimRef:
namespace: default
name: app-storage-claim
gcePersistentDisk:
pdName: gke-pv
fsType: ext4
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-storage-claim
spec:
storageClassName: "apps"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
app-storage 10 RWO Retain Bound default/app-storage-claim apps 104s
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
app-storage-claim Bound app-storage 10 RWO apps 3m5s
List the existing Storage Classes Provided by GKE
kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
premium-rwo pd.csi.storage.gke.io Delete WaitForFirstConsumer true 9h
standard (default) kubernetes.io/gce-pd Delete Immediate true 9h
standard-rwo pd.csi.storage.gke.io Delete WaitForFirstConsumer true 9h
Use one of the above in the below StatefulSet. With the volumeClaimTemplates key name, you can request PVC's from the storage class dynamically.
It will create as many PVC's as required automatically depending upon the requested number of "replicas" for the statefulset.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
replicas: 1
serviceName: mysql
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mysql
image: mysql:5.6
ports:
- name: tpc
protocol: TCP
containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: root
volumeMounts:
- name: mysql-pvc
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-pvc
spec:
storageClassName: standard-rwo
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
This has created the below PVC now:
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pvc-mysql-0 Bound pvc-377f5d0b-988a-4cc2-9e78-15d85b31ad91 5Gi RWO standard-rwo 19s
Note:
-
The name of the PVC is static. It includes, "the template name provided for the PVC","Statefuset Name" and ending with the stetefulset' ordinal#.
-
Deleting the PVC will also delete the PV it is based on.
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-377f5d0b-988a-4cc2-9e78-15d85b31ad91 5Gi RWO Delete Bound default/mysql-pvc-mysql-0 standard-rwo 2m8s
It is to demonstrate how flexible this "volumeClaimTemplates" feature is. Scaling the replicas of the Statefulset (from 1 to 2):
kubectl scale statefulset mysql --replicas 2
It does NOT need to have PV/PVC's pre-created or anything. The required PVC is created automatically.
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pvc-mysql-0 Bound pvc-377f5d0b-988a-4cc2-9e78-15d85b31ad91 5Gi RWO standard-rwo 5m12s
mysql-pvc-mysql-1 Bound pvc-c49216b6-ee39-43be-96b9-e81e97b2258f 5Gi RWO standard-rwo 46s
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-377f5d0b-988a-4cc2-9e78-15d85b31ad91 5Gi RWO Delete Bound default/mysql-pvc-mysql-0 standard-rwo 5m56s
pvc-c49216b6-ee39-43be-96b9-e81e97b2258f 5Gi RWO Delete Bound default/mysql-pvc-mysql-1 standard-rwo 90s
** (3) Create a PVC with the default Storage class - "pd-standard"**
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: webapps-storage
spec:
storageClassName: "standard"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-7b439c6f-a4d0-484f-9232-dce0089a2988 5Gi RWO Delete Bound default/webapps-storage standard 9s
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
webapps-storage Bound pvc-7b439c6f-a4d0-484f-9232-dce0089a2988 5Gi RWO standard 8s
Using the PVC in a Pod
apiVersion: v1
kind: Pod
metadata:
name: nginx-app-pod
spec:
volumes:
- name: app-storage
persistentVolumeClaim:
claimName: webapps-storage
containers:
- name: nginx-app-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: app-storage