在AWS Elastic Beanstalk应用程序中运行Tomcat Docker时进行端口转发
我有一个运行在AWS Elastic Beanstalk (EB)上的docker容器内的Tomcat 7.0 webapp(我在这里跟着教程)。
当我浏览到我的EBurlmyapplication.elasticbeanstalk.com时 ,我得到了由Nginx服务的502 Bad Gateway
。 所以立即清楚,我的端口80没有转发到我的容器。 当我浏览到myapplication.elasticbeanstalk.com:8888 (我在Dockerfile中公开的另一个端口)时,连接被拒绝( ERR_CONNECTION_REFUSED
)。 所以我SSH到AWS实例,并检查docker日志,这表明我的Tomcat服务器已成功启动,但显然还没有处理任何请求。
有没有人有任何想法我的端口8888似乎没有转发到我的容器?
执行命令(在AWS实例上):
sudo docker ps -a
得到:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c353e236da7a aws_beanstalk/current-app:latest "catalina.sh run" 28 minutes ago Up 13 minutes 80/tcp, 8080/tcp, 8888/tcp sharp_leakey
显示端口80,8080和8888在docker集装箱上打开。
我的Dockerfile非常简单:
FROM tomcat:7.0 EXPOSE 8080 EXPOSE 8888 EXPOSE 80
和我的Dockerrun.aws.json文件是:
{ "AWSEBDockerrunVersion": "1", "Image": { "Name": "myusername/mycontainer-repo" }, "Authentication": { "Bucket": "mybucket", "Key": "docker/.dockercfg" }, "Ports": [ { "ContainerPort": "8888" } ] }
有没有人看到我可能会出错? 我甚至不知道在哪里看这个问题。
另外,我的AWS安全组的实例在端口80,8080和8888上打开。任何build议将不胜感激! 我在这里不知所措
更新1:
小的更新,虽然我仍然有麻烦。 在SSH进入我的AWS EB实例之后,我检查了Docker容器以获取容器的IP:
sudo docker inspect c353e236da7a
这给了我IP为172.17.0.6
。
然后,再次从AWS实例中,我运行了一个curl
命令:
curl 172.17.0.6:8080/homepage
哪个工作,并返回主页的HTML! 然而, curl 172.17.0.6:8888/homepage
不起作用(所以我不知道什么"ContainerPort" : "8888"
在Dockerrun.aws.json
文件中的Dockerrun.aws.json
)。
但是,我仍然有这个问题,为什么我的:8080
请求被转发到容器Tomcatnetworking服务器? 如上所述, myapplication.elasticbeanstalk.com : ERR_CONNECTION_REFUSED
仍然收到拒绝的连接( ERR_CONNECTION_REFUSED
)。
myapplication.elasticbeanstalk.com
是一个负载均衡器,而不是您的实例。 弹性beanstalk启动负载均衡器来自动调整您的实例。 因此,当您连接到myapplication.elasticbeanstalk.com:8888
您实际上正在连接到只有端口80打开的实例。 然后,负载均衡器将stream量传送到侦听端口8080的实例。
您只需使用不带端口的URL即可访问您的Web应用程序: myapplication.elasticbeanstalk.com
这是行不通的原因是因为你告诉你的docker容器使用端口8080,但告诉Beanstalk转到端口8888.当然,所有的端口是开放的,但tomcat只运行在端口8080。
dockerrun.aws.json
的ports部分并不告诉你的应用运行哪个端口,它告诉负载均衡器转发哪个端口。
端口 – (当您指定Image键时需要)列出Docker容器上公开的端口。 AWS Elastic Beanstalk使用ContainerPort值将Docker容器连接到主机上运行的反向代理。
您可以指定多个容器端口,但AWS Elastic Beanstalk只使用第一个容器将您的容器连接到主机的反向代理,并从公共Internet路由请求。
如这里所见。
或者换句话说,你告诉beanstalk转发的8888工作正常,但是你的应用实际上是在8080端口上运行的。你应该改变dockerrun.aws.json来使用端口8080
。
我使用nginx的监听端口来修复这个问题。 所以,你必须添加.ebextensions目录到你的应用程序的根目录,并把你的configuration文件放在这里(在我的例子中是00-bypass-nginx-proxy.config):
files: "/tmp/change_nginx_port.sh": mode: "000755" owner: root group: root content: | #!/bin/sh # change listen port from 80 to 8761 sed -i '7s/.*/ listen 8761;/' /etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf # restart nginx service nginx restart container_commands: 00setup-nginx: command: "/tmp/change_nginx_port.sh"
现在您的服务将在端口8761上提供。请注意脚本的sed
部分,硬编码的行号可能会在您的环境中有所不同。
- 将Elastic Beanstalk环境variables暴露给使用Docker的Laravel的技术人员
- Elastic Beanstalk CLI – 不replace部署上的实例
- 将Elastic Beanstalkconfiguration更改为Docker
- Docker部署失败的Elastic Beanstalk
- AWS Elastic Beanstalk中的多容器Dockerconfiguration版本错误
- Amazon Elastic Beanstalk vs使用docker容器的EC2实例
- ElasticBeanstalk:存放一个防弹的docker集装箱
- Elastic Beanstalk和Docker启动错误
- 如何从Elastic Beanstalk实例访问S3存储桶中的dockerconfiguration文件