可以在运行apache时连接到docker容器,但是当它在端口80上运行netcat时却不能

时间:2018-05-15 14:35:51

标签: docker

我正在使用docker.io Debian软件包运行Debian服务器(稳定版)。这是由Debian发布的,而不是Docker开发人员发布的。由于docker.io仅在sid中可用,因此我已从那里安装(apt install -t unstable docker.io)。

我的防火墙允许连接到/来自docker容器:

$ sudo ufw status
(...)
Anywhere                   ALLOW       172.17.0.0/16             
172.17.0.0/16              ALLOW       Anywhere                  

我也在/etc/ufw/before.rules

中有这个
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 172.17.0.0/16    -o eth0 -j MASQUERADE

所以 - 我用

创建了一个图像
$ sudo debootstrap stable ./stable-chroot http://deb.debian.org/debian > /dev/null
$ sudo tar -C stable-chroot -c . | docker import - debian-stable

然后启动了一个容器并安装了apache2和netcat。主机上的端口1111将重定向到容器上的端口80:

$ docker run -ti -p 1111:80 debian-stable bash
root@dc4996de9fe6:/# apt update
(... usual output from apt update ...)
root@dc4996de9fe6:/# apt install apache2 netcat
(... expected output, installation successful ...)
root@dc4996de9fe6:/# service apache2 start
root@dc4996de9fe6:/# service apache2 status
[ ok ] apache2 is running.

从主机我可以连接到apache服务器:

$ curl 127.0.0.1:1111
(... HTML from the Debian apache placeholder page ...)
$ telnet 127.0.0.1 1111
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.

它等待我输入(如果我输入GET /我得到Debian apache占位符页面)。好。如果我在容器内停止apache,

root@06da401a5724:/# service apache2 stop
[ ok ] Stopping Apache httpd web server: apache2.
root@06da401a5724:/# service apache2 status
[FAIL] apache2 is not running ... failed!

然后将拒绝与主机上端口1111的连接(如预期的那样):

$ telnet 127.0.0.1 1111
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Connection closed by foreign host.

现在,如果我在容器上启动netcat,则侦听端口80:

root@06da401a5724:/# nc -l 172.17.0.2 80

然后我无法与主持人联系!

$ telnet localhost 1111
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

如果我在容器中尝试nc -l 127.0.0.1 80,也会发生同样的情况。

可能会发生什么? apache和netcat都在端口80上搜索。我错过了什么? 我很欣赏任何提示......

更新:如果我试试这个:

root@12b8fd142e00:/# nc -vv -l -p 80
listening on [any] 80 ...
172.17.0.1: inverse host lookup failed: Unknown host
invalid connection to [172.17.0.2] from (UNKNOWN) [172.17.0.1] 54876

然后它有效!

现在它很奇怪......容器内的ifconfig告诉我它有IP 172.17.0.2,但我只能使用netcat绑定到172.17.0.1

root@12b8fd142e00:/# ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe11:2  prefixlen 64  scopeid 0x20<link>

而Apache似乎想要172.17.0.2代替:

2AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message

但它实际上使用172.17.0.1

root@12b8fd142e00:/# netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 12b8fd142e00:http       172.17.0.1:54942        TIME_WAIT  
tcp        0      0 12b8fd142e00:39528      151.101.48.204:http     TIME_WAIT  

1 个答案:

答案 0 :(得分:2)

Apache没有监听172.17.0.1,这是主机的地址(在docker网桥中)。

在netstat输出中,本地地址已解析为12b8fd142e00。使用netstat的-n选项查看未解析的(数字)地址(例如netstat -plnet以查看侦听套接字)。 172.17.0.1是连接到Apache的外部地址(它确实是主机)。

netstat输出中的最后一行显示某个进程建立了与151.101.48.204:80的连接,可能是为了发出HTTP请求。您可以使用netstat -p查看进程的PID /名称。