Creating Persistent Volumes in Kubernetes on Google cloud platform

Viewed 1717

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!

3 Answers

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

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

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
Related