Docker端口转发可在IPv6上运行,但不能在IPv4上运行 [英] Docker port fowarding working on IPv6 but not IPv4

查看:982
本文介绍了Docker端口转发可在IPv6上运行,但不能在IPv4上运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下非常简单的docker-compose.yml,可在Mac上运行:

I have the following very simple docker-compose.yml, running on a Mac:

version: "3.7"
services:
  apache:
    image: httpd:2.4.41
    ports:
      - 80:80

我运行 docker-compose up ,然后运行此 curl 然后Apache返回内容:

I run docker-compose up, then I run this curl and Apache returns content:

/tmp/test $ curl -v http://localhost
*   Trying ::1:80...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.66.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sat, 26 Oct 2019 18:30:03 GMT
< Server: Apache/2.4.41 (Unix)
< Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT
< ETag: "2d-432a5e4a73a80"
< Accept-Ranges: bytes
< Content-Length: 45
< Content-Type: text/html
< 
<html><body><h1>It works!</h1></body></html>
* Connection #0 to host localhost left intact

但是,如果我尝试使用127.0访问容器。 0.1而不是localhost,我拒绝连接:

However, if I try to access the container using 127.0.0.1 instead of localhost, I get connection refused:

/tmp/test $ curl -v http://127.0.0.1
*   Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connection failed
* connect to 127.0.0.1 port 80 failed: Connection refused
* Failed to connect to 127.0.0.1 port 80: Connection refused
* Closing connection 0
curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused

Localhost确实指向127.0.0.1:

Localhost does point to 127.0.0.1:

/tmp/test $ ping localhost
PING localhost (127.0.0.1): 56 data bytes

netstat显示要转发的所有本地IP地址端口80:

And netstat shows all local IP addresses port 80 to be forwarded:

/tmp/test $ netstat -tna | grep 80
...
tcp46      0      0  *.80                   *.*                    LISTEN     
...

实际上,我试图使用我在 / etc / hosts 文件中指向127.0.0.1的自定义域来访问容器。我以为该域名有问题,但是后来我尝试了127.0.0.1,但也没有用,所以我认为关于docker的某些基本问题我没有做对。

I came to this actually trying to access the container using a custom domain I had on my /etc/hosts file pointing to 127.0.0.1. I thought there was something wrong with that domain name, but then I tried 127.0.0.1 and didn't work either, so I'm concluding there is something very basic about docker I'm not doing right.

为什么 curl http:// localhost 起作用,但是 curl http://127.0.0.1 起作用

Why is curl http://localhost working but curl http://127.0.0.1 is not?

更新

似乎本地主机正在解析为IPv6 :: 1 ,因此端口转发似乎在IPv6上有效,但在IPv4地址上无效。

It seems localhost is resolving to IPv6 ::1, so port forwarding seems to be working on IPv6 but not IPv4 addresses. Does that make any sense?

UPDATE 2

我无法修复它,但指向我的域名称改为 :: 1 而不是 / etc / hosts中的 127.0.0.1 code>暂时可以作为解决方法。

I wasn't able to fix it, but pointing my domain name to ::1 instead of 127.0.0.1 in my /etc/hosts serves as a workaround for the time being.

更新3

8个月后,我碰到了陷入同一问题,并在这里找到我自己的问题,但仍未得到答复。但是这次我不能应用相同的解决方法,因为我需要将端口转发绑定到我的IPv4地址,以便可以从其他主机访问它。

8 months later I bumped into the same issue and found my own question here, still unanswered. But this time I can't apply the same workaround, because I need to bind the port forwarding to my IPv4 address so it can be accessed from other hosts.

推荐答案

找到了罪魁祸首: pfctl

AFAIK, pfctl 不应该自动运行,但我的 /System/Library/LaunchDaemons/com.apple.pfctl.plist 则表示相反。

AFAIK, pfctl is not supposed to run automatically but my /System/Library/LaunchDaemons/com.apple.pfctl.plist said otherwise.

Packet Filtering已配置为将端口80上的所有传入流量重定向到8080,将443重定向到8443。而且在没有任何进程实际侦听端口80和443的情况下完成了此操作,这就是 lsof netstat 不会显示任何内容。

The Packet Filtering was configured to redirect all incoming traffic on port 80 to 8080, and 443 to 8443. And this is done without any process actually listening to port 80 and 443, that's why lsof and netstat wouldn't show anything,.

/ Library / LaunchDaemons / it。 winged.httpdfwd.plist 具有以下

 <key>ProgramArguments</key>
 <array>
  <string>sh</string>
  <string>-c</string>
  <string>echo "rdr pass proto tcp from any to any port {80,8080} -> 127.0.0.1 port 8080" | pfctl -a "com.apple/260.HttpFwdFirewall" -Ef - &amp;&amp; echo "rdr pass proto tcp from any to any port {443,8443} -> 127.0.0.1 port 8443" | pfctl -a "com.apple/261.HttpFwdFirewall" -Ef - &amp;&amp; sysctl -w net.inet.ip.forwarding=1</string>
 </array>
 <key>RunAtLoad</key>

解决方案只是侦听端口8080和8443。所有对端口80和443的请求现在都透明地重定向。

The solution was simply to listen on ports 8080 and 8443. All requests to ports 80 and 443 are now being redirected transparently.

在调试时,我发现了无数关于类似问题的未解决问题。我希望这对某人有帮助。

While debugging this I found countless open questions about similar problems without answers. I hope this helps somebody.

这篇关于Docker端口转发可在IPv6上运行,但不能在IPv4上运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