Creating Persistent Volumes in Kubernetes on Google cloud platform

10/20/2018

I'm trying to deploy a postgres service to google cloud kubernetes with a persistent volume and persistent volume claim to provide storage for my application.

When I deploy, the pod gets stuck in a CrashLoopBackOff.

One of the pod's events fails with the message:

Error: failed to start container "postgres": Error response from daemon: error while creating mount source path '/data/postgres-pv': mkdir /data: read-only file system

This is the yaml I am trying to deploy using kubectl:

kind: PersistentVolume
apiVersion: v1
metadata:
  name: postgres-pv
  labels:
    type: local
    app: postgres
spec:
  capacity:
    storage: 5Gi
  storageClassName: standard
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /data/postgres-pv
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: postgres-pvc
  labels:
    type: local
    app: postgres
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  volumeName: postgres-pv
---
apiVersion: v1
kind: Secret
metadata:
  name: postgres-credentials
type: Opaque
data: 
  user: YWRtaW4=
  password: password==
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: postgres-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres-container
          image: postgres:9.6.6
          env:
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: postgres-credentials
                  key: user
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-credentials
                  key: password   
            - name: POSTGRES_DB
              value: kubernetes_django
          ports:
            - containerPort: 5432
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgres-volume-mount
      volumes:
        - name: postgres-volume-mount
          persistentVolumeClaim:
            claimName: postgres-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: postgres
  labels:
    app: postgres
spec:
  ports:
    - protocol: TCP
      port: 5432
      targetPort: 5432
  selector:
   app: postgres

Nothing fails to deploy, but the pod gets stuck in a CrashLoopBackOff.

Thanks for the help!

-- wc_coder
google-kubernetes-engine
kubernetes
persistent-volumes
postgresql

3 Answers

2/21/2019

I had the same problem. Following this tutorial I got it all to work with minikube but it gave the same error on GCP.

As mentioned by Patrick W, the docs say:

Types of Persistent Volumes

  • ...
  • HostPath (Single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)
  • ...

To solve this, I found a solution in the kubernetes docs

You'll first have to create a gcePersistentDisk:

gcloud compute disks create --size=[SIZE] --zone=[ZONE] [DISK_NAME]

and then the configuration as described in the link should do the trick:

kind: PersistentVolume
apiVersion: v1
metadata:
  name: postgres-pv
  labels:
    type: local
spec:
  capacity:
    storage: 4Gi
  storageClassName: standard
  accessModes:
    - ReadWriteMany
  gcePersistentDisk:
    pdName:data-disk
    fsType: ext4
    readOnly: true
-- Tim
Source: StackOverflow

4/28/2019

firstly you should not use host path in your persistent volume. secondly, I think you missing a part in your deployment you should specify a PDATA directory .

for the sake of simplicity I share me yml deployment :

1. Persistance Volum Claim:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: postgres-pvc  
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi

2. config map to hold posgres env :

apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
  labels:
    app: postgres
data:
  POSTGRES_DB: profile
  POSTGRES_USER: postgresadmin
  POSTGRES_PASSWORD: othmane
  PGDATA: /var/lib/postgresql/data/pgdata

3. postgres deployment :

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:10.4
          imagePullPolicy: "IfNotPresent"
          ports:
            - containerPort: 5432
              name: postgres
          envFrom:
            - configMapRef:
                name: postgres-config
          volumeMounts:
           - name: postgres-db
             mountPath: /var/lib/postgresql/data
      volumes:
      - name: postgres-db
        persistentVolumeClaim: 
          claimName: postgres-pvc


---

apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  selector:
    app: postgres
  ports:
   - protocol: "TCP"
     port: 5432
     targetPort: 5432
  type: ClusterIP
-- Othmane Daanouni
Source: StackOverflow

10/26/2018

The problem is your persistent volume. You are using host path which is not, and according to the doc, never will be, supported

-- Patrick W
Source: StackOverflow