<p>I want to mount an Azure Shared Disk to the multiple deployments/nodes based on this:
<a href="https://learn.microsoft.com/en-us/azure/virtual-machines/disks-shared" rel="nofollow noreferrer">https://learn.microsoft.com/en-us/azure/virtual-machines/disks-shared</a></p>
<p>So, I created a shared disk in Azure Portal and when trying to mount it to deployments in Kubernetes I got an error:</p>
<blockquote>
<p>&quot;Multi-Attach error for volume &quot;azuredisk&quot; Volume is already used by pod(s)...&quot;</p>
</blockquote>
<p>Is it possible to use Shared Disk in Kubernetes? If so how?
Thanks for tips.</p>

<p><strong><a href="https://azure.microsoft.com/en-us/blog/announcing-the-general-availability-of-azure-shared-disks-and-new-azure-disk-storage-enhancements/" rel="noreferrer">Yes, you can</a></strong>, and the capability is GA.</p>
<p>An Azure Shared Disk can be mounted as ReadWriteMany, which means you can mount it to multiple nodes and pods. It requires the <a href="https://learn.microsoft.com/en-us/azure/aks/azure-disk-csi#shared-disk" rel="noreferrer">Azure Disk CSI driver</a>, and the caveat is that currently only Raw Block volumes are supported, thus the application is responsible for managing the control of writes, reads, locks, caches, mounts, and fencing on the shared disk, which is exposed as a raw block device. This means that you mount the raw block device (disk) to a pod container as a <code>volumeDevice</code> rather than a <code>volumeMount</code>.</p>
<p><a href="https://github.com/kubernetes-sigs/azuredisk-csi-driver/tree/master/deploy/example/sharedisk" rel="noreferrer">The documentation examples</a> mostly points to how to create a Storage Class to dynamically provision the static Azure Shared Disk, but I have also created one statically and mounted it to multiple pods on different nodes.</p>
<h3>Dynamically Provision Shared Azure Disk</h3>
<ol>
<li>Create Storage Class and PVC</li>
</ol>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-csi
provisioner: disk.csi.azure.com
parameters:
  skuname: Premium_LRS  # Currently shared disk only available with premium SSD
  maxShares: &quot;2&quot;
  cachingMode: None  # ReadOnly cache is not available for premium SSD with maxShares&gt;1
reclaimPolicy: Delete
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc-azuredisk
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 256Gi  # minimum size of shared disk is 256GB (P15)
  volumeMode: Block
  storageClassName: managed-csi
</code></pre>
<ol start="2">
<li>Create a deployment with 2 replicas and specify volumeDevices, devicePath in Spec</li>
</ol>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: deployment-azuredisk
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
      name: deployment-azuredisk
    spec:
      containers:
        - name: deployment-azuredisk
          image: mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine
          volumeDevices:
            - name: azuredisk
              devicePath: /dev/sdx
      volumes:
        - name: azuredisk
          persistentVolumeClaim:
            claimName: pvc-azuredisk
</code></pre>
<h3>Use a Statically Provisioned Azure Shared Disk</h3>
<p>Using an Azure Shared Disk that has been provisioned through ARM, Azure Portal, or through the Azure CLI.</p>
<ol>
<li>Define a PersistentVolume (PV) that references the DiskURI and DiskName:</li>
</ol>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: azuredisk-shared-block
spec:
  capacity:
    storage: &quot;256Gi&quot; # 256 is the minimum size allowed for shared disk
  volumeMode: Block # PV and PVC volumeMode must be 'Block'
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  azureDisk:
    kind: Managed
    diskURI: /subscriptions/&lt;subscription&gt;/resourcegroups/&lt;group&gt;/providers/Microsoft.Compute/disks/&lt;disk-name&gt;
    diskName: &lt;disk-name&gt;
    cachingMode: None # Caching mode must be 'None'
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-azuredisk-managed
spec:
  resources:
    requests:
      storage: 256Gi
  volumeMode: Block
  accessModes:
    - ReadWriteMany
  volumeName: azuredisk-shared-block # The name of the PV (above)
</code></pre>
<p>Mounting this PVC is the same for both dynamically and statically provisioned shared disks. Reference the deployment above.</p>
