<p>I'm having some trouble getting a ReadOnlyMany persistent volume to mount across multiple pods on GKE. Right now it's only mounting on one pod and failing to mount on any others (due to the volume being in use on the first pod), causing the deployment to be limited to one pod.</p>
<p>I suspect the issue is related to the volume being populated from a volume snapshot.</p>
<p>Looking through related questions, I've sanity-checked that
spec.containers.volumeMounts.readOnly = true
and
spec.containers.volumes.persistentVolumeClaim.readOnly = true
which seemed to be the most common fixes for related issues.</p>
<p>I've included the relevant yaml below. Any help would be greatly appreciated!</p>
<p>Here's (most of) the deployment spec:</p>
<pre><code>spec:
  containers:
  - env:
    - name: GOOGLE_APPLICATION_CREDENTIALS
      value: /var/secrets/google/key.json
    image: eu.gcr.io/myimage
    imagePullPolicy: IfNotPresent
    name: monsoon-server-sha256-1
    resources:
      requests:
        cpu: 100m
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /mnt/sample-ssd
      name: sample-ssd
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: gke-cluster-1-default-pool-3d6123cf-kcjo
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 29
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - name: sample-ssd
    persistentVolumeClaim:
      claimName: sample-ssd-read-snapshot-pvc-snapshot-5
      readOnly: true
</code></pre>
<p>The storage class (which is also the default storage class for this cluster):</p>
<pre><code>apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: sample-ssd
provisioner: pd.csi.storage.gke.io
volumeBindingMode: Immediate
parameters:
    type: pd-ssd
</code></pre>
<p>The PVC:</p>
<pre><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sample-ssd-read-snapshot-pvc-snapshot-5
spec:
  storageClassName: sample-ssd
  dataSource:
    name: sample-snapshot-5
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 20Gi
</code></pre>

Mike Perrow
<p>Google Engineers are aware about this issue.</p>
<p>More details about this issue you can find in <a href="https://github.com/kubernetes/kubernetes/issues/70505" rel="nofollow noreferrer">issue report</a> and <a href="https://github.com/kubernetes-csi/external-provisioner/pull/469" rel="nofollow noreferrer">pull request</a> on GitHub.</p>
<p>There's a <strong>temporary workaround</strong> if you're trying to provision a PD from a snapshot and make it ROX:</p>
<ol>
<li>Provision a PVC with datasource as RWO;</li>
</ol>
<blockquote>
<p>It will create a new Compute Disk with the content of the source disk<br />
2. Take the PV that was provisioned and copy it to a new PV that's ROX according to the <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/readonlymany-disks" rel="nofollow noreferrer">docs</a></p>
</blockquote>
<p>You can execute it with the following commands:</p>
<h3>Step 1</h3>
<blockquote>
<p>Provision a PVC with datasource as RWO;</p>
</blockquote>
<pre><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: workaround-pvc
spec:
  storageClassName: ''
  dataSource:
    name: sample-ss
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
</code></pre>
<p>You can check the <strong>disk name</strong> with command:</p>
<p><code>kubectl get pvc</code> and check the <code>VOLUME</code> column. This is the <code>disk_name</code></p>
<h3>Step 2</h3>
<blockquote>
<p>Take the PV that was provisioned and copy it to a new PV that's ROX</p>
</blockquote>
<p>As mentioned in the  <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/readonlymany-disks" rel="nofollow noreferrer">docs</a> you need to create another disk using the previous disk (created in step 1) as source:</p>
<pre><code># Create a disk snapshot:
gcloud compute disks snapshot &lt;disk_name&gt;

# Create a new disk using snapshot as source
gcloud compute disks create pvc-rox --source-snapshot=&lt;snapshot_name&gt;
</code></pre>
<p>Create a new PV and PVC ReadOnlyMany</p>
<pre><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-readonly-pv
spec:
  storageClassName: ''
  capacity:
    storage: 20Gi
  accessModes:
    - ReadOnlyMany
  claimRef:
    namespace: default
    name: my-readonly-pvc
  gcePersistentDisk:
    pdName: pvc-rox
    fsType: ext4
    readOnly: true
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-readonly-pvc
spec:
  storageClassName: ''
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 20Gi
</code></pre>
<p>Add the <code>readOnly: true</code> on your <code>volumes</code> and <code>volumeMounts</code> as mentioned <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/readonlymany-disks#using_the_persistentvolumeclaim_in_a_pod" rel="nofollow noreferrer">here</a></p>
<pre><code>readOnly: true
</code></pre>
