【问题标题】:Exposing ports in Docker won't work在 Docker 中暴露端口不起作用
【发布时间】:2016-12-14 04:12:54
【问题描述】:

我正在尝试使用 Docker 和 Selenium Grid 设置一个自动化测试平台。在下图中,您可以看到我正在使用的结构。最上面是在 Compute Engine 上运行的 ubuntu 服务器。左边是一个运行 ubuntu 14.04 的 docker 容器。该容器使用 Google App Engine 在 localhost:8080 上运行我们的项目。右边是 Selenium Hub,有两个节点在 4444 端口上运行。

Docker and Selenium setup

这是运行 docker ps 时的输出:

CONTAINER ID        IMAGE                               COMMAND                  CREATED             STATUS              PORTS                     NAMES
f5ac6e3c8270        xxxxx/ubuntuport:14.04              "/bin/bash"              3 days ago          Up 13 seconds       0.0.0.0:32777->8080/tcp   drunk_kalam
4246ca0790db        eu.gcr.io/xxxxxx/selenium-chrome    "/bin/sh -c 'rm -rf /"   4 weeks ago         Up 3 days                                     evil_mahavira
8d06f90a1a84        eu.gcr.io/xxxxxx/selenium-firefox   "/bin/sh -c 'rm -rf /"   4 weeks ago         Up 3 days                                     nauseous_torvalds
dc548f638778        eu.gcr.io/xxxxxx/selenium-hub       "/opt/bin/entry_point"   4 weeks ago         Up 3 days           0.0.0.0:32770->4444/tcp   modest_khorana

如您所见,集线器和 ubuntu 容器都激活了端口,并从运行 docker 容器的 ubuntu 主机转发。我已经在 Google Compute Engine 中打开了这些端口。

在 docker 容器中,我使用 Google App Engine sdk 在本地运行我们的项目。使用 docker exec -it drunk_kalam bash 后,我激活了 App Engine 服务器。该命令从 docker 容器中运行。将来这将成为脚本的一部分,但由于这仍在进行中,因此它正在容器内运行。下面你可以看到项目正在运行:

root@f5ac6e3c8270:/# google_appengine/dev_appserver.py --php_executable_path=/usr/bin/php5-cgi --php_gae_extension_path=appengine-php-extension/modules/gae_runtime_module.so ./xxxxxxxxxxxxxxx/
INFO     2016-08-08 12:19:49,287 sdk_update_checker.py:229] Checking for updates to the SDK.
WARNING  2016-08-08 12:19:49,532 simple_search_stub.py:1146] Could not read search indexes from /tmp/appengine.xxxxxxxxxxx.root/search_indexes
INFO     2016-08-08 12:19:49,535 api_server.py:205] Starting API server at: http://localhost:39475
WARNING  2016-08-08 12:19:51,217 inotify_file_watcher.py:196] There are too many directories in your application for changes in all of them to be monitored. You may have to restart the development server to see some changes to your files.
INFO     2016-08-08 12:19:51,218 dispatcher.py:197] Starting module "default" running at: http://localhost:8080
INFO     2016-08-08 12:19:51,220 admin_server.py:116] Starting admin server at: http://localhost:8000

问题是我无法通过端口 8080 访问项目。我已经在 Dockerfile 中公开了该端口,并且尝试使用 -P 标志和 -p 8080 标志运行容器。像这样:

docker run -dPi xxxxx/ubuntuport:14.04

我已经使用完全相同的命令启动了 selenium hub,并且该端口是可访问的。运行以下命令时:

nmap -p 4444 172.17.0.3

我得到以下输出:

Nmap scan report for 172.17.0.3
Host is up (0.00010s latency).
PORT     STATE SERVICE
4444/tcp open  krb524
Nmap done: 1 IP address (1 host up) scanned in 0.03 seconds

当我在运行项目的 docker 容器上在 8080 上运行 nmap 时,我得到以下输出:

Nmap scan report for 172.17.0.2
Host is up (0.000085s latency).
PORT     STATE  SERVICE
8080/tcp closed http-proxy
Nmap done: 1 IP address (1 host up) scanned in 0.03 seconds

我相信问题出在 ubuntu 容器的 Dockerfile 中。下面你可以看到Dockerfile,它是来自官方ubuntu仓库的dockerfile,添加了EXPOSE 8080这一行。

FROM scratch
ADD ubuntu-trusty-core-cloudimg-amd64-root.tar.gz /

EXPOSE 8080

# a few minor docker-specific tweaks
# see https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap
RUN set -xe \
    \
    && echo '#!/bin/sh' > /usr/sbin/policy-rc.d \
    && echo 'exit 101' >> /usr/sbin/policy-rc.d \
    && chmod +x /usr/sbin/policy-rc.d \
    \
    && dpkg-divert --local --rename --add /sbin/initctl \
    && cp -a /usr/sbin/policy-rc.d /sbin/initctl \
    && sed -i 's/^exit.*/exit 0/' /sbin/initctl \
    \
    && echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \
    \
    && echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \
    && echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \
    && echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \
    \
    && echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \
    \
    && echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes \
    \
    && echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests

RUN rm -rf /var/lib/apt/lists/*

RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list

CMD ["/bin/bash"]

用于暴露端口的命令与 Selenium Hub 相同,只是端口号不同。我似乎无法弄清楚为什么这个端口保持关闭。任何帮助将不胜感激。

提前致谢

泰恩

【问题讨论】:

    标签: selenium ubuntu docker


    【解决方案1】:

    来自您的输出:0.0.0.0:32777->8080/tcp。也就是说,侦听所有接口的端口 32777 将被映射(使用 NAT 和 docker-proxy)到容器内的端口 8080。因此,您需要访问端口 32777 而不是 8080。这种随机端口映射发生在您公开端口并与 -P 共享时。

    如果你想共享一个特定的端口而不是随机映射,你可以用小写的p选项定义它:-p 8080:8080甚至-p 8888:8080,将8888端口映射到容器的8080端口。


    从聊天会话中可以看出,这是应用程序在容器内的环回上监听。使用netstat -lnt,它显示:

    tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 
    

    更新应用程序以绑定到 0.0.0.0 允许端口转发按预期工作。

    【讨论】:

    • 我可以访问 32777 端口。但是映射不起作用,因为 8080 端口已关闭。因此我的 ubuntu 主机无法访问 Docker 容器。我也尝试将它映射到非随机端口上,但是 docker 容器上的 8080 端口保持关闭的事实并没有改变。
    • 8080 端口应该监听什么?从您的 ps 输出中,您启动了 bash。 shell 本身不会监听网络流量。
    • 在 docker 容器中,我使用 Google App Engine sdk 在本地运行我们的网站。这在端口 8080 上处于活动状态。如果没有它在端口 8080 上侦听,我将无法访问它。澄清一下:Selenium 集线器应该在 Docker 容器的本地主机上运行测试。
    • 你所有的命令都表明你启动了一个 bash shell,并且容器内没有任何东西在监听端口 8080。请更新问题,详细说明这个容器是如何构建的,用于启动的命令容器,并在此容器中执行docker exec 以显示应用程序正在运行。
    • 您似乎正在通过docker exec 运行您的应用程序,并且在您启动容器时它没有运行。这是你想要的行为吗? “我相信问题出在 Dockerfile 的某个地方。”如果不包含会重新创建您的问题的 Dockerfile,则很难在此处提供帮助。
    猜你喜欢
    • 2019-02-01
    • 2018-09-03
    • 2019-10-24
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多