How to use PersistentVolume for PostgreSQL data in Kubernetes

We are developing Web-server by Flask & DB-server by PostgreSQL in Kubernetes, and considering to use PersistentVolume in order to make data persistent.

However, for the directory specified as Volume, the ownership is forced to become ‘root’ user.

In PostgreSQL, if the user and owner do not match, the server can not be set up. And, we can not set up a server under the user=‘root’. So, we can not make PostgreSQL server data persistent.

Dockerfile

FROM ubuntu:latest

ARG project_dir=/app/

WORKDIR $project_dir

RUN apt update
RUN apt install --yes python3 python3-pip postgresql-9.5
RUN apt clean
RUN ln -s /usr/bin/python3 /usr/bin/python
RUN ln -s /usr/bin/pip3 /usr/bin/pip

RUN pip install flask
RUN pip install flask_sqlalchemy
RUN pip install psycopg2

ADD app.py $project_dir
ADD templates/ $project_dir/templates/

USER postgres

RUN /etc/init.d/postgresql start && \
  psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" && \
  createdb -O docker docker

RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/9.5/main/pg_hba.conf
RUN echo "listen_addresses='*'" >> /etc/postgresql/9.5/main/postgresql.conf

EXPOSE 5000

CMD /usr/lib/postgresql/9.5/bin/postgres -D /var/lib/postgresql/9.5/main -c config_file=/etc/postgresql/9.5/main/postgresql.conf & python /app/app.py

development.yaml

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: dummyproject
  labels:
    app: dummyproject
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dummyproject
  template:
    metadata:
      labels:
        app: dummyproject
    spec:
      containers:
      - name: dummyproject
        image: dummyproject:0.1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 5000
        volumeMounts:
        - mountPath: /var/lib/postgresql/
          name: mydata
      volumes:
        - name: mydata
          persistentVolumeClaim:
            claimName: nfs-claim1

Please let me know if you know the solution.

2 answers

  • answered 2018-05-16 11:25 Alexandr Lurye

    Feel free to run PostgreSQL as root. Root in the container is not the same as root on a bare Linux machine. UID==0 doesn't imply superpowers anymore. Nowadays user access is controlled with the mechanism of capabilities, and your container won't have any dangerous capabilities by default (unless you explicitly ask Kubernetes for some).

  • answered 2018-05-16 13:06 Anton Kostenko

    You have 2 options here:

    1. Set UID to 0 in the container, as @Alexandr Lurye told above. That is more or less secure now.
    2. You can use InitContainer to change the owner. That is my answer how to do it - https://serverfault.com/questions/906083/how-to-mount-volume-with-specific-uid-in-kubernetes-pod/907160#907160