I'm working on a bare-metal inst of k8s, and am trying out local persistent volume using k8s v1.14. The purpose is to allow me to create an HA postgres deployment using postgres-operator. Since I'm on bare metal, I cannot make use of dynamic PVCs, as seems to be normal in the tutorials.
To begin with, I created some PVs bound to manually created volumes on the host nodes. The PVs are assigned, using nodeAffinity
, to specific nodes. i.e. primary-vol
PV is assigned to node1
, and replica-vol-1
is assigned to node2
and so on.
I am then binding my pod to the PV using a PVC as documented here.
What I've found is that the k8s scheduler has placed my pod (which is bound to a PV on node1
) on node2
rather than node1
as I expected.
Is there a way, using affinity on the pod, to ensure that the pod is created on the same node as the PV it is bound to?
EDIT: to simplify the question (with apologies to artists and architects everywhere)
How can the pod know what node the PV is assigned to, when it doesn't even know what PV it is bound to?
Yes, you can achieve it using the claimRef in your PV definition. By using claimRef
in your PV, you're binding a PVC with specific name to that PV and you can use that PVC name in your pod definition in persistentVolumeClaim
.
You should have PV definition like following:
{
"kind": "PersistentVolume",
"apiVersion": "v1",
"metadata": {
"name": "pv-data-vol-0",
"labels": {
"type": "local"
}
},
"spec": {
"capacity": {
"storage": "10Gi"
},
"accessModes": [
"ReadWriteOnce"
],
"storageClassName": "local-storage",
"local": {
"path": "/prafull/data/pv-0"
},
"claimRef": {
"namespace": "default",
"name": "data-test-sf-0"
},
"nodeAffinity": {
"required": {
"nodeSelectorTerms": [
{
"matchExpressions": [
{
"key": "kubernetes.io/hostname",
"operator": "In",
"values": [
"ip-10-0-1-46.ec2.internal"
]
}
]
}
]
}
}
}
}
In the above json file, the claimRef
, name
should be the name of the PVC you want to bind that PV to and namespace
should be the namespace in which the PVC
reside.
Note: namespace
is mandatory field as PV's are independent of namespace and PVC are bound in namespace and hence PV should know in which namespace it should look for PVC.
So once you're able to bind the specific PV to specific PVC, you can bind that specific PVC to the specific POD and hence that pod will always come on the same node where PV is present.
For reference, please have a look at my following answer:
Is it possible to mount different pods to the same portion of a local persistent volume?
Hope this helps