<p>I am trying to use gcePersistentDisk as ReadOnlyMany so that my pods on multiple nodes can read the data on this disk. Following the documentation <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/readonlymany-disks" rel="noreferrer">here</a> for the same. </p>

<p>To create and later format the gce Persistent Disk, I have followed the instructions in the documentation <a href="https://cloud.google.com/compute/docs/disks/add-persistent-disk" rel="noreferrer">here</a>. Following this doc, I have sshed into one of the nodes and have formatted the disk. See below the complete error and also the other yaml files.</p>

<p><strong>kubectl describe pods -l podName</strong></p>

<pre><code>Name:               punk-fly-nodejs-deployment-5dbbd7b8b5-5cbfs
Namespace:          default
Priority:           0
PriorityClassName:  &lt;none&gt;
Node:               gke-mycluster-default-pool-b1c1d316-d016/10.160.0.12
Start Time:         Thu, 25 Apr 2019 23:55:38 +0530
Labels:             app.kubernetes.io/instance=punk-fly
                    app.kubernetes.io/name=nodejs
                    pod-template-hash=1866836461
Annotations:        kubernetes.io/limit-ranger=LimitRanger plugin set: cpu request for container nodejs
Status:             Pending
IP:
Controlled By:      ReplicaSet/punk-fly-nodejs-deployment-5dbbd7b8b5
Containers:
  nodejs:
    Container ID:
    Image:          rajesh12/smartserver:server
    Image ID:
    Port:           3002/TCP
    Host Port:      0/TCP
    State:          Waiting
      Reason:       ContainerCreating
    Ready:          False

    Restart Count:  0
    Requests:
      cpu:  100m
    Environment:
      MYSQL_HOST:           mysqlservice
      MYSQL_DATABASE:       app
      MYSQL_ROOT_PASSWORD:  password
    Mounts:
      /usr/src/ from helm-vol (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-jpkzg (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True
Volumes:
  helm-vol:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  my-readonly-pvc
    ReadOnly:   true
  default-token-jpkzg:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-jpkzg
    Optional:    false
QoS Class:       Burstable
Node-Selectors:  &lt;none&gt;
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason                  Age               From                                               Message
  ----     ------                  ----              ----                                               -------
  Normal   Scheduled               2m                default-scheduler                                  Successfully assigned default/punk-fly-nodejs-deployment-5dbbd7b8b5-5cbfs to gke-mycluster-default-pool-b1c1d316-d016
  Normal   SuccessfulAttachVolume  1m                attachdetach-controller                            AttachVolume.Attach succeeded for volume "pvc-9c796180-677e-11e9-ad35-42010aa0000f"
  Warning  FailedMount             10s (x8 over 1m)  kubelet, gke-mycluster-default-pool-b1c1d316-d016  MountVolume.MountDevice failed for volume "pvc-9c796180-677e-11e9-ad35-42010aa0000f" : failed to mount unformatted volume as read only
  Warning  FailedMount             0s                kubelet, gke-mycluster-default-pool-b1c1d316-d016  Unable to mount volumes for pod "punk-fly-nodejs-deployment-5dbbd7b8b5-5cbfs_default(86293044-6787-11e9-ad35-42010aa0000f)": timeout expired waiting for volumes to attach or mount for pod "default"/"punk-fly-nodejs-deployment-5dbbd7b8b5-5cbfs". list of unmounted volumes=[helm-vol]. list of unattached volumes=[helm-vol default-token-jpkzg]
</code></pre>

<p><strong>readonly_pv.yaml</strong></p>

<pre><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-readonly-pv
spec:
  storageClassName: ""
  capacity:
    storage: 1G
  accessModes:
    - ReadOnlyMany
  gcePersistentDisk:
    pdName: mydisk0
    fsType: ext4
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-readonly-pvc
spec:
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 1G
</code></pre>

<p><strong>deployment.yaml</strong></p>

<pre><code>  volumes:
    - name: helm-vol
      persistentVolumeClaim:
        claimName: my-readonly-pvc
        readOnly: true
  containers:
    - name: {{ .Values.app.backendName }}
      image: "{{ .Values.image.repository }}:{{ .Values.image.tagServer }}"
      imagePullPolicy: {{ .Values.image.pullPolicy }}
      env:
      - name: MYSQL_HOST
        value: mysqlservice
      - name: MYSQL_DATABASE
        value: app
      - name: MYSQL_ROOT_PASSWORD
        value: password
      ports:
        - name: http-backend
          containerPort: 3002
      volumeMounts:
        - name: helm-vol
          mountPath: /usr/src/
</code></pre>

<p>It sounds like your <a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims" rel="nofollow noreferrer">PVC</a> is dynamically provisioning a new volume that is not formatted with the <a href="https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/" rel="nofollow noreferrer">default StorageClass</a></p>

<p>It could be that your Pod is being created in a different availability from where you have the <a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistent-volumes" rel="nofollow noreferrer">PV</a> provisioned. The gotcha with having multiple Pod readers for the gce volume is that the Pods always have to be in the same availability zone.</p>

<p>Some options:</p>

<ul>
<li><p>Simply create and format the <a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistent-volumes" rel="nofollow noreferrer">PV</a> on the same availability zone where your node is.</p></li>
<li><p>When you define your PV you could specify <a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#node-affinity" rel="nofollow noreferrer">Node Affinity</a> to make sure it always gets assigned to a specific node.</p></li>
<li><p>Define a <a href="https://kubernetes.io/docs/concepts/storage/storage-classes/" rel="nofollow noreferrer">StorageClass</a> that specifies the filesystem</p>

<pre><code>kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: mysc
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  fsType: ext4
</code></pre>

<p>And then use it in your PVC:</p>

<pre><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 1G
  storageClassName: mysc
</code></pre>

<p>The volume will be automatically provisioned and formatted.</p></li>
</ul>
