【问题标题】:Failed to deploy multi-containers docker to ElasticBeanstalk无法将多容器 docker 部署到 ElasticBeanstalk
【发布时间】:2021-10-26 02:04:14
【问题描述】:

我试图将多容器 docker 部署到 Elastic Beanstalk 中。但它不起作用。我尝试使用正在运行的 docker-compose 在本地运行。

下面是我的 Dockerrun.aws.json 和 docker-compose.yml

docker-compose.yml

version: '3'

services:
   nginx:
      image: nginx:alphine
      restart: always
      ports:
      - 80:80
      volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      depends_on:
      - sbapi
   db:
      image: mysql:latest
      environment:
      - MYSQL_ROOT_PASSWORD=P@ssw0rd
      - MYSQL_DATABASE=sbapi
      - MYSQL_USER=user
      - MYSQL_PASSWORD=password
      ports:
      - 3306:3306
      restart: always
      volumes:
      - mysql-data:/var/lib/mysql
   sbapi:
      image: sbapi
      build:
         context: ./
         dockerfile: Dockerfile
      ports:
      - 8080:8080
      restart: always
      volumes:
      - ./app:/app
      depends_on:
      - db
      
volumes:
  mysql-data:

Dockerrun.aws.json

 {
   "AWSEBDockerrunVersion":2,
   "containerDefinitions":[
      {
         "name":"db",
         "hostname": "db",
         "image":"mysql:latest",
         "essential":true,
         "memory":512,
         "environment": [
            {
                "name": "MYSQL_ROOT_PASSWORD",
                "value": "P@ssw0rd"
            },
            {
                "name": "MYSQL_DATABASE",
                "value": "sbapi"
            },
            {
                "name": "MYSQL_USER",
                "value": "user"
            },
            {
                "name": "MYSQL_PASSWORD",
                "value": "password"
            }
         ],
         "portMappings":[
            {
               "hostPort":3306,
               "containerPort":3306
            }
         ],
         "mountPoints":[
            {
               "containerPath":"/var/lib/mysql",
               "sourceVolume":"mysql-data"
            }
         ]
      },
      {
         "name":"sbapi",
         "hostname": "sbapi",
         "essential":true,
         "image":"xxxxxxxxxxxxxxxx.dkr.ecr.ap-southeast-1.amazonaws.com/sbapi",
         "memory":512,
         "portMappings":[
            {
               "hostPort":8080,
               "containerPort":8080
            }
         ],
         "links": [
            "db"
         ]
      },
      {
         "name":"nginx",
         "image":"nginx:alpine",
         "essential":true,
         "memory": 128,
         "portMappings":[
            {
               "hostPort":80,
               "containerPort":80
            }
         ],
         "mountPoints":[
            {
               "containerPath":"/etc/nginx/conf.d",
               "sourceVolume":"nginx-data"
            }
         ],
         "links":[
            "sbapi"
         ]
      }
   ],
   "family": "",
   "volumes":[
      {
         "host":{},
         "name":"mysql-data"
      },
      {
         "name": "nginx-data",
         "host": {
            "sourcePath": "/var/app/current/nginx/conf.d"
         }
      }
   ]
}

这是我的 nginx.stouterr.log。不知道会不会自动关机。

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged version
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2021/08/26 00:21:11 [notice] 1#1: using the "epoll" event method
2021/08/26 00:21:11 [notice] 1#1: nginx/1.21.1
2021/08/26 00:21:11 [notice] 1#1: built by gcc 8.3.0 (Debian 8.3.0-6) 
2021/08/26 00:21:11 [notice] 1#1: OS: Linux 4.14.238-125.422.amzn1.x86_64
2021/08/26 00:21:11 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 133489:133489
2021/08/26 00:21:11 [notice] 1#1: start worker processes
2021/08/26 00:21:11 [notice] 1#1: start worker process 30
2021/08/26 00:21:11 [notice] 1#1: start worker process 31
2021/08/26 00:21:11 [notice] 1#1: signal 3 (SIGQUIT) received, shutting down
2021/08/26 00:21:11 [notice] 30#30: gracefully shutting down
2021/08/26 00:21:11 [notice] 30#30: exiting
2021/08/26 00:21:11 [notice] 30#30: exit
2021/08/26 00:21:11 [notice] 31#31: gracefully shutting down
2021/08/26 00:21:11 [notice] 31#31: exiting
2021/08/26 00:21:11 [notice] 31#31: exit
2021/08/26 00:21:11 [notice] 1#1: signal 17 (SIGCHLD) received from 30
2021/08/26 00:21:11 [notice] 1#1: worker process 30 exited with code 0
2021/08/26 00:21:11 [notice] 1#1: worker process 31 exited with code 0
2021/08/26 00:21:11 [notice] 1#1: exit

我检查了 ECS,一开始有 3 个容器正在运行。但后来,所有状态都变为停止,并再次产生另一个新任务。

