How do I statically provision a volume for a StatefulSet?

1/15/2018

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

PersistentVolume yaml:

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

PersistentVolumeClaim yaml:

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

StatefulSet yaml:

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
-- Dan
google-cloud-platform
google-kubernetes-engine
kubernetes

1 Answer

1/16/2018

StatefulSet will create it's own PersistentVolumeClaim for each pod so you don't have to create one yourself. A PersistentVolume and a PersistentVolumeClaim will bind exclusively one to one. Your PVC is binding to your volume so any PVCs created by the StatefulSet can't bind to your volume so it won't be used.

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

PersistentVolume.yaml:

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

StatefulSet.yaml:

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
-- Ian Lewis
Source: StackOverflow