在 docker 中使用 iptables 端口重定向

在 docker 中使用 iptables 端口重定向

我有一台运行 Jenkins 的 Linux 服务器(端口 8080 上的 HTTP),同一台服务器也运行 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 规则来解决这个问题?

答案1

对 iptables 规则的一个可能修改是删除两者并替换为:

iptables -t nat -A PREROUTING -p tcp -m tcp -i eth0 --dport 80 -j REDIRECT --to-ports 8080

就我的情况而言,这将确保只有端口 80 上的 TCP 流量通过接口eth0将被重定向。来自主机上的 docker 容器的流量将不会被重定向。请注意,我也省略了 localhost 重定向,尽管可以对其进行修改以避免过滤来自 interface 的任何内容docker0

另一个解决方案是使用反向代理将 TCP 端口 80 上的传入 HTTP 请求转发到主机的端口 8080。我使用了球童使用以下简单的 Caddyfile:

localhost:80
proxy / localhost:8080

有了这个,我就可以完全删除 iptables 规则。

这似乎在端口 80 上提供了一个简单的重定向,同时允许 docker 容器正常使用传出 HTTP。

相关内容