Centos

將 Docker 流量鏡像到同一容器中的不同埠

  • February 6, 2019

我在 CentOS 上使用 docker 容器來模擬網路上的設備,並有兩個工具在每個容器內執行,以模擬與實際網路設備的通信。單獨來說,這兩種工具都可以在 docker 容器內工作,並且可以通過一個我們稱之為 8000 的埠與外界通信,但由於兩者都嘗試使用 8000,它們無法同時執行。為了解決這個問題,我希望將 8000 上的流量鏡像到另一個埠,我們將在此處呼叫 8001,以便一個工具可以在 8000 上執行,而另一個工具可以在 8001 上接收其數據包。在我的 Dockerfile 中,我EXPOSE這兩個(雖然不在執行命令中發布它們)。

在網際網路上閒逛,我發現了這個。試圖使其適應我的目的,我最終得到了以下內容,我從內部執行docker exec -it <container> bash。根據我的原始理解,它應該將消息複製到不同的本地主機 IP 的 8000 埠,同時讓原始消息通過,然後將重複的數據包傳遞回 127.0.0.1:8001。

iptables -t mangle -A PREROUTING -p UDP --dport 8000 -j TEE --gateway 127.0.0.2
iptables -t nat -A PREROUTING -d 127.0.0.2 -p UDP --dport 8000 -j DNAT --to 127.0.0.1:8001

這似乎不起作用。在 8001 上執行一個工具導致它錯過了我從外部世界扔到 8000 的所有數據包。

同樣,我找到了這個,並嘗試將其調整為以下內容,但它似乎也不起作用,並且嘗試讓 netcat 在容器中正常執行已被證明是一件令人頭疼的事情。

iptables -A PREROUTING -t mangle -p tcp ! -s 127.0.0.1 --dport 8000 -j TEE --gateway 127.0.0.1
iptables -A OUTPUT -t nat -p tcp -s 127.0.0.1/32 --dport 8000 -j DNAT --to 127.0.0.1:8001

我對 docker 和 iptables 都是新手,因此對這裡出錯的底層機制的任何解釋都將不勝感激。

經過一番努力,發現需要在容器內執行的解決方案如下:

sysctl -w net.ipv4.conf.eth0.route_localnet=1
iptables -t mangle -A PREROUTING -i eth0 -p UDP --dport 8000 -j TEE --gateway 127.0.0.1
iptables -t nat -A PREROUTING -p UDP --dport 8000 -j DNAT --to-destination 127.0.0.1:8001

缺少的關鍵是要在容器內執行的 sysctl 命令以首先允許執行操作。然後,它需要是 eth0 而不是以前的解決方案,否則你最終會出現無限循環。

引用自:https://serverfault.com/questions/951513