歡迎光臨
每天分享高質量文章

圖解Kubernetes網絡

你一直在Kubernetes集群中運行一系列服務並已從中獲益,或者你正打算這麼做。儘管有一系列工具能幫助你建立並管理集群,你仍困惑於集群底層是如何工作的,以及出現問題該如何處理。我曾經就是這樣的。

誠然Kubernetes對初學者來說已足夠易用,但我們仍然不得不承認,它的底層實現異常複雜。Kubernetes由許多部件組成,如果你想對失敗場景做好應對準備,那麼你必須知道各部件是如何協調工作的。其中一個最複雜,甚至可以說是最關鍵的部件就是網絡。
因此我著手精確理解Kubernetes網絡是如何工作的。我閱讀了許多文章,看了很多演講,甚至瀏覽了代碼庫。以下就是我的所得。


Kubernetes網絡模型

核心點是,Kubernetes網絡有一個重要的基本設計原則:
每個Pod擁有唯一的IP
這個Pod IP被該Pod內的所有容器共享,並且其它所有Pod都可以路由到該Pod。你可曾註意到,你的Kubernetes節點上運行著一些”pause”容器?它們被稱作“沙盒容器(sandbox containers)”,其唯一任務是保留並持有一個網絡命名空間(netns),該命名空間被Pod內所有容器共享。通過這種方式,即使一個容器死掉,新的容器創建出來代替這個容器,Pod IP也不會改變。這種IP-per-pod模型的巨大優勢是,Pod和底層主機不會有IP或者端口衝突。我們不用擔心應用使用了什麼端口。
這點滿足後,Kubernetes唯一的要求是,這些Pod IP可被其它所有Pod訪問,不管那些Pod在哪個節點。
節點內通信
第一步是確保同一節點上的Pod可以相互通信,然後可以擴展到跨節點通信、internet上的通信,等等。

Kubernetes Node(root network namespace)
在每個Kubernetes節點(本場景指的是Linux機器)上,都有一個根(root)命名空間(root是作為基準,而不是超級用戶)–root netns。
最主要的網絡接口 eth0 就是在這個root netns下。

Kubernetes Node(pod network namespace)
類似的,每個Pod都有其自身的netns,通過一個虛擬的以太網對連接到root netns。這基本上就是一個管道對,一端在root netns內,另一端在Pod的nens內。
我們把Pod端的網絡接口叫 eth0,這樣Pod就不需要知道底層主機,它認為它擁有自己的根網絡設備。另一端命名成比如 vethxxx。你可以用ifconfig 或者 ip a 命令列出你的節點上的所有這些接口。

Kubernetes Node(linux network bridge)
節點上的所有Pod都會完成這個過程。這些Pod要相互通信,就要用到linux的以太網橋 cbr0 了。Docker使用了類似的網橋,稱為docker0。
你可以用 brctl show 命令列出所有網橋。

Kubernetes Node(same node pod-to-pod communication)
假設一個網絡資料包要由pod1到pod2。
  1. 它由pod1中netns的eth0網口離開,通過vethxxx進入root netns。

  2. 然後被傳到cbr0,cbr0使用ARP請求,說“誰擁有這個IP”,從而發現標的地址。

  3. vethyyy說它有這個IP,因此網橋就知道了往哪裡轉發這個包。

  4. 資料包到達vethyyy,跨過管道對,到達pod2的netns。

這就是同一節點內容器間通信的流程。當然也可以用其它方式,但是無疑這是最簡單的方式,同時也是Docker採用的方式。
節點間通信
正如我前面提到,Pod也需要跨節點可達。Kubernetes不關心如何實現。我們可以使用L2(ARP跨節點),L3(IP路由跨節點,就像雲提供商的路由表),Overlay網絡,或者甚至信鴿。無所謂,只要流量能到達另一個節點的期望Pod就好。每個節點都為Pod IPs分配了唯一的CIDR塊(一段IP地址範圍),因此每個Pod都擁有唯一的IP,不會和其它節點上的Pod衝突。
大多數情況下,特別是在雲環境上,雲提供商的路由表就能確保資料包到達正確的目的地。我們在每個節點上建立正確的路由也能達到同樣的目的。許多其它的網絡插件通過自己的方式達到這個目的。
這裡我們有兩個節點,與之前看到的類似。每個節點有不同的網絡命名空間、網絡接口以及網橋。

Kubernetes Nodes with route table(cross node pod-to-pod communication)
假設一個資料包要從pod1到達pod4(在不同的節點上)。
  1. 它由pod1中netns的eth0網口離開,通過vethxxx進入root netns。

  2. 然後被傳到cbr0,cbr0通過發送ARP請求來找到標的地址。

  3. 本節點上沒有Pod擁有pod4的IP地址,因此資料包由cbr0 傳到 主網絡接口 eth0。

  4. 資料包的源地址為pod1,標的地址為pod4,它以這種方式離開node1進入電纜。

  5. 路由表有每個節點的CIDR塊的路由設定,它把資料包路由到CIDR塊包含pod4的IP的節點。

  6. 因此資料包到達了node2的主網絡接口eth0。現在即使pod4不是eth0的IP,資料包也仍然能轉發到cbr0,因為節點配置了IP forwarding enabled。節點的路由表尋找任意能匹配pod4 IP的路由。它發現了 cbr0 是這個節點的CIDR塊的標的地址。你可以用route -n命令列出該節點的路由表,它會顯示cbr0的路由,型別如下:

  7. 網橋接收了資料包,發送ARP請求,發現標的IP屬於vethyyy。

  8. 資料包跨過管道對到達pod4。

