如何让Postgres容器与Amazon EFS共享数据?

Kim*_*Sok 1 database amazon-ecs docker docker-compose amazon-efs

我有一个有 2 个实例的集群。两个实例都有 Postgres 容器及其作为卷链接到弹性文件系统访问点的卷。

我将两个实例的卷映射到 /var/lib/postgresql/data,但容器没有共享其数据。

这是我的配置

docker-compose.yml

version: "3.0"
services:
    front:
        image: 540744822643.dkr.ecr.ap-southeast-1.amazonaws.com/front:latest
        links:
            - app:app.plasgate.com
        networks:
            - app
        container_name: front
        environment:
            - NODE_OPTIONS=--max-old-space-size=2048
        ports:
            - "8080:80"
        logging:
            driver: awslogs
            options:
                awslogs-group: sms-gateway
                awslogs-region: ap-southeast-1
                awslogs-stream-prefix: "front"
    app:
        image: 540744822643.dkr.ecr.ap-southeast-1.amazonaws.com/plasgate:latest
        links:
            - jasmin:jasmin
            - db:db
        networks:
            - app
        container_name: app
        environment:
            - PYTHONUNBUFFERED=1
            - PYTHONIOENCODING=UTF-8
        restart: on-failure:10
        ports:
            - "5000:5000"
        logging:
            driver: awslogs
            options:
                awslogs-group: sms-gateway
                awslogs-region: ap-southeast-1
                awslogs-stream-prefix: "app"
    nginx:
        image: 540744822643.dkr.ecr.ap-southeast-1.amazonaws.com/nginx:latest
        links:
            - app:app
            - front:front
        container_name: nginx
        networks:
            - app
        environment:
            API_HOST: "service.wpdevelop.xyz"
            API_PORT: 5000
            FRONT_HOST: "customer.wpdevelop.xyz"
            FRONT_PORT: 8080

        ports:
            - "80:80"
            - "443:443"
        logging:
            driver: awslogs
            options:
                awslogs-group: sms-gateway
                awslogs-region: ap-southeast-1
                awslogs-stream-prefix: "nginx"
    db:
        image: 540744822643.dkr.ecr.ap-southeast-1.amazonaws.com/postgres:latest
        volumes:
            - postgres:/var/lib/postgresql/data:rw
        restart: on-failure:10
        networks:
            - app
        environment:
            POSTGRES_PASSWORD: "xxx@2020"
            POSTGRES_USER: webadmin
            POSTGRES_DB: smsgwdev
        ports:
            - "5432:5432"
        logging:
            driver: awslogs
            options:
                awslogs-group: sms-gateway
                awslogs-region: ap-southeast-1
                awslogs-stream-prefix: "db"
    redis:
        image: 540744822643.dkr.ecr.ap-southeast-1.amazonaws.com/radis:latest
        container_name: redis
        restart: on-failure:10
        networks:
            - app
        ports:
            - "6379:6379"
        logging:
            driver: awslogs
            options:
                awslogs-group: sms-gateway
                awslogs-region: ap-southeast-1
                awslogs-stream-prefix: "redis"
volumes:
    postgres:
networks:
    app:
        driver: bridge
Run Code Online (Sandbox Code Playgroud)

ecs-params.yml

version: 1
task_definition:
    family: sms-gateway
    ecs_network_mode: bridge
    services:
        front:
            essential: true
            cpu_shares: 100
            mem_limit: 2147483648
            healthcheck:
                test: ["CMD-SHELL", "curl -f http://localhost || exit 1"]
                interval: 5s
                timeout: 10s
                retries: 3
                start_period: 30s
        app:
            essential: false
            cpu_shares: 100
            mem_limit: 2147483648
            healthcheck:
                test: ["CMD-SHELL", "curl -f http://localhost:5000 || exit 1"]
                interval: 5s
                timeout: 10s
                retries: 3
                start_period: 30s
            depends_on:
                - container_name: db
                  condition: HEALTHY
        nginx:
            essential: false
            cpu_shares: 100
            mem_limit: 2147483648
            healthcheck:
                test: ["CMD-SHELL", "curl -f http://localhost || exit 1"]
                interval: 5s
                timeout: 10s
                retries: 3
                start_period: 30s
        db:
            essential: false
            cpu_shares: 100
            mem_limit: 2147483648
            healthcheck:
                test: pg_isready -U webadmin -d smsgwdev
                interval: 5s
                timeout: 10s
                retries: 2
                start_period: 30s
        redis:
            essential: false
            cpu_shares: 100
            mem_limit: 2147483648
            healthcheck:
                test: ["CMD-SHELL", "redis-cli", "ping"]
                interval: 5s
                timeout: 10s
                retries: 2
                start_period: 30s

    efs_volumes:
        - name: postgres
          filesystem_id: fs-a4aa73e4
          transit_encryption: ENABLED
          access_point: fsap-007405b3e9bc7bc2f
Run Code Online (Sandbox Code Playgroud)

如何让两个 Postgres 容器使用相同的 pgdata?

mre*_*rre 5

首先也是最重要的一点,在 EFS 上运行 Postgres 并不是一个好主意。我认为如果您需要快速且测试环境中负载非常低的东西,\xe2\x80\x99 就可以了,但 EFS 不是数据库引擎的正确后端。其次,在 2 个容器之间共享 EFS 共享是一个更糟糕的主意。这种设置是不允许的,因为每个数据库都会同时对相同的数据文件进行非仲裁访问,而这不是 Postgres 应该工作的方式。

\n

其次,您没有明确地调用它,但您是否使用它ecs-cli来部署它?如果是这样,我的建议是考虑我们 (AWS) 与 Docker 一起引入的替代机制,该机制依赖于新的 Docker Compose 功能来部署到云(例如 ECS)。新版本ecs-cli称为Copilot,它不再支持 Docker。ecs-params请注意,新的 Docker Compose 集成目前不需要单独的文件(尽管正在讨论引入一个文件),并且依赖于x-aws-docker compose 文件本身的扩展。

\n

第三,无论这是否是一个好主意(它\xe2\x80\x99s不是!),紧接着这个例子并受到这个例子的启发,以下简单的组合允许您部署2个共享相同数据的Postgres容器目录:

\n
version: \'3.4\'\nservices:\n  db1:\n    container_name: db1\n    image: postgres:latest\n    environment:\n      - POSTGRES_USER=me\n      - POSTGRES_PASSWORD=mypassword\n    volumes:\n      - my-vol:/var/lib/postgresql/data\n  db2:\n    depends_on:\n      - db1\n    container_name: db2\n    image: postgres:latest\n    environment:\n      - POSTGRES_USER=me\n      - POSTGRES_PASSWORD=mypassword\n    volumes:\n      - my-vol:/var/lib/postgresql/data\n  app:\n    container_name: app\n    image: nginx\nvolumes:\n  my-vol:\n\n
Run Code Online (Sandbox Code Playgroud)\n

如果您docker compose up在 ECS 环境中(请参阅博客了解更多详细信息),您将获得 3 个 ECS 服务(1 个 app/nginx 和 2 个 DB 服务),其中 2 个 DB 服务坚持使用相同的 EFS 访问点。同样,这只是一个证明 docker compose 文件有效的学术示例。我不建议在任何有意义的部署中使用它。

\n

[更新]:我刚刚注意到上面的撰写中只有 1 个 postgres。因此,我假设您有两个单独的撰写文件,其中一个 postgres 数据库坚持使用同一文件系统。我上面所说的一切仍然适用,但请注意,存在一个限制,甚至会阻止您从技术上部署此场景

\n