【问题标题】:How to persist data using a postgres database, Docker, and Kubernetes?如何使用 postgres 数据库、Docker 和 Kubernetes 持久化数据?
【发布时间】:2016-04-27 18:09:33
【问题描述】:

我正在尝试在运行 Postgres 自定义映像的容器上安装永久性磁盘。我正在使用 Kubernetes 并遵循 this 教程。

这是我的db_pod.yaml 文件:

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

我使用命令gcloud compute disks create --size 200GB my-db-disk创建磁盘。

但是,当我运行 pod 时,将其删除,然后再次运行(如教程中所示),我的数据不会持久化。

我尝试了此文件的多个版本,包括 PersistentVolumes 和 PersistentVolumeClaims,我尝试更改 mountPath,但没有成功。

编辑

用于创建 Postgres 镜像的 Dockerfile:

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"]

以及入口点脚本:

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

【问题讨论】:

  • 我看不出有什么问题。你能详细说明你是如何确认数据没有被持久化的吗? (您是登录数据库并选择 *,还是通过 wordpress 前端)。您还可以在 mysql 和 wordpress pod 上查找运行 kubectl describe pod 的可疑消息吗?
  • 我只是从前端添加数据,然后删除两个 pod,然后重新启动它们。我倾向于认为问题在于构建映像时正在创建我的数据库并且外部卷不再能够安装到现有数据上的事实......
  • 发布您的 dockerfile 会有所帮助。

标签: postgresql docker persistence kubernetes


【解决方案1】:

最后,真正的问题似乎是我试图从我的入口点脚本创建数据库。 诸如创建数据库或用户之类的事情应该在容器创建时完成,所以我最终使用了标准 Postgres 映像,它实际上提供了一种简单易用的方法来创建用户和数据库。

这是 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

感谢所有帮助过我的人:)

【讨论】:

  • 在我的情况下,问题在于 mountPath - 它是 /var/lib/postgresql 但是当我将它更改为 /var/lib/postgresql/data - 现在它可以工作了
  • @PavelAgarkov,您希望我将其添加到答案中,还是您想将其作为单独的答案?我认为应该执行其中任何一项来快速帮助有同样问题的人。
  • 你的答案是正确的。一开始我没有引起足够的重视。而id不管你是使用PV/PVC还是直接访问gcePersistentDisk。抱歉打扰了:)
  • @PavelAgarkov 我用相同的修复程序遇到了同样的问题,并设法在 Postgres Dockerfile github.com/docker-library/postgres/blob/...在此位置显式声明 - 请参阅此处 stackoverflow.com/questions/57140161/… 了解更多信息。
【解决方案2】:
  • 您的自定义 postgresql 是否将数据保存在 /var/lib/postgresql/data 中?
  • 您能否从您的 postgresql 容器中获取日志并发现任何有趣的内容?
  • 当您的 pod 运行时,您能否看到容器内的挂载点并检查永久性磁盘是否存在?

【讨论】:

  • 1.不,不是,这就是问题所在。 2. 不,我得到的唯一日志有四行没有任何意义:( 3. 永久磁盘正在挂载,但它只包含一个lost+found 目录,没有其他内容。我尝试在其中手动创建一个文件,并且它仍然没有持续......
【解决方案3】:

我遵循了这种情况,我能够通过将 mountPath 更改为 /var/lib/postgresql 来保存我的数据,并且还使用 cassandra 进行了复制(即 mountPath 为 /var/lib/cassandra)

我能够从不同的节点/主机删除/重新启动 pod,并且仍然可以看到我的“用户”表和我之前输入的数据。但是,我没有使用自定义镜像,我只是使用了标准 docker 镜像。

【讨论】:

  • 它也适用于我使用标准 docker postgres 图像:) 我想我将从那里开始。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-13
  • 1970-01-01
  • 1970-01-01
  • 2019-06-17
  • 1970-01-01
相关资源
最近更新 更多