<p>I am trying to understand the Access Modes of Kubernetes <code>PersistentVolumes</code>.</p>
<p>As per the Kubernetes docs, the access modes are:</p>
<pre><code>ReadWriteOnce -- the volume can be mounted as read-write by a single node
ReadOnlyMany -- the volume can be mounted read-only by many nodes
ReadWriteMany -- the volume can be mounted as read-write by many nodes
</code></pre>
<p>Volume Plugin <code>HostPath</code> supports <code>ReadWriteOnce</code></p>
<p>I have a K8s cluster of <code>1 controlplane and 1 worker1 node</code> I deployed two Pods one to each node, pv, pvc in the same <code>namespace</code> as per the below config. Both the pods running on different nodes are able to Read-Write to the local path <code>/tmp/test</code>.</p>
<p>As per my understanding, this should not happen. Only one node should be able to ReadWrite and another node should only be able to Read.</p>
<p>Can someone explain what is happening here, if possible please provide me with examples/blogs to see the differences between <code>RWO, RWX, ROX</code>? Most of the blogs, just talk about the PV, PVC and access modes in brief.</p>
<pre><code>apiVersion: v1
kind: Pod
metadata:
  name: pod2
spec:
  nodeName: controlplane
  containers:
  - image: nginx
    name: pod2
    volumeMounts:
      - name: vol
        mountPath: /usr/share/nginx/html
  volumes:
  - name: vol
    persistentVolumeClaim:
      claimName: pvc
---
apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  nodeName: worker1
  containers:
  - image: nginx
    name: pod1
    volumeMounts:
      - name: vol
        mountPath: /usr/share/nginx/html
  volumes:
  - name: vol
    persistentVolumeClaim:
      claimName: pvc
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /tmp/test
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
</code></pre>

<ol>
<li><p>please note that you should not run pods on control plane, so you should replace <code>nodeName: controlplane</code> with <code>nodeName: worker2</code> in you yaml file. Usually you need to use <code>toleration</code> to run pod on control plane, because it has a taint preventing to run regular pod on it...</p>
</li>
<li><p>I tried your yaml on Google Kubernetes Engine (gke), I had to replace <code>nodeName</code> fields to make it works:</p>
</li>
</ol>
<pre><code>diff example.yaml example-gke.yaml 
6c6
&lt;   nodeName: controlplane
---
&gt;   nodeName: gke-qserv-dev-worker-pool-a64a-01bc5238-3zl9 
23c23
&lt;   nodeName: worker1
---
&gt;   nodeName: gke-qserv-dev-worker-pool-a64a-01bc5238-23t3 
</code></pre>
<p>And as you can see, k8s refuses to create <code>pod2</code>:</p>
<pre><code>kubectl get pods
NAME                                   READY   STATUS              RESTARTS   AGE
pod1                                   1/1     Running             0          6m27s
pod2                                   0/1     ContainerCreating   0          6m27s
</code></pre>
<p>Here is the message I get:</p>
<pre><code>kubectl describe pod pod2 | tail -n 1
  Warning  FailedAttachVolume  7m28s                 attachdetach-controller                                Multi-Attach error for volume &quot;pvc-2fb657ce-4678-4e92-9f64-e4b46b9a3ec7&quot; Volume is already used by pod(s) pod1
</code></pre>
<p>So, as you can see you cannot mount a PV on two different pods running on two different nodes. So what you get on your side is not a regular k8s behaviour. It could be a side-effect of your storage class, particularly if you use <code>minikube</code> or <code>kind</code>.</p>
