在 AWS Elastic Beanstalk 应用程序中 运行 a Tomcat Docker 中的端口转发

Port forwarding in when running a Tomcat Docker in an AWS Elastic Beanstalk application

我在 AWS Elastic Beanstalk[=70] 上的 docker 容器内有一个 Tomcat 7.0 webapp 运行 =] (EB)(我按照教程 here)。

当我浏览到我的 EB url myapplication.elasticbeanstalk.com 时,我得到一个由 nginx 提供的 502 Bad Gateway。所以很明显我的端口 80 没有转发到我的容器。当我浏览到 myapplication.elasticbeanstalk.com:8888(我在 Docker 文件中公开的另一个端口)时,连接被拒绝 (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 容器上打开。

我的Docker文件相当简单:

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 上打开。 任何建议将不胜感激!我在这里不知所措。

更新 1:

次要更新,但我仍然遇到问题。 SSH 进入我的 AWS EB 实例后,我检查了 Docker 容器以获取容器的 IP:

sudo docker inspect c353e236da7a

这给了我 172.17.0.6.

的 IP

然后,再次从 AWS 实例,我 运行 一个 curl 命令:

curl 172.17.0.6:8080/homepage 

哪个有效,returns首页HTML!但是,curl 172.17.0.6:8888/homepage 不起作用(所以我不确定 "ContainerPort" : "8888"Dockerrun.aws.json 文件中的含义)。

但是,我仍然有一个问题,为什么我的 :8080 请求没有被转发到容器 Tomcat 网络服务器?如上,myapplication.elasticbeanstalk.com:8080/homepage 仍然收到拒绝连接 (ERR_CONNECTION_REFUSED).

myapplication.elasticbeanstalk.com 是负载均衡器,而不是您的实例。 Elastic beanstalk 启动一个负载均衡器来自动缩放您的实例。因此,当您连接到 myapplication.elasticbeanstalk.com:8888 时,您实际上是在连接到一个只打开了端口 80 的实例。然后负载均衡器将流量转发到侦听端口 8080 的实例。

您应该能够通过 url 访问您的 Web 应用程序而无需端口:myapplication.elasticbeanstalk.com

这不起作用的原因是因为你告诉你的 docker 容器使用端口 8080,但是告诉 Beanstalk 转发到端口 8888。当然,你所有的端口都是开放的,但是 tomcat 仅在端口 8080 上 运行ning。

dockerrun.aws.json 中的端口部分不会告诉您的应用要 运行 哪个端口,它会告诉负载均衡器要转发到哪个端口。

Ports – (required when you specify the Image key) Lists the ports to expose on the Docker container. AWS Elastic Beanstalk uses ContainerPort value to connect the Docker container to the reverse proxy running on the host.

You can specify multiple container ports, but AWS Elastic Beanstalk uses only the first one to connect your container to the host's reverse proxy and route requests from the public Internet.

如所见here.

或者,换句话说,您告诉 beantalk 转发到的 8888 工作正常,但您的应用程序实际上 运行ning 在端口 8080 上。您应该更改 dockerrun.aws.json 以使用改为 8080 端口。

我通过修复 nginx 的侦听端口完成了这项工作。 因此,您必须将 .ebextensions 目录添加到应用程序的根目录中,并将您的配置文件放在这里(在我的示例中,它是 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 部分,有硬编码的行号,可能因您的环境而异。