<p>I am using Google Kubernetes Engine and would like my <code>StatefulSet</code> to use my previously created disk <code>my-app-disk</code> instead of dynamically creating new persistent disk for each replica in the set. My config is as follows:</p>

<p><code>PersistentVolume</code> yaml:</p>

<pre><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-app-data
  labels:
    app: my-app
spec:
  capacity:
    storage: 60Gi
  accessModes:
    - ReadWriteOnce
  gcePersistentDisk:
    pdName: my-app-disk
    fsType: ext4
</code></pre>

<p><code>PersistentVolumeClaim</code> yaml:</p>

<pre><code>apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-app-data
  labels:
    app: my-app
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 60Gi
  selector:
    matchLabels:
      app: my-app
</code></pre>

<p><code>StatefulSet</code> yaml:</p>

<pre><code>apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
  name: my-stateful-set
spec:
  serviceName: my-stateful-set
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: gcr.io/projectname/my-app:0.0.3
        ports:
        - containerPort: 80
          name: http
        volumeMounts:
        - name: my-app-data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: my-app-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 50Gi
</code></pre>

<p><code>StatefulSet</code> will create it's own <code>PersistentVolumeClaim</code> for each pod so you don't have to create one yourself. A <code>PersistentVolume</code> and a <code>PersistentVolumeClaim</code> will bind exclusively <a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#binding" rel="noreferrer">one to one</a>. Your PVC is binding to your volume so any PVCs created by the <code>StatefulSet</code> can't bind to your volume so it won't be used.</p>

<p>In your case your <code>PersistentVolume</code> and the <code>StatefulSet</code> below should do the trick. Make sure to delete the <code>PersistentVolumeClaim</code> you created so that it's not bound to your <code>PersistentVolume</code>. Also, make sure the storage class name is set properly below on your PV and in <code>volumeClaimTemplates</code> on your <code>StatefulSet</code> below or the PVC made by the <code>StatefulSet</code> may not bind to your volume.</p>

<p><code>PersistentVolume.yaml</code>:</p>

<pre><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-app-data
  labels:
    app: my-app
spec:
  capacity:
    storage: 60Gi
  storageClassName: standard
  accessModes:
    - ReadWriteOnce
  gcePersistentDisk:
    pdName: my-app-disk
    fsType: ext4
</code></pre>

<p><code>StatefulSet.yaml</code>:</p>

<pre><code>apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
  name: my-stateful-set
spec:
  serviceName: my-stateful-set
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: gcr.io/projectname/my-app:0.0.3
        ports:
        - containerPort: 80
          name: http
        volumeMounts:
        - name: my-app-data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: my-app-data
    spec:
      selector:
        matchLabels:
          app: my-app
      storageClassName: standard
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 50Gi
</code></pre>
