4

I am trying to mount a persistent disk on my container which runs a Postgres custom image. I am using Kubernetes and following this tutorial.

This is my db_pod.yaml file:

apiVersion: v1
kind: Pod
metadata:
  name: lp-db
  labels:
    name: lp-db
spec:
  containers:
    - image: my_username/my-db
      name: my-db
      ports:
        - containerPort: 5432
          name: my-db
      volumeMounts:
        - name: pg-data
          mountPath: /var/lib/postgresql/data
  volumes:
    - name: pg-data
      gcePersistentDisk:
        pdName: my-db-disk
        fsType: ext4

I create the disk using the command gcloud compute disks create --size 200GB my-db-disk.

However, when I run the pod, delete it, and then run it again (like in the tutorial) my data is not persisted.

I tried multiple versions of this file, including with PersistentVolumes and PersistentVolumeClaims, I tried changing the mountPath, but to no success.

Edit

Dockerfile for creating the Postgres image:

FROM ubuntu:trusty
RUN rm /bin/sh && \
    ln -s /bin/bash /bin/sh

# Get Postgres
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main" >> /etc/apt/sources.list.d/pgdg.list
RUN apt-get update && \
    apt-get install -y wget
RUN wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

# Install virtualenv (will be needed later)
RUN apt-get update && \
    apt-get install -y \
        libjpeg-dev \
        libpq-dev \
        postgresql-9.4 \
        python-dev \
        python-pip \
        python-virtualenv \
        strace \
        supervisor


# Grab gosu for easy step-down from root
RUN gpg --keyserver pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
    && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.2/gosu-$(dpkg --print-architecture)" \
    && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.2/gosu-$(dpkg --print-architecture).asc" \
    && gpg --verify /usr/local/bin/gosu.asc \
    && rm /usr/local/bin/gosu.asc \
    && chmod +x /usr/local/bin/gosu \
    && apt-get purge -y --auto-remove ca-certificates wget

# make the "en_US.UTF-8" locale so postgres will be utf-8 enabled by default
RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \
    && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
ENV LANG en_US.utf8

# Adjust PostgreSQL configuration so that remote connections to the database are possible.
RUN echo "host all  all    0.0.0.0/0  md5" >> /etc/postgresql/9.4/main/pg_hba.conf

# And add ``listen_addresses`` to ``/etc/postgresql/9.4/main/postgresql.conf``
RUN echo "listen_addresses='*'" >> /etc/postgresql/9.4/main/postgresql.conf
RUN echo "log_directory='/var/log/postgresql'" >> /etc/postgresql/9.4/main/postgresql.conf

# Add all code from the project and all config files
WORKDIR /home/projects/my-project
COPY . .

# Add VOLUMEs to allow backup of config, logs and databases
ENV PGDATA /var/lib/postgresql/data
VOLUME /var/lib/postgresql/data

# Expose an entrypoint and a port
RUN chmod +x scripts/sh/*
EXPOSE 5432
ENTRYPOINT ["scripts/sh/entrypoint-postgres.sh"]

And entrypoint script:

echo " I am " && gosu postgres whoami

gosu postgres /etc/init.d/postgresql start && echo 'Started postgres'
gosu postgres psql --command "CREATE USER myuser WITH SUPERUSER PASSWORD 'mypassword';"  && echo 'Created user'
gosu postgres createdb -O myuser mydb && echo 'Created db'

# This just keeps the container alive.
tail -F /var/log/postgresql/postgresql-9.4-main.log
3
  • I can't see anything wrong off the bat. Can you elaborate on how you confirmed that the data is not persisted? (did you log into the database and select *, or via the wordpress frontend). Can you also look for suspicious messages running kubectl describe pod on the mysql and wordpress pods? Commented Jan 20, 2016 at 22:39
  • 1
    I simply added data from the fronted, then deleted both pods, and then restarted them. I tend to believe that the problem lies within the fact that my database is being created when I build the image and the external volume is no longer able to be mounted onto existing data... Commented Jan 21, 2016 at 9:28
  • Posting your dockerfile would be helpful. Commented Jan 21, 2016 at 16:16

3 Answers 3

11

In the end, it seems that the real problem was the fact that I was trying to create the database from my entrypoint script. Things such as creating a db or a user should be done at container creation time so I ended up using the standard Postgres image, which actually provides a simple and easy way to create an user and a db.

This is the fully functional configuration file for Postgres.

apiVersion: v1
kind: Pod
metadata:
  name: postgres
  labels:
    name: postgres
spec:
  containers:
    - name: postgres
      image: postgres
      env:
        - name: PGDATA
          value: /var/lib/postgresql/data/pgdata
        - name: POSTGRES_USER
          value: myuser
        - name: POSTGRES_PASSWORD
          value: mypassword
        - name: POSTGRES_DB
          value: mydb
      ports:
        - containerPort: 5432
      volumeMounts:
        - mountPath: /var/lib/postgresql/data
          name: pg-data
  volumes:
    - name: pg-data
      persistentVolumeClaim:
        claimName: pg-data-claim

Thanks to all those who helped me :)

Sign up to request clarification or add additional context in comments.

4 Comments

In my case problem was with mountPath - it was /var/lib/postgresql But when I changed it to /var/lib/postgresql/data - now it works
@PavelAgarkov, would you like me to add this to the answer or do you want to make it a separate answer in itself? I think either of these should be done to quickly help people with the same problem.
Your answer is correct. I did not pay enough attention at the first place. And id does not matter whether you use PV/PVC or directly access gcePersistentDisk. Sorry for bothering:)
@PavelAgarkov I ran into the same issue with the same fix and managed to locate the source down to this line in the Postgres Dockerfile github.com/docker-library/postgres/blob/… where a VOLUME is explicitly declared at this location - see here stackoverflow.com/questions/57140161/… for more information.
0
  • does your custom postgresql persist data at /var/lib/postgresql/data?
  • are you able to get logs from your postgresql container and spot anything interesting?
  • when your pod is running, can you see the mountpoints inside your container and check the persistent disk is there?

1 Comment

1. No, it doesn't, that's the problem. 2. No, the only log I get has four lines that say nothing meaningful :( 3. The persistent disk is being mounted, but it only contains a lost+found directory and nothing else. I tried manually creating a file inside it, and it still doesn't persist...
0

I followed this scenario and I was able to persist my data by changing the mountPath to /var/lib/postgresql and also reproduced using cassandra (i.e. /var/lib/cassandra for mountPath)

I was able to delete/restart pods from different nodes/hosts and still see my "users" table and the data I previously entered. However, I was not using a custom image, I just used standard docker images.

1 Comment

It also works for me using the standard docker postgres image :) I think I will start from there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.