<p>After learning that we should have used a <code>StatefulSet</code> instead of a <code>Deployment</code> in order to be able to attach the same persistent volume to multiple pods and especially pods on different nodes, I tried changing our config accordingly.</p>

<p>However, even when using the same name for the volume claim as before, it seems to be creating an entirely new volume instead of using our existing one, hence the application loses access to the existing data when run as a <code>StatefulSet</code>.</p>

<p>Here's the volume claim part of our current <code>Deployment</code> config:</p>

<pre><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gitea-server-data
  labels:
    app: gitea
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
</code></pre>

<p>This results in a claim with the same name.</p>

<p>And here's the template for the <code>StatefulSet</code>:</p>

<pre><code>  volumeClaimTemplates:
    - metadata:
        name: gitea-server-data
        labels:
          app: gitea
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 20Gi
</code></pre>

<p>This results in new claims for every pod, with the pod name and an ID per claim, like e.g. <code>gitea-server-data-gitea-server-0</code>.</p>

<p>The new claims are now using a new volume instead of the existing one. So I tried specifying the existing volume explicitly, like so:</p>

<pre><code>  volumeClaimTemplates:
    - metadata:
        name: gitea-server-data
        labels:
          app: gitea
      spec:
        accessModes:
          - ReadWriteOnce
        volumeName: pvc-c87ff507-fd77-11e8-9a7b-420101234567
        resources:
          requests:
            storage: 20Gi
</code></pre>

<p>However, this results in pods failing to be scheduled and the new claim being "pending" indefinitely:</p>

<blockquote>
  <p>pod has unbound immediate PersistentVolumeClaims (repeated times)</p>
</blockquote>

<p>So the question is: how can we migrate the volume claim(s) in a way that allows us to use the existing persistent volume and access the current application data from a new <code>StatefulSet</code> instead of the current <code>Deployment</code>?</p>

<p>(In case it is relevant, we are using Kubernetes on GKE.)</p>

<p>In StatefulSet, when you try to use PVC to store your data, you actually define your PVC by using <code>volumeClaimTemplates</code> like:</p>

<pre><code>volumeClaimTemplates:
    - metadata:
        name: gitea-server-data
        labels:
          app: gitea
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 20Gi
</code></pre>

<p>In this scenario, the following things could happen:</p>

<ul>
<li>If the StatefulSet name is <code>gitea-server</code> and the replica is <code>1</code> then
the only pod of the StatefulSet will use the PVC named <code>gitea-server-data-gitea-server-0</code>(if already exist in the cluster) or create a new one named <code>gitea-server-data-gitea-server-0</code>(if doesn't exist in the cluster).</li>
<li>If the StatefulSet name is <code>gitea-server</code> and the replica is <code>2</code> then
the two Pod of the StatefulSet will use the PVCs named <code>gitea-server-data-gitea-server-0</code> and <code>gitea-server-data-gitea-server-1</code> repectively(if already exist in the cluster) or create new PVCs named <code>gitea-server-data-gitea-server-0</code> an <code>gitea-server-data-gitea-server-1</code>(if doesn't exist in the cluster) and so on.</li>
</ul>

<p>Generally, in StatefulSet, generated PVC name follow the convention:</p>

<pre><code>&lt;volumeClaimTemplates name&gt;-&lt;StatefulSet name&gt;-&lt;Pod ordinal&gt;
</code></pre>

<p>Now, if you create a PVC named <code>gitea-server-data-gitea-server-0</code>and the other things looks like:</p>

<pre><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gitea-server-data
  labels:
    app: gitea
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
</code></pre>

<p>then after creating the PVC, if you try to create a StatefulSet with replica <code>1</code> and with the above configuration that defined in <code>volumeClaimTemplates</code> then the SatefulSet will use this PVC(<code>gitea-server-data-gitea-server-0</code>).</p>

<p>You can also use this PVC in other workload(Like Deployment) by specifying the field <code>spec.accessmodes</code> as <code>ReadWriteMany</code>.</p>
