在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部分,硬编码的行号可能会在您的环境中有所不同。