繁体   English   中英

在 Amazon Linux 2 实例上的 ECS 任务中运行时,docker 容器中的 Bash 重定向失败

[英]Bash redirection in docker container failing when ran in ECS task on Amazon Linux 2 instances

我正在尝试运行包含 3 个容器的 ECS 任务 - postgres、redis 和来自私有 ECR 存储库的图像。 自定义图像容器定义有一个命令等待 postgres 容器可以通过 bash 命令接收流量

"command": [
    "/bin/bash",
    "-c",
    "while !</dev/tcp/postgres/5432; do echo \"Waiting for postgres database to start...\"; /bin/sleep 1; done; /bin/sh /app/start-server.sh;"
],

当我通过 docker 在我的本地机器上通过docker-compose运行它时,它可以工作,但在 Amazon Linux 2 EC2 机器上,这是在 while 循环运行时打印的:

/bin/bash: 第 1 行:postgres: 名称或服务未知

/bin/bash: 第 1 行:/dev/tcp/postgres/5432: 无效参数

postgres 容器运行没有错误,该容器的最后一个日志是

数据库系统已准备好接受连接

我不确定这是 docker 网络问题还是 amazon linux 2 的 bash 未使用--enable-net-redirections编译的问题,我在此处找到了解释

任务定义:

{
    "networkMode": "bridge",
    "containerDefinitions": [
        {
            "environment": [
                {
                    "name": "POSTGRES_DB",
                    "value": "metadeploy"
                },
                {
                    "name": "POSTGRES_USER",
                    "value": "<redacted>"
                },
                {
                    "name": "POSTGRES_PASSWORD",
                    "value": "<redacted>"
                }
            ],
            "essential": true,
            "image": "postgres:12.9",
            "mountPoints": [],
            "name": "postgres",
            "memory": 1024,
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "metadeploy-postgres",
                    "awslogs-region": "us-east-1",
                    "awslogs-create-group": "true",
                    "awslogs-stream-prefix": "mdp"
                }
            }
        },
        {
            "essential": true,
            "image": "redis:6.2",
            "name": "redis",
            "memory": 1024
        },
        {
        "command": [
            "/bin/bash",
            "-c",
            "while !</dev/tcp/postgres/5432; do echo \"Waiting for postgres database to start...\"; /bin/sleep 1; done; /bin/sh /app/start-server.sh;"
        ],
            "environment": [
                {
                    "name": "DJANGO_SETTINGS_MODULE",
                    "value": "config.settings.local"
                },
                {
                    "name": "DATABASE_URL",
                    "value": "<redacted-postgres-url>"
                },
                {
                    "name": "REDIS_URL",
                    "value": "redis://redis:6379"
                },
                {
                    "name": "REDIS_HOST",
                    "value": "redis"
                }
            ],
            "essential": true,
            "image": "the private ecr image uri built from here https://github.com/SFDO-Tooling/MetaDeploy",
            "links": [
                "redis"
            ],
            "mountPoints": [
                {
                    "containerPath": "/app/node_modules",
                    "sourceVolume": "AppNode_Modules"
                }
            ],
            "name": "web",
            "portMappings": [
                {
                    "containerPort": 8080,
                    "hostPort": 8080
                },
                {
                    "containerPort": 8000,
                    "hostPort": 8000
                },
                {
                    "containerPort": 6006,
                    "hostPort": 6006
                }
            ],
            "memory": 1024,
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "metadeploy-web",
                    "awslogs-region": "us-east-1",
                    "awslogs-create-group": "true",
                    "awslogs-stream-prefix": "mdw"
                }
            }
        }
    ],
    "family": "MetaDeploy",
    "volumes": [
        {
            "host": {
                "sourcePath": "/app/node_modules"
            },
            "name": "AppNode_Modules"
        }
    ]
}

对应docker-compose.yml包含:

version: '3'

services:
  postgres:
    environment:
      POSTGRES_DB: metadeploy
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: sample_db_password
    volumes:
      - ./postgres:/var/lib/postgresql/data:delegated
    image: postgres:12.9
    restart: always

  redis:
    image: redis:6.2

  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: |
      /bin/bash -c 'while !</dev/tcp/postgres/5432; do echo "Waiting for postgres database to start..."; /bin/sleep 1; done; \
      /bin/sh /app/start-server.sh;'
    ports:
      - '8080:8080'
      - '8000:8000'
      # Storybook server
      - '6006:6006'
    stdin_open: true
    tty: true
    depends_on:
      - postgres
      - redis
    links:
      - redis
    environment:
      DJANGO_SETTINGS_MODULE: config.settings.local
      DATABASE_URL: postgres://postgres:sample_db_password@postgres:5432/metadeploy
      REDIS_URL: redis://redis:6379
      REDIS_HOST: redis
    volumes:
      - .:/app:cached
      - /app/node_modules

我是否需要重新编译 bash 才能使用--enable-net-redirections ,如果需要我该怎么做?

如果没有 bash 的网络重定向功能,最好的办法是使用ncnetcat (如果可用)之类的东西来确定端口是否打开。 如果这些不可用,可能值得修改您的应用程序逻辑以更好地处理数据库故障情况。

或者,一种可能更好的方法是:

  1. healthcheck图像添加健康postgres
  2. 修改web服务的depends_on子句“长语法”以添加对postgres的依赖性service_healthy而不是默认的service_started

这种方法有两个主要好处:

  1. postgres映像可能具有检测数据库是否已启动并正在运行的工具。
  2. web服务不再需要手动检查数据库是否准备就绪。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM