【问题标题】:How to create a persistent data volume for Postgres Database container in docker swarm如何在 docker swarm 中为 Postgres 数据库容器创建持久数据卷
【发布时间】:2019-10-29 07:51:22
【问题描述】:

我有几个 Postgresql 服务,以及其他一些对我有用的服务(用于创建 HA Postgresql 集群)。该集群在 docker-compose 中描述如下:

    version: '3.3'
services:

  haproxy:
    image: haproxy:alpine
    ports:
        - "5000:5000"
        - "5001:5001"
        - "8008:8008"
    configs: 
      - haproxy_cfg
    networks:
      - dbs
    command: haproxy -f /haproxy_cfg

  etcd:
    image: quay.io/coreos/etcd:v3.1.2
    configs:
      - etcd_cfg
    networks: 
      - dbs
    command: /bin/sh /etcd_cfg

  dbnode1:
    image: seocahill/patroni:1.2.5
    secrets: 
      - patroni.yml
    environment:
      - PATRONI_NAME=dbnode1
      - PATRONI_POSTGRESQL_DATA_DIR=data/dbnode1
      - PATRONI_POSTGRESQL_CONNECT_ADDRESS=dbnode1:5432
      - PATRONI_RESTAPI_CONNECT_ADDRESS=dbnode1:8008
    env_file:
      - test.env
    networks:
      - dbs
    entrypoint: patroni
    command: /run/secrets/patroni.yml

  dbnode2:
    image: seocahill/patroni:1.2.5
    secrets: 
      - patroni.yml
    environment:
      - PATRONI_NAME=dbnode2
      - PATRONI_POSTGRESQL_DATA_DIR=data/dbnode2
      - PATRONI_POSTGRESQL_CONNECT_ADDRESS=dbnode2:5432
      - PATRONI_RESTAPI_CONNECT_ADDRESS=dbnode2:8008
    env_file:
      - test.env
    networks:
      - dbs
    entrypoint: patroni
    command: /run/secrets/patroni.yml

  dbnode3:
    image: seocahill/patroni:1.2.5
    secrets: 
      - patroni.yml
    environment:
      - PATRONI_NAME=dbnode3
      - PATRONI_POSTGRESQL_DATA_DIR=data/dbnode3
      - PATRONI_POSTGRESQL_CONNECT_ADDRESS=dbnode3:5432
      - PATRONI_RESTAPI_CONNECT_ADDRESS=dbnode3:8008
    env_file:
      - test.env
    networks:
      - dbs
    entrypoint: patroni
    command: /run/secrets/patroni.yml

networks:
  dbs:
    external: true

configs:
  haproxy_cfg:
    file: config/haproxy.cfg
  etcd_cfg:
    file: config/etcd.sh

secrets:
  patroni.yml:
    file: patroni.test.yml

我从https://github.com/seocahill/ha-postgres-docker-stack.git 获取了这个 yml 代码。我使用下一个命令在 docker swarm 中部署此服务 - docker network create -d overlay --attachable dbs && docker stack deploy -c docker-stack.test.yml test_pg_cluster。但是如果我创建一些数据库并向其中插入一些数据然后重新启动服务 - 我的数据将会丢失。 我知道我需要使用volume 在主机上保存数据。 我使用 docker 命令创建卷:docker volume create pgdata 使用默认 docker 卷目录并像这样安装它:

dbnode1:
        image: seocahill/patroni:1.2.5
        secrets: 
          - patroni.yml
        environment:
          - PATRONI_NAME=dbnode1
          - PATRONI_POSTGRESQL_DATA_DIR=data/dbnode1
          - PATRONI_POSTGRESQL_CONNECT_ADDRESS=dbnode1:5432
          - PATRONI_RESTAPI_CONNECT_ADDRESS=dbnode1:8008
        env_file:
          - test.env
        volumes:
          pgdata:/data/dbnode1
        networks:
          - dbs
        entrypoint: patroni
        command: /run/secrets/patroni.yml

        volumes:
           pgdata:

当容器启动时,它在容器内的数据目录 data/dbnode1 中有自己的配置。如果我挂载卷pgdata 以在主机中存储数据,我无法连接到数据库并且容器目录data/dbnode1 中有空文件夹。如何创建持久数据卷以在 PostgerSQL 中保存更改的数据?

【问题讨论】:

  • 例如docker swarm 不会在集群节点之间同步卷,不建议从主机绑定挂载,除非您为服务添加放置约束,就好像服务崩溃并重新安排到不同的节点,然后您将“松散”您的数据 -您应该在可以从所有节点访问的 nfs 共享中创建 docker 卷。例如可以看看this compose file

标签: docker docker-compose docker-swarm patroni


【解决方案1】:

直接添加路径更容易创建volumes。检查这个例子。

dbnode1:
        image: seocahill/patroni:1.2.5
        secrets: 
          - patroni.yml
        environment:
          - PATRONI_NAME=dbnode1
          - PATRONI_POSTGRESQL_DATA_DIR=data/dbnode1
          - PATRONI_POSTGRESQL_CONNECT_ADDRESS=dbnode1:5432
          - PATRONI_RESTAPI_CONNECT_ADDRESS=dbnode1:8008
        env_file:
          - test.env
        volumes:
          - /opt/dbnode1/:/data/dbnode1
        networks:
          - dbs
        entrypoint: patroni
        command: /run/secrets/patroni.yml

注意线条

        volumes:
          - /opt/dbnode1/:/data/dbnode1

我使用路径/opt/dbnode1/ 将文件系统存储在/data/dbnode1 的容器中。

另外需要注意的是,docker swarm 不会为您创建文件夹。因此,您必须在启动服务之前创建文件夹。运行mkdir -p /opt/dbnode1 这样做。

【讨论】:

  • 您建议使用绑定挂载而不是 docker 托管卷。注意docsThe file or directory does not need to exist on the Docker host already. It is created on demand if it does not yet exist
  • 这就是为什么我要在主机中创建文件夹。
  • 不,不需要在主机中创建文件夹。这就是文档中写的内容。你可以试试看它是自动创建的
  • 你不知道它指的是什么主机。文档状态 DOCKER HOST 将自动创建 BUT 运行容器的实际机器不会自动创建文件夹。您将收到以下错误:invalid mount config for type "bind": bind source path does not exist: $PATH_IN_MACHINE
猜你喜欢
  • 1970-01-01
  • 2022-08-13
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-26
  • 1970-01-01
相关资源
最近更新 更多