Docker端口转发不起作用。

61

我已经设置了Docker容器,以便在本地将我的机器Docker容器访问另一台机器。

使用以下命令创建一个容器:

    docker run -it -d --name containerName -h www.myhost.net -v /var/www/html -p 7000:8000 --net mynetwork --ip 172.11.0.10 --privileged myimagename bash

创建容器后的详细信息:

        CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES

        1e1e5e9b74b4        myimgaename         "bash"              21 minutes ago      Up 6 minutes        0.0.0.0:7000->8000/tcp   containername

网络详细信息:

     "NetworkSettings": {
        "Bridge": "",
        "SandboxID": "fe357c54c816fff0f9d642037dc9a173be7f7e42a80776d006572f6a1395969e",
        "HairpinMode": false,
        "LinkLocalIPv6Address": "",
        "LinkLocalIPv6PrefixLen": 0,
        "Ports": {
            "8000/tcp": [
                {
                    "HostIp": "0.0.0.0",
                    "HostPort": "7000"
                }
            ]
        }
如果我在我的主机(hostmachine)上使用Docker的IP地址(172.11.0.10)或主机名(www.myhost.net)进行访问,则可以正常工作。但是,如果我使用端口进行访问,则无法正常工作:主机机器的IP地址为192.168.1.1。
  go to the browser  192.168.1.1:7000  hostmachine and locally connected anoter machine also.

但是我的7000端口在主机上正在监听:

        # ps aux | grep 7000
        root     10437  0.0  0.2 194792 24572 pts/0    Sl+  12:33   0:00 docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 7000 -container-ip 172.11.0.10 -container-port 8000
        root     10941  0.0  0.0 118492  2324 pts/3    R+   12:44   0:00 grep --color=auto 7000

更新1:

      $ docker version
        Client:
         Version:      1.11.2
         API version:  1.23
         Go version:   go1.5.4
         Git commit:   b9f10c9
         Built:        Wed Jun  1 21:39:21 2016
         OS/Arch:      linux/amd64

        Server:
         Version:      1.11.2
         API version:  1.23
         Go version:   go1.5.4
         Git commit:   b9f10c9
         Built:        Wed Jun  1 21:39:21 2016
         OS/Arch:      linux/amd64

请告诉我为什么无法从另一台机器访问我的容器,该如何解决这个问题。


1
你是使用Docker Toolbox还是本地Docker? - Shiraaz.M
@Shiraaz.M 我正在使用本地的 Docker,我使用命令行(fed23)安装它 dnf install docker。 - Rajkumar .E
13个回答

176

一个非常普遍的问题可能是这个:

将您的应用程序在Docker中绑定到0.0.0.0,而不是127.0.0.1地址,以便让Docker能够访问容器内部的应用程序。

UPD: 不要尝试使用docker解决此问题。没有docker命令可以解决该问题。它严格依赖于使用的应用程序、Web框架等。阅读容器中使用的工具手册。尝试搜索“如何将[使用框架]绑定到特定的地址和端口”。它可能是一个环境变量、cli参数、代码等。


28
这句话的意思是什么?请不要只使用英语。发布完整的Docker命令。 - mathtick
6
我明白了,应该是“告诉应用程序去绑定”而不是“告诉Docker去绑定应用程序”,知道了。 - mathtick
2
这是什么意思? - Shahid Karimi
6
简单解释:你的网络应用程序必须连接到IP地址,以便其他应用程序/浏览器/服务器/用户可以发现它并进行连接。0.0.0.0 IP地址意味着你的应用程序将连接到你拥有的所有IP地址。127.0.0.1 IP地址是私有的,不对外开放。由于你的应用程序在容器中运行,所以对于它来说,主机就是外部世界,因此你必须将socket连接到容器的外部地址0.0.0.0,以便让你的主机连接它。 - DenisKolodin
2
我正在使用Rails,需要使用bin/rails server --binding 0.0.0.0而不是bin/rails server - keineahnung2345
显示剩余12条评论

28

主机上的端口7000被重定向到容器中的端口8000,但容器中是否有任何东西在监听该端口?

您的docker run命令有点奇怪:-it用于交互式地运行一个带有终端的容器;-d用于在后台运行容器;最后的bash覆盖了镜像配置为启动命令的任何内容,这就是为什么我认为没有任何东西在端口8000上监听。

尝试使用以下命令运行最简单的NGINX容器:

docker run -d -p 8081:80 nginx:alpine

然后确认您能够访问主页:

curl http://localhost:8081
如果这个正常工作,那我会看看你如何运行图像。

6
在我的情况下,localhost:8081无法使用。我必须使用docker-machine ip default代替(192.168.99.100)。有任何想法为什么localhost无法工作吗? - user12384512
3
当你使用 Docker "本地化"时,容器与主机计算机"绑定"在一起,因此你使用localhost。当你使用 Docker Toolbox 这样的替代方案时,Docker 在一个虚拟机内运行,因此容器与虚拟机的 localhost相"绑定",你需要使用它的 IP 地址(通常为192.168.99.100)。 - TBG

3

我在使用Docker for Mac时也遇到了这个问题。点击Docker图标,然后选择重新启动即可解决。


3

对于在docker容器中运行serverless-offline的任何人:

我试图将我的mac上的localhost:3000映射到默认的serverless-offline应用程序端口3000(该端口在docker内运行),并通过以下方式实现了期望的结果:

(1) 在通常的serverless离线命令中添加--host:0.0.0.0,如下所示:

serverless offline --host 0.0.0.0

(2) 然后使用常规端口映射运行docker容器:

docker run -p 3000:3000 <your-image-name>

注意:在运行之前,需要重建我的镜像以确保一切正常运行。


1

您好,我遇到了一个问题,我正在使用Dockerfile构建镜像。我发现我无法将地址设置为特定的IP地址,这意味着在更改后

    srv := &http.Server{
    Handler: s,
    Addr:    "127.0.0.1:5000",
}

    srv := &http.Server{
    Handler: s,
    Addr:    ":5000",
}

命令docker run -dp 5000:5000 --name myapiserver api_server:v1正常工作。我可以无问题地访问容器端口5000。所以总之,在容器中,您只能设置服务器的端口吗?
更新
127.0.0.1是主机不会发送到外部的IP地址,正确处理方式是通过所有IP地址发送,即0:0:0:0或简写为仅端口。

0

经过数千小时的解决问题,我终于用这种愚蠢的方法解决了它:

  1. 卸载 docker:

sudo yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine docker-ce

  1. 更新我的 CentOS 系统:

    yum -y update

  2. 重启

  3. 重新安装 docker

  4. 重新安装容器/镜像

现在它像魔法一样运行。


0

您可以使用docker run -d -p 127.0.0.1:9000:4000 --name some-container some-image-name或者使用-it标志。


0

可能的一个问题是您的容器正在使用IPV6,在运行容器之后,例如如果您正在使用以下内容运行容器>

docker run -it -p 8080:80 --name mycontainer myimage

然后在您的主机机器的bash中运行此命令 >

sudo netstat -tulpn | grep :8080

如果输出中有tcp6,那么意味着您的容器正在使用IPV6。


0

非常简单,只需通过docker-machine ip检查docker的IP地址

通常为192.168.99.100

首先创建一个docker容器并运行它 docker run -d -p 8081:80 nginx:alpine

然后在浏览器上运行http://192.168.99.100:8081/


1
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

0

我在Docker Wordpress容器中遇到了这个问题。

故障排除:

在Docker主机上执行curl -Is http://192.168.X.X会返回预期结果,但在不同子网的笔记本电脑上执行相同的命令会一直挂起。

同样,在Docker主机上,telnet 192.168.X.X 80可以连接到80端口,但在Docker主机外部无法连接,也会一直挂起。

docker logs containerName没有提供有用的线索。

在路由器的防火墙上,我允许了Docker主机和我的笔记本电脑之间的所有内容,以确保路由器的防火墙不会破坏端口80的连接。

解决方案:

为了减少复杂性,我决定从docker run命令中删除自定义网络。

与OP一样,我在docker run命令中指定了自己的自定义网络和IP地址。但是当我从docker run命令中删除--net--ip时,容器使用默认桥接和Docker DHCP分配的地址启动。

测试解决方案:

我使用以下命令找到了我的WordPress容器的IP地址:

docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' wordpressContainerName

我尝试在我的笔记本电脑上的浏览器中加载WordPress。容器现在可以通过不同子网上的Docker主机外部转发端口80进行联系。

结论:

docker run命令中删除--net--ip可以解决我的问题;当然,你的情况可能会有所不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接