Directly specifying a persistent volume in a configuration file makes a tight couple with a particular infrastructure. For the preceding example (tomcat-log volume), pdName is gce-pd-1 and Volume type is gcePersistentDisk. From a container management point of view, the pod definition shouldn't be locked into the specific environment because the infrastructure could be different based on the environment. The ideal pod definition should be flexible or abstract the actual infrastructure and specify only volume name and mount point.
Consequently, Kubernetes provides an abstraction layer that associates the pod with the persistent volume, which is called the Persistent Volume Claim (PVC). This allows us to decouple from the infrastructure. The Kubernetes administrator just needs to pre-allocate the size of the persistent volume in advance. Then Kubernetes will bind the persistent volume and the PVC as follows:
The following example is a definition of a pod that uses a PVC; let's reuse the previous example (gce-pd-1) to register with Kubernetes first:
$ cat pv-gce-pd-1.yml
apiVersion: "v1"
kind: "PersistentVolume"
metadata:
name: pv-1
spec:
storageClassName: "my-10g-pv-1"
capacity:
storage: "10Gi"
accessModes:
- "ReadWriteOnce"
gcePersistentDisk:
fsType: "ext4"
pdName: "gce-pd-1"
$ kubectl create -f pv-gce-pd-1.yml
persistentvolume/pv-1 created
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-1 10Gi RWO Retain Available my-10g-pv-1 11s
Note that we assign storageClassName as my-10g-pv-1, as an identifier that the PVC can bind to by specifying the same name.
Next, we create a PVC that associates with the persistent volume (pv-1).
//create PVC specify storageClassName as "my-10g-pv-1"
$ cat pvc-1.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-1
spec:
storageClassName: "my-10g-pv-1"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
$ kubectl create -f pvc-1.yml
persistentvolumeclaim/pvc-1 created
//check PVC status is "Bound"
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-1 Bound pv-1 10Gi RWO my-10g-pv-1 7s
//check PV status is also "Bound"
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-1 10Gi RWO Retain Bound default/pvc-1 my-10g-pv-1 2m
Now the tomcat setting has been decoupled from the GCE persistent volume, and bound to the abstracted volume, pvc-1:
$ cat tomcat-pvc.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
spec:
replicas: 1
selector:
matchLabels:
run: tomcat
template:
metadata:
labels:
run: tomcat
spec:
containers:
- image: tomcat
name: tomcat
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /usr/local/tomcat/logs
name: tomcat-log
volumes:
- name: tomcat-log
persistentVolumeClaim:
claimName: "pvc-1"