docker - 运行 apache 时可以连接到 docker 容器,但在端口 80 上运行 netcat 时不能
问题描述
我正在使用 Debian 软件包运行 Debian 服务器(稳定) 。这docker.io
是 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
解决方案
Apache 没有监听172.17.0.1
,这是主机的地址(在 docker 桥中)。
在 netstat 输出中,本地地址已解析为12b8fd142e00
. 使用-n
带有 netstat 的选项来查看未解析的(数字)地址(例如netstat -plnet
查看监听套接字)。172.17.0.1
是连接到 Apache 的外部地址(它确实是主机)。
netstat 输出的最后一行显示某个进程连接到 151.101.48.204:80,可能是为了发出 HTTP 请求。您可以使用 . 查看进程的 PID/名称netstat -p
。
推荐阅读
- jquery - jQuery 选择器格式化
- javascript - 如何使用 JavaScript 将一个输入字段中收集的数组数据传递给另一个输入字段而不丢失数组属性?
- java - com.android.builder.dexing.DexArchiveMergerException:合并 dex 档案时出错:
- aws-cli - AWS CodeDeploy :bucket 选项不得包含正斜杠 (/)
- java - 文件夹位置的字符串中的字符串?
- c++ - GNU 缩进:它是否支持 C++
- python-3.x - 使用 Mac 设置 Jupyter Notebook 服务器
- java - 为什么 spark-submit 失败并显示“执行 Jupyter 命令时出错”?
- python - 如何在 QMainwindow 中替换 QWidget
- java - 我的 Java 程序中的“驱动程序无法解析”