我完全不知所措了。在 Leaseweb 虚拟服务器上从 Ubuntu 14.04 升级到 Ubuntu 16.04 后,docker 不再接受与本地主机的连接。使用原始 CouchBase 服务器映像,在我的笔记本电脑上运行以下命令可以完美运行(Docker 版本 1.12.1,内部版本 23cf638):
$ docker run --rm -ti --name couchbase-server -p 127.0.0.1:8091:8091 couchbase/server:community-4.5.0
Starting Couchbase Server -- Web UI available at http://<ip>:8091 and logs available in /opt/couchbase/var/lib/couchbase/logs
$ curl localhost:8091
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>301 Moved Permanently</title></head><body><h1>Moved Permanently</h1><p>The document has moved <a href="http://localhost:8091/ui/index.html>here</a>.</p></body></html>
然而,当我在 Leaseweb 上托管的 Ubuntu 16.04 VM 上运行相同的命令(相同的 docker Docker 版本 1.12.1,构建 23cf638)时,失败:
# curl localhost:8091
curl: (7) Failed to connect to localhost port 8091: Connection refused
# netstat -tnlp|grep 8091
tcp 0 0 127.0.0.1:8091 0.0.0.0:* LISTEN 7387/docker-proxy
# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 8080
REDIRECT tcp -- anywhere anywhere tcp dpt:https redir ports 8443
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 anywhere
MASQUERADE all -- 172.18.0.0/16 anywhere
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:8091
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- anywhere anywhere
RETURN all -- anywhere anywhere
DNAT tcp -- anywhere localhost tcp dpt:8091 to:172.17.0.2:8091
但是,当我向公众开放端口时,它开始工作:
# docker run --rm -ti --name couchbase-server -p 8091:8091 couchbase/server:community-4.5.0
# netstat -tnlp|grep 8091
tcp6 0 0 :::8091 :::* LISTEN 15434/docker-proxy
# curl localhost:8091
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>301 Moved Permanently</title></head><body><h1>Moved Permanently</h1><p>The document has moved <a href="http://localhost:8091/ui/index.html>here</a>.</p></body></html>
# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 8080
REDIRECT tcp -- anywhere anywhere tcp dpt:https redir ports 8443
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 anywhere
MASQUERADE all -- 172.18.0.0/16 anywhere
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:8091
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- anywhere anywhere
RETURN all -- anywhere anywhere
DNAT tcp -- anywhere anywhere tcp dpt:8091 to:172.17.0.2:8091
唯一的区别是在最后一行destination anywhere
VS localhost
。但是,在我的家用机器上,相关的 iptables 规则localhost
也一样,而且可以正常工作。事实上,在我的家用机器上,iptables 规则完全相同,但它们可以正常工作。家用机器使用较新的内核(4.8.0-34-generic vs VM 上的 4.4.0-59-generic)并在裸机上运行,而不是在 VM 上运行半虚拟化。也许就是这样?支持人员说上述操作在 Ubuntu 14.04 VM 上完美运行,也许我不应该升级……