通過 docker 使用 iptables 埠重定向
我有一台執行 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 規則的可能修改是刪除兩者並替換為:
iptables -t nat -A PREROUTING -p tcp -m tcp -i eth0 --dport 80 -j REDIRECT --to-ports 8080
這將確保,就我而言,只有*通過介面
eth0
*的埠 80 上的 TCP 流量才會被重定向。來自主機上 docker 容器的流量不會被重定向。請注意,我也省略了 localhost 重定向,儘管可以對其進行修改以避免過濾來自 interface 的任何內容docker0
。另一種解決方案是使用反向代理將 TCP 埠 80 上的傳入 HTTP 請求轉發到主機的埠 8080。我將Caddy與以下簡單的 Caddyfile 一起使用:
localhost:80 proxy / localhost:8080
有了這個,我可以完全刪除 iptables 規則。
這似乎在埠 80 上提供了一個簡單的重定向,並允許 docker 容器正常使用傳出 HTTP。