博客 / 詳情

返回

容器網絡中的 Iptables 包路徑

前面我們分析了《數據包如何遊走於 Iptables 規則之間》,那麼在容器網絡這種更復雜的場景中數據包是如何在 iptables 的各個規則之間遊走的呢?

為了搞清楚這個問題,我們首先有一些前置概念需要了解。

前置概念

network namespace

namespace 是容器隔離的基礎,而 network namespace 則使得每個 namespace 獨享 IP address、port、routing tables、iptables 等網絡相關資源。這就意味着,數據包在容器和宿主機上經歷的 iptables 是不一樣的。

veth pair

veth pair 是容器網絡的命脈,因為容器靠這個技術實現跨命名空間通信(namespace 把容器關了起來,veth pair 又按需把容器放了出來)。簡單理解,數據從一個 veth 進去,就會從另一個 veth 出來。這個實現也很簡潔,主要在 veth_xmit 函數中,大家可以到參考鏈接中稍微閲讀下。

容器組網

目前有三大主流模式。

overlay

簡單來講,就是容器網絡是構建在宿主機網絡上的另一層網絡,容器 IP 本身在宿主機網絡上不可路由,跨主機通信需要藉助封包手段才能讓容器互聯。典型案例:Flannel(VXLAN 模式)、Calico(IPIP 模式)、Weave 等。

underlay

容器和宿主機共享一張網絡,典型案例:MACVLAN、SR-IOV。由於共享網絡,不存在封包過程,所以性能很好。

路由

路由模式其實是 Underlay 模式的一種特例,它的跨主機通信是通過路由轉發來實現的,也沒有封包這個過程,所以性能也較好。

進入主題

我們以路由模式為例,如圖是一個典型的 node


圖 1

當 pod1 準備往其他 node 上的 pod 發數據時,pod1 內部的 iptables 路徑是這樣的:

image.png
圖 2

該 node 上是這樣的:

image.png
圖 3

veth 收到包後,這個包已經來到了宿主機 namespace,經宿主機路由規則判斷,要走宿主機 eth0 網卡將包發出到宿主機網絡上,所以是走的 forward 鏈 和 postrouting 鏈。
假設目的地址不是另一個 pod ip 而是網絡外部地址,比如 google.com,則 postrouting 中會有相應的 snat 規則。


我們再來加個碼,假設 node 上有一些加密組件,將 pod 到 pod 之間的流量加密,那麼該 node 上就是這樣的:

image.png
圖 4

veth 收到包後,這個包已經來到了宿主機 namespace,經宿主機路由規則判斷,流量需要被加密,於是走到加密網卡,所以走的還是 forward 鏈和 postrouting 鏈,區別在於,經過加密網卡後,數據進入加密進程,加密進程完成對包的加密後,從宿主機 namespace 發出,直接到主網卡 eth0,所以走的是 output 鏈和 postrouting 鏈。
加密進程和加密網卡之間的關聯在《流量劫持技術哪家強?》中已有表述,主要有:涉及用户態的 tun/tap 技術,以及僅內核態的 wireguard 技術。

對於接受端,基本就是上面的圖反過來,就不贅述了。

注:要得出這些結論,需要用到《數據包如何遊走於 Iptables 規則之間?》中提到的技術。當然,自己用 ebpf 等工具去 trace 也未嘗不可,就是麻煩點。

參考

  • https://github.com/torvalds/linux/blob/master/drivers/net/veth.c#L343
  • https://jingyecn.top:18080/immutable-infrastructure/network/c...
  • https://aws.github.io/aws-eks-best-practices/networking/index/
  • http://www.adminsehow.com/2011/09/iptables-packet-traverse-map/
user avatar huorongsecurity 頭像
1 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.