3

I’m getting started with kubernetes, and I want to create a simple app with a single webserver & postgres database. The problem I’m running into is the deployment of the postgres is giving me permission errors. The following are discussions around this:

EDIT

spec:

  • OSX - 10.15.4
  • minikube - v1.9.2
  • kubernetes - v1.18.2

minikube setup

minikube start --driver=virtualbox --cpus=2 --memory=5120 --kubernetes-version=v1.18.2 --container-runtime=docker --mount=true --mount-string=/Users/holmes/kubernetes/pgdata:/data/pgdata

The permission error: chmod: changing permissions of '/var/lib/postgresql/data': Operation not permitted

I am trying to mount a local OS directory into minikube to be used with the postgres deployment/pod/container volume mount.

After I run the above setup I ssh into minikube (minikube ssh) and check the permissions

# minikube: /
drwxr-xr-x   3 root   root   4096 May 13 19:31 data
# minikube: /data
drwx------  1 docker docker   96 May 13 19:27 pgdata

By running the script below the chmod permission error surfaces. If I change the --mount-string=/Users/holmes/kubernetes/pgdata:/data (leave out /pgdata) and then minikube ssh to create the pgdata directory:

mkdir -p /data/pgdata
chmod 777 /data/pgdata

I get a different set of permissions before deployment

# minikube: /
drwx------   1 docker docker   96 May 13 20:10 data
# minikube: /data
drwxrwxrwx 1 docker docker   64 May 13 20:25 pgdata

and after deployment

# minikube: /
drwx------   1 docker docker  128 May 13 20:25 data
# minikube: /data
drwx------ 1 docker docker   64 May 13 20:25 pgdata

Not sure why this changes, and the chmod permission error persists. It seems like the above reference links are bouncing around different methods on different machines on different vms which I don’t understand nor can I get this to work. Can someone walk me getting this to work? Super confused going through all the above discussions.

postgres.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: data-block

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
  namespace: data-block
  labels:
    type: starter
data:
  POSTGRES_DB: postgres
  POSTGRES_USER: postgres
  POSTGRES_PASSWORD: docker

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-pv
  namespace: data-block
  labels:
    app: postgres
spec:
  capacity:
    storage: 2Gi
  accessModes:
  - ReadWriteOnce
  hostPath:
    path: /data/pgdata

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pv-claim
  namespace: data-block
  labels:
    app: postgres
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: ""

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  namespace: data-block
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:12.2
        ports:
        - containerPort: 5432
        envFrom:
        - configMapRef:
            name: postgres-config
        volumeMounts:
        - name: postgres-vol
          mountPath: /var/lib/postgresql/data
      volumes:
      - name: postgres-vol
        persistentVolumeClaim:
          claimName: postgres-pv-claim

UPDATE

I went ahead and updated the deployment script to a simple pod. The goal is map the postgres /var/lib/postgresql/data to my local file directory /Users/<my-path>/database/data to persist the data.

---
apiVersion: v1
kind: Pod
metadata:
  name: postgres-pod
  namespace: data-block
  labels:
    name: postgres-pod
spec:
  containers:
  - name: postgres
    image: postgres:12.3
    imagePullPolicy: IfNotPresent
    ports:
    - name: postgres-port
      containerPort: 5432
    envFrom:
    - configMapRef:
        name: postgres-env-config
    - secretRef:
        name: postgres-secret
    volumeMounts:
    - name: postgres-vol
      mountPath: /var/lib/postgresql/data
  volumes:
    - name: postgres-vol
      hostPath:
        path: /Users/<my-path>/database/data
  restartPolicy: Never

The error: initdb: error: could not access directory "/var/lib/postgresql/data": Permission denied

How to go about mounting the local file directory?