這就是Kubernetes網絡的基礎。下次你碰到問題,務必先檢查這些網橋和路由表。
前面我們漫談了Kubernetes的網絡模型。我們觀察了資料包是如何在同一節點上的pod 間和跨節點的 pod 間流動的。我們也註意到了Linux網橋和路由表在這個過程中所扮演的角色。
現在我們將進一步闡述這些概念,並闡述Overlay網絡是如何工作的。我們也將理解Kubernetes千變萬化的Pod是如何從運行的應用中抽象出來,併在幕後處理的。

Overlay 網絡

Overlay網絡不是預設必須的,但是它們在特定場景下非常有用。比如當我們沒有足夠的IP空間,或者網絡無法處理額外路由,抑或當我們需要Overlay提供的某些額外管理特性。一個常見的場景是當雲提供商的路由表能處理的路由數是有限制時。例如,AWS路由表最多支持50條路由才不至於影響網絡性能。因此如果我們有超過50個Kubernetes節點,AWS路由表將不夠。這種情況下,使用Overlay網絡將幫到我們。
本質上來說,Overlay就是在跨節點的本地網絡上的包中再封裝一層包。你可能不想使用Overlay網絡,因為它會帶來由封裝和解封所有報文引起的時延和複雜度開銷。通常這是不必要的,因此我們應當在知道為什麼我們需要它時才使用它。
為了理解Overlay網絡中流量的流向,我們拿Flannel做例子,它是CoreOS 的一個開源專案。

Kubernetes Node with route table(cross node pod-to-pop Traffic flow with flannel overlay network)
這裡我們註意到它和之前我們看到的設施是一樣的,只是在root netns中新增了一個虛擬的以太網設備,稱為flannel0。它是虛擬擴展網絡Virtual Extensible LAN(VXLAN)的一種實現,但是在Linux上,它只是另一個網絡接口。
從pod1到pod4(在不同節點)的資料包的流向類似如下:
1、它由pod1中netns的eth0網口離開,通過vethxxx進入root netns。
2、然後被傳到cbr0,cbr0通過發送ARP請求來找到標的地址。
3a、由於本節點上沒有Pod擁有pod4的IP地址,因此網橋把資料包發送給了flannel0,因為節點的路由表上flannel0被配成了Pod網段的標的地址。
3b、flanneld daemon和Kubernetes apiserver或者底層的etcd通信,它知道所有的Pod IP,並且知道它們在哪個節點上。因此Flannel創建了Pod IP和Node IP之間的映射(在用戶空間)。
flannel0取到這個包,併在其上再用一個UDP包封裝起來,該UDP包頭部的源和目的IP分別被改成了對應節點的IP,然後發送這個新包到特定的VXLAN端口(通常是8472)。

Packet-in-packet encapsulation(notice the packet is encapsulated from 3c to 6b in previous diagram)
儘管這個映射發生在用戶空間,真實的封裝以及資料的流動發生在內核空間,因此仍然是很快的。
3c、封裝後的包通過eth0發送出去,因為它涉及了節點間的路由流量。
4、包帶著節點IP信息作為源和目的地址離開本節點。
5、雲提供商的路由表已經知道瞭如何在節點間發送報文,因此該報文被髮送到標的地址node2。
6a、包到達node2的eth0網卡,由於標的端口是特定的VXLAN端口,內核將報文發送給了 flannel0。
6b、flannel0解封報文,並將其發送到 root 命名空間下。
從這裡開始,報文的路徑和我們之前在Part 1 中看到的非Overlay網絡就是一致的了。
6c、由於IP forwarding開啟著,內核按照路由表將報文轉發給了cbr0。
7、網橋獲取到了包,發送ARP請求,發現標的IP屬於vethyyy。
8、包跨過管道對到達pod4。
這就是Kubernetes中Overlay網絡的工作方式,雖然不同的實現還是會有細微的差別。有個常見的誤區是,當我們使用Kubernetes,我們就不得不使用Overlay網路。事實是,這完全依賴於特定場景。因此請確保在確實需要的場景下才使用。
在前一部分我們學習了Kubernetes網絡的基礎知識。現在我們知道了Overlay網絡是如何工作的。在下一部分,我們將看到Pod創建和刪除過程中網絡變化是如何發生的,以及出站和進站流量是如何流動的。
總體而言我對網絡概念仍然是個新手,因此我非常期待能得到大家的反饋,特別是某些不清晰或者錯誤的地方。

原文鏈接:https://medium.com/@ApsOps/an-illustrated-guide-to-kubernetes-networking-part-1-d1ede3322727

赞(0)

分享創造快樂