无法将多容器 docker 部署到 ElasticBeanstalk
Posted
技术标签:
【中文标题】无法将多容器 docker 部署到 ElasticBeanstalk【英文标题】:Failed to deploy multi-containers docker to 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
?
【参考方案1】:
EB 的 Docker 平台支持 docker-compose.yml,如 Docker environment with Docker Compose 中所述:
创建 docker-compose.yml 文件以将 Docker 映像从托管存储库部署到 Elastic Beanstalk。如果您的所有部署都来自公共存储库中的图像,则不需要其他文件。
所以你可能只需要Dockerrun.aws.json v3
到enable access to private docker registry。
【讨论】:
我的图像在 ECR 中。所以我还需要 dockerrun 对吗? @EinnHann 应通过 EB 实例角色启用对 ECR 的访问。所以不需要dockerrun。 这意味着在我的 docker-compose 中我可以在 ECR 中指定 docker 镜像? @EinnHann 我相信。你试过吗?有什么错误吗? 是的,我试过了。我收到此错误错误在环境中找不到 ecs 任务定义(或空定义文件)。它抱怨找不到 dockerrun.aws.json。【参考方案2】:-
确保您的绑定地址正确(您打算使用的 IP 地址的主机名)
确保 JDBC 端口号正确
确保为相关端口打开安全组
当然,请验证数据库的用户名和密码
【讨论】:
我正在使用这个 spring.datasource.url=jdbc:mysql://db:3306/sbapi?allowPublicKeyRetrieval=true&useSSL=false,所以主机名是 dockerrun.aws.js 中的 db。用户名和密码也正确。 但我认为错误是无法连接MySQL。只是我不确定哪个配置出错了。 是有道理的,它消除了#1 和#2。你能确认是否有基本的连接 - 比如你能卷曲或 ping 你的数据库吗?很有可能是安全组(上面提到的#3)阻止了它 只是好奇,因为它在多个容器中,所以我还需要设置安全组吗? 我说的是数据库,我假设这是一个在 AWS 上运行的实例,它需要安全组 3306,允许其他 80 个。以上是关于无法将多容器 docker 部署到 ElasticBeanstalk的主要内容,如果未能解决你的问题,请参考以下文章
将 Perl Docker 容器部署到 Elastic Beanstalk
无法访问 jarfile - Elastic Beanstalk 上的 Docker
在 Elastic Beanstalk 上部署 Docker 环境
如何将具有多个 Docker 容器的应用程序部署到 AWS Elastic Beanstalk?