<p>I have a simple deployment with 2 replicas.</p>

<p>I would like that each of the replicas have same storage folder in them (shared application upload folder)</p>

<p>I've been playing with claims and volumes, but haven't got the edge still, so asking for a quick help / example.</p>

<pre><code>apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: 'test-tomcat'
      labels:
        app: test-tomcat
    spec:
      selector:
        matchLabels:
          app: test-tomcat
      replicas: 3
      template:
        metadata:
          name: 'test-tomcat'
          labels:
            app: test-tomcat
        spec:
          volumes:
          - name: 'data'
            persistentVolumeClaim:
              claimName: claim
          containers:
          - image: 'tomcat:9-alpine'
            volumeMounts:
            - name: 'data'
              mountPath: '/app/data'
            imagePullPolicy: Always
            name: 'tomcat'
            command: ['bin/catalina.sh', 'jpda', 'run']
</code></pre>

<p><br/></p>

<pre><code>kind: PersistentVolume
apiVersion: v1
metadata:
  name: volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 2Gi
  accessModes:
  - ReadWriteMany
  hostPath:
    path: "/mnt/data"
</code></pre>

<p><br/></p>

<pre><code>kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: claim
spec:
  storageClassName: manual
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
</code></pre>

<p>First of all, you need to decide what type of a Persistent Volume to use. Here are several examples of an on-premise cluster:</p>

<ul>
<li><p><strong>HostPath</strong> - local Path on a Node. Therefore, if the first Pod is located on Node1 and the second is on Node2, storages will be different. To resolve this problem, you can use one of the following options. Example of a HostPath:</p>

<pre><code>kind: PersistentVolume
apiVersion: v1
metadata:
  name: example-pv
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 3Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
</code></pre></li>
<li><p><strong>NFS</strong> - PersistentVolume of that type uses Network File System. NFS is a distributed file system protocol that allows you to mount remote directories on your servers. You need to install NFS server before using the NFS in Kubernetes; here is the example <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nfs-mount-on-ubuntu-16-04" rel="noreferrer">How To Set Up an NFS Mount on Ubuntu</a>. Example in Kubernetes:</p>

<pre><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 3Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp
    server: 172.17.0.2
</code></pre></li>
<li><p><strong>GlusterFS</strong> - GlusterFS is a scalable, distributed file system that aggregates disk storage resources from multiple servers into a single global namespace. As for the NFS, you need to install GlusterFS before using it in Kubernetes; here is the <a href="https://github.com/gluster/gluster-kubernetes" rel="noreferrer">link</a> with instructions, and <a href="https://docs.okd.io/latest/install_config/storage_examples/gluster_example.html" rel="noreferrer">one</a> more with the sample. Example in Kubernetes:</p>

<pre><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv 
  annotations:
    pv.beta.kubernetes.io/gid: "590" 
spec:
  capacity:
    storage: 3Gi 
  accessModes: 
    - ReadWriteMany
  glusterfs:
    endpoints: glusterfs-cluster 
    path: myVol1 
    readOnly: false
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: Service
metadata:
  name: glusterfs-cluster 
spec:
  ports:
  - port: 1
---
apiVersion: v1
kind: Endpoints
metadata:
  name: glusterfs-cluster 
subsets:
  - addresses:
      - ip: 192.168.122.221 
    ports:
      - port: 1 
  - addresses:
      - ip: 192.168.122.222 
    ports:
      - port: 1 
  - addresses:
      - ip: 192.168.122.223 
    ports:
      - port: 1 
</code></pre></li>
</ul>

<p>After creating a PersistentVolume, you need to create a PersistaentVolumeClaim. A PersistaentVolumeClaim is a resource used by Pods to request volumes from the storage. After you create the PersistentVolumeClaim, the Kubernetes control plane looks for a PersistentVolume that satisfies the claim’s requirements. Example:</p>

<pre><code>kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: example-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
</code></pre>

<p>And the last step, you need to configure a Pod to use the PersistentVolumeClaim. Here is the example:</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: 'test-tomcat'
  labels:
    app: test-tomcat
spec:
  selector:
    matchLabels:
      app: test-tomcat
  replicas: 3
  template:
    metadata:
      name: 'test-tomcat'
      labels:
        app: test-tomcat
    spec:
      volumes:
      - name: 'data'
        persistentVolumeClaim:
          claimName: example-pv-claim #name of the claim should be the same as defined before
      containers:
      - image: 'tomcat:9-alpine'
        volumeMounts:
        - name: 'data'
          mountPath: '/app/data'
        imagePullPolicy: Always
        name: 'tomcat'
        command: ['bin/catalina.sh', 'jpda', 'run']
</code></pre>