我还收到错误“连接被拒绝”,无法从我的 Spring Boot 应用程序连接 MySQL。

Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[na:na]
    at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source) ~[na:na]
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-java-8.0.23.jar!/:8.0.23]
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-java-8.0.23.jar!/:8.0.23]
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) ~[mysql-connector-java-8.0.23.jar!/:8.0.23]
    at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) ~[mysql-connector-java-8.0.23.jar!/:8.0.23]
    at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) ~[mysql-connector-java-8.0.23.jar!/:8.0.23]
    at com.mysql.cj.NativeSession.connect(NativeSession.java:144) ~[mysql-connector-java-8.0.23.jar!/:8.0.23]
    at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:953) ~[mysql-connector-java-8.0.23.jar!/:8.0.23]
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:823) ~[mysql-connector-java-8.0.23.jar!/:8.0.23]
    ... 58 common frames omitted
Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:na]
    at java.base/java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) ~[na:na]
    at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) ~[na:na]
    at java.base/java.net.AbstractPlainSocketImpl.connect(Unknown Source) ~[na:na]
    at java.base/java.net.SocksSocketImpl.connect(Unknown Source) ~[na:na]
    at java.base/java.net.Socket.connect(Unknown Source) ~[na:na]
    at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:155) ~[mysql-connector-java-8.0.23.jar!/:8.0.23]
    at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) ~[mysql-connector-java-8.0.23.jar!/:8.0.23]
    ... 61 common frames omitted

这是我的 application.properties

spring.datasource.url=jdbc:mysql://db:3306/sbapi?allowPublicKeyRetrieval=true&useSSL=false
spring.datasource.username=user
spring.datasource.password=password

server.port = 8080

从本地运行 docker-compose up 时,我能够访问 API。但是,在部署到 Elastic Beanstalk 时,它不起作用。不知道是哪一部分出了问题,我很好奇为什么ECS会停止自己并一次又一次地重新生成新任务?

【问题讨论】:

  • ECS 服务有事件选项卡来检查消息。此外,如果任务停止,您可以在 ECS 控制台中查看其详细信息,并且通常还可以找到错误消息。
  • 是的,我已经检查过了,我什至进入 EC2 运行 docker。不知何故,我收到此错误原因:java.net.UnknownHostException:db:系统错误。
  • 我试过 docker ps 我可以看到 mysql 正在运行。 59d6bf11b1ba mysql:latest "docker-entrypoint.s…" 34 分钟前 Up 34 分钟 0.0.0.0:3306->3306/tcp, 33060/tcp
  • 我尝试 exec 进入 mysql 容器并检查主机 root@db:/etc# cat hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00: :0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.2 db
  • 如果你有 docker compose,为什么要使用Dockerrun.aws.json

标签: mysql amazon-web-services spring-boot docker-compose amazon-elastic-beanstalk


【解决方案1】:

EB 的 Docker 平台支持 docker-compose.yml,如 Docker environment with Docker Compose 中所述:

创建 docker-compose.yml 文件以将 Docker 映像从托管存储库部署到 Elastic Beanstalk。如果您的所有部署都来自公共存储库中的图像,则不需要其他文件。

所以你可能只需要Dockerrun.aws.json v3enable access to private docker registry

【讨论】:

  • 我的图像在 ECR 中。所以我还需要 dockerrun 对吗?
  • @EinnHann 应通过 EB 实例角色启用对 ECR 的访问。所以不需要dockerrun。
  • 这意味着在我的 docker-compose 中我可以在 ECR 中指定 docker 镜像?
  • @EinnHann 我相信。你试过吗?有什么错误吗?
  • 是的,我试过了。我收到此错误错误在环境中找不到 ecs 任务定义(或空定义文件)。它抱怨找不到 dockerrun.aws.json。
【解决方案2】:
  1. 确保您的绑定地址正确(您打算使用的 IP 地址的主机名)
  2. 确保 JDBC 端口号正确
  3. 确保为相关端口打开安全组
  4. 当然,请验证数据库的用户名和密码

【讨论】:

  • 我正在使用这个 spring.datasource.url=jdbc:mysql://db:3306/sbapi?allowPublicKeyRetrieval=true&useSSL=false,所以主机名是 dockerrun.aws.js 中的 db。用户名和密码也正确。
  • 但我认为错误是无法连接MySQL。只是我不确定哪个配置出错了。
  • 是有道理的,它消除了#1 和#2。你能确认是否有基本的连接 - 比如你能卷曲或 ping 你的数据库吗?很有可能是安全组(上面提到的#3)阻止了它
  • 只是好奇,因为它在多个容器中,所以我还需要设置安全组吗?
  • 我说的是数据库,我假设这是一个在 AWS 上运行的实例,它需要安全组 3306,允许其他 80 个。
猜你喜欢
  • 2020-07-21
  • 1970-01-01
  • 2022-08-19
  • 2021-04-09
  • 2018-04-13
  • 2018-02-05
  • 2020-08-28
  • 2020-04-09
  • 2015-06-20
相关资源
最近更新 更多