我有一台运行 Jenkins(端口 8080 上的 HTTP)的 Linux 服务器,并且同一台服务器也在运行 Docker 1.12.1。我使用了一些 iptables 规则(根据官方 Jenkins 安装文档)将端口 8080 重定向到主机的端口 80,因此默认 HTTP 将适用于 Jenkins(即http://myserver
,而不是http://myserver:8080
):
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
然而,这些规则破坏了 Docker 在命令期间通过 HTTP 下载正确资源的能力docker build
。例如,RUN apt-get update
失败并出现多个“下载失败”错误。在容器内执行wget http://www.google.com
会返回 Jenkins 主页的 HTML。来自主机的 HTTP GET 工作正常。删除 iptables 规则会导致RUN apt-get update
再次工作。所以我认为那些 iptables 规则正在干扰 docker 的网络机制。
这样的端口重定向可以与 Docker 共存吗?如果是这样,如何编写 iptables 规则来解决这个问题?
对 iptables 规则的可能修改是删除两者并替换为:
这将确保,就我而言,只有通过接口
eth0
的端口 80 上的 TCP 流量才会被重定向。来自主机上 docker 容器的流量不会被重定向。请注意,我也省略了 localhost 重定向,尽管可能可以对其进行修改以避免过滤来自 interface 的任何内容docker0
。另一种解决方案是使用反向代理将 TCP 端口 80 上的传入 HTTP 请求转发到主机的端口 8080。我将Caddy与以下简单的 Caddyfile 一起使用:
有了这个,我可以完全删除 iptables 规则。
这似乎在端口 80 上提供了一个简单的重定向,并允许 docker 容器正常使用传出 HTTP。