Postgres with Kubernetes and persistentDisk

5.8k Views Asked by At

I'm getting started with Kubernates and having problems installing Postgres using Kubernetes with a GCE Persistent disk. I can successfully install Mysql using both the Kubernates walkthroughs and also the following guide: http://amygdala.github.io/kubernetes/2015/01/13/k8s1.html

However, when I try to achieve a similar thing with postgres, it seems to fail when attaching to the disk or using the disk. I've created a pod yaml based on the mysql one from the above post but substituting the postgres docker image:

apiVersion: v1beta1
id: postgres
desiredState:
  manifest:
    version: v1beta1
    id: postgres
    containers:
      - name: postgres
        image: postgres
        env:
          - name: DB_PASS
            value: password
        cpu: 100
        ports:
          - containerPort: 5432
        volumeMounts:
            # name must match the volume name below
          - name: persistent-storage
            # mount path within the container
            mountPath: /var/lib/postgresql/data
    volumes:
      - name: persistent-storage
        source:
          persistentDisk:
            # This GCE PD must already exist and be formatted ext4
            pdName: postgres-disk
            fsType: ext4
labels:
  name: postgres
kind: Pod

However when I create

$ kubectl create -f postgres.yaml

I get the following errors:

$ kubectl logs postgres
$ postgres cannot access the server configuration file "/var/lib/postgresql/data/postgresql.conf": No such file or directory

I can see that the postgres-disk is attached to a minion server, so I'm wondering if it's related to the Volumes in the docker image that I'm using, or if I need separate mount paths for the postgresql.conf file.

Now if I change the mount path (eg mountPath: /var/lib/postgresql) the pod will start ok but it doesn't appear to be using the persistent data. Inspecting the volumes in the docker container on the minion gives me:

"Volumes": {
        "/dev/termination-log": "/var/lib/kubelet/pods/52177db4-149c-11e5-a64b-42010af06968/containers/postgres/91ecf33c939588b4165865f46b646677bf964fab81ea7ec08b598568513d4644",
        "/var/lib/postgresql": "/var/lib/kubelet/pods/52177db4-149c-11e5-a64b-42010af06968/volumes/kubernetes.io~gce-pd/pgdata",
        "/var/lib/postgresql/data": "/var/lib/docker/vfs/dir/c3ecda11de6a598d99842c06bee22097f1cb63a6e467cbe7af874d003140a4af",
        "/var/run/secrets/kubernetes.io/serviceaccount": "/var/lib/kubelet/pods/52177db4-149c-11e5-a64b-42010af06968/volumes/kubernetes.io~secret/default-token-b6s28"
    },

I've also tried using a json file with v1beta3 with similar results:

{
  "kind": "Pod",
  "apiVersion": "v1beta3",
  "metadata": {
    "name": "postgres"
  },
  "spec": {
    "volumes": [{
      "name": "pgdata",
      "gcePersistentDisk": {
        "pdName": "postgres-disk",
        "fsType": "ext4"
      }
    }],
    "containers": [
      {
        "name": "postgres",
        "image": "postgres",
        "ports": [
          {
            "name": "postgres-ports",
            "hostPort": 5432,
            "containerPort": 5432
          }
        ],
        "env": [
          {
            "name": "DB_USER",
            "value": "postgres"
          },
          {
            "name": "DB_PASS",
            "value": "password"
          }
        ],
        "volumeMounts": [
          {
            "name": "pgdata",
            "readOnly": false,
            "mountPath": "/var/lib/postgresql/data"
          }
        ]
      }
    ]
  }
}

It's quite possible I've just missed something in the doco, but any help would be appreciated with this!

3

There are 3 best solutions below

2
On BEST ANSWER

Please check the documentation for volumes https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/volumes.md#gcepersistentdisk

Before you can use a GCE PD with a pod, you need to create it.

gcloud compute disks create --size=500GB --zone=us-central1-a pg-data-disk

This would be your config, mind the gcePersistentDisk

apiVersion: v1beta1
id: postgres
desiredState:
  manifest:
    version: v1beta1
    id: postgres
    containers:
      - name: postgres
        image: postgres
        env:
          - name: DB_PASS
            value: password
        cpu: 100
        ports:
          - containerPort: 5432
        volumeMounts:
            # name must match the volume name below
          - name: persistent-storage
            # mount path within the container
            mountPath: /var/lib/postgresql/data
    volumes:
      - name: persistent-storage
        source:
          gcePersistentDisk:
            # This GCE PD must already exist and be formatted ext4
            pdName: pg-data-disk
            fsType: ext4
labels:
  name: postgres
kind: Pod
1
On

Your yaml has "persistentDisk" where it should have "gcePersistentDisk". Use kubectl create -f <file> --validate to catch errors like this. Your json appears correct, though.

Is it possible that postgres requires that config file to exist already?

0
On

I'm getting the same problem as well - it's due to the db initialization script wrongly assuming a non-empty volume directory means it has already been initialized.

Unfortunately, a new GCE persistence disk contains a lost+found directory.

I've submitted a fix for the docker image here.