Per the documentation:
The control plane can bind PersistentVolumeClaims to matching PersistentVolumes in the cluster. However, if you want a PVC to bind to a specific PV, you need to pre-bind them.
By specifying a PersistentVolume in a PersistentVolumeClaim, you declare a binding between that specific PV and PVC. If the PersistentVolume exists and has not reserved PersistentVolumeClaims through its claimRef field, then the PersistentVolume and PersistentVolumeClaim will be bound.
The binding happens regardless of some volume matching criteria, including node affinity. The control plane still checks that storage class, access modes, and requested storage size are valid.
Even though StatefulSets are the resource used to manage stateful applications, I have modified the pv/pvc example they provide into a Deployment example (with nginx, compatible with at least minikube, please comment/edit compatibility with cloud providers):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-pvc
spec:
volumeName: foo-pv
storageClassName: "standard"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "1Gi"
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: foo-pv
# name: bar-pv
spec:
storageClassName: "standard"
capacity:
storage: "1Gi"
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/test/"
# claimRef:
# name: foo-pvc
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: foo-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- name: nginx-storage
mountPath: /test/
volumes:
- name: nginx-storage
persistentVolumeClaim:
claimName: foo-pvc
So, to elaborate on the documentation, if you fill in the PV's spec.claimRef.name (as foo-pvc or anything) your PVC will sit pending and won't bind. (I left it commented out.) You will notice however, that if you edit it after creating the PV like above, with kubectl edit pv foo-pv
, that it is set by the control plane as such.
Also, i left an alternate PV metadata.name (commented out), you can switch the comment line and see as well that it will not bind if the value doesn't match what the PVC specified with spec.volumeName.
Additional note: I found that if you have not created /mnt/test before deploying the above, it will create that folder when you write to it from inside the container.