M.Holmes
  • 165
  • 1
  • 11
  • Did you manage to solve the problem ? – Malgorzata May 20 '20 at 08:32
  • No. I am still investigating. For now the data is not being saved locally on the host. The date resides with minikube – M.Holmes May 20 '20 at 14:05
  • Did you try to add to volumeMounts: section in Deployment configuration file param: readOnly: false ? – Malgorzata Jun 15 '20 at 11:55
  • @MaggieO I get the following error: `initdb: error: could not access directory "/var/lib/postgresql/data": Permission denied` with or without the `readOnly: false – M.Holmes Jun 16 '20 at 19:34
  • Your claim requests the class "" and effectively disable dynamic provisioning for itself. Can you delete line with storageclass from pvc definition or add existing storageclass which you want to use ? – Malgorzata Jun 29 '20 at 13:35
  • Were you able to solve your issue? – thomas Apr 14 '21 at 14:30

1 Answers1

0

You are declaring the PGDATA field that maybe the cause of the issue. I faced the same error, this comes because there's as LOST+FOUND folder already in that directory however, the container wants it to be a empty dir. Giving the subPath field solves this issue. Please try this it should solve the issue and you need not need any PGDATA field. Try omitting it from your configmap and add subPath to some folder. Please go through following manifests.

https://github.com/mendix/kubernetes-howto/blob/master/postgres-deployment.yaml

https://www.bmc.com/blogs/kubernetes-postgresql/

it's a statefulset that usually you should go with and not a deployment when it comes to Database deployment.

        - name: postgredb
          mountPath: /var/lib/postgresql/data
         #setting subPath will fix your issue it can be pgdata or 
          postgres or any other folder name according to your 
          choice.
          subPath: postgres 
redzack
  • 800
  • 3
  • 12
  • updated the files following your suggestions. With the updates I get the following msg `initdb: error: could not access directory "/var/lib/postgresql/data": Permission denied` – M.Holmes May 12 '20 at 20:28
  • I wonder if this issue is related to how PersistentVolumes 'hostPath' works? Not really sure though – M.Holmes May 12 '20 at 20:31
  • I'm using the same deployment manifest, as I came across similar issue. Can you try a fresh deployment probably in some other namespace? Also I am using the same on AKS and EKS but not with hostPath. Probably you maybe having the issue there. I installed postgres v9 for this purpose. – redzack May 12 '20 at 20:34
  • I found this error `StorageClass's fields: StorageClass "manual" not found` This might be the cause? – M.Holmes May 12 '20 at 20:53
  • Maybe you need to visit how to create your own storage class type. Please look up here to create your own class or use **standard** as the storageclassName. You can remove that field it will pick up by default. https://kubernetes.io/docs/concepts/storage/storage-classes/ – redzack May 12 '20 at 21:02
  • I removed the storageclass manual. Leaving everything else the same it appears to be functional. I created the deployment, went inside the pod/container and created a table & inserted data. I then deleted the pod, another one was created automatically. I went inside the new pod/container and checked if the data persisted. It did! But where is it being stored on my local machine? – M.Holmes May 12 '20 at 21:27
  • @M.Holmes can you please post the working config if not done as of now so that it may help others. Also it should be at the place where your pvc is mounted. I'm assuming you were talking about hostPath. Could you please check at that path? Also if you can go inside the node of your minikube and run lsblk to check whatever volumes are mounted. To ssh into minikube node do a **ssh docker@node-IP** and password would be **tcuser** – redzack May 12 '20 at 21:49
  • I updated the yaml files and performed the volume mount checks. hostPath doesn't appear to be mounted. – M.Holmes May 13 '20 at 00:23
  • Where is that *Users/xxx/xxx* directory? It should be on the minikube node. HostPath is the path on node and not on your local laptop. Please check the example here. I think you got the concept wrong https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-pod. Configure something like this. – redzack May 13 '20 at 06:25
  • I hope this is solved and the above answer was valid, if yes please receive the answer so that it may help others. Thanks – redzack May 13 '20 at 14:52
  • unfortunately it has not. When I ssh into minikube the node filesystem reflects what I have locally. Here is minikube documentation on PV https://minikube.sigs.k8s.io/docs/handbook/persistent_volumes/. Even if I change the host path to `/data/pgdata` the data is persisted as `/tmp/hostpath-provisioner/pvc-4e511630-926d-43f2-8286-2204bb791ff6`. I am testing mounting with this guidance: https://minikube.sigs.k8s.io/docs/handbook/mount/ – M.Holmes May 13 '20 at 15:51
  • According to your previous comment, you said that the data persisted but where it is you were not able to find out? I am not understanding what you could be doing wrong or how it isn't persisting now. According to the question, there were permission errors on mounting and it has been resolved AFAIK. The **subPath** worked and then removing **storageClassName** worked too. Now the PV creation using **hostPath** has issues thats the third issue we came across. – redzack May 13 '20 at 17:49
  • The data did persist but not to the expected host path. The data persisted to this `/tmp/hostpath-provisioner/pvc-4e511630-926d-43f2-8286-2204bb791ff6` inside the minikube host. I don't know how this happened especially because I was explicitly adding a `hostPath`. I updated the PV object to explicitly host the path at the `/data` path following the minikube docs. I removed the subpath and kept the volumeMount as is. The container works, I can access postgres, but the data does not persist across deployments. I think the issue is with minikube & PV hosts path. I added the minikube setup – M.Holmes May 13 '20 at 17:54