[Kubernetes]談談容器跨主機網絡

繼上篇文章:[Kubernetes]淺談容器網絡,本身給本身挖的坑,這篇文章來談談容器跨主機網絡.
要理解容器"跨主通訊"的原理,就要來談談 Flannel 這個項目.
Flannel 項目是 CoreOS 公司主推的容器網絡方案.提供容器網絡功能的,分別是: VXLAN , host-gw , UDP .
這三種不一樣的實現,表明了三種容器跨主機網絡的主流實現方法.這裏主要講 VXLAN 和 UDP 模式.
先從 UDP 模式講起.
web

  • 假設,我有兩臺宿主機:
    • 宿主機 Node 1 上有一個容器 container-1 ,它的 IP 地址是 100.96.1.2 ,對應的 docker0 網橋的地址是: 100.96.1.1/24
    • 宿主機 Node 2 上有一個 container-2 , 它的 IP 地址是 100.96.2.3 ,對應的 docker0 網橋的地址是: 100.96.2.1/24
  • 咱們如今的任務,就是讓 container-1 訪問 container-2 .
    這種狀況下, container-1 容器裏的進程發起的 IP 包,其源地址就是 100.96.1.2 , 目的地址就是 100.96.2.3 .因爲目的地址 100.96.2.3 並不在 Node 1 的 docker0 網橋的網段裏,因此這個 IP 包會被交給默認路由規則,經過容器的網關進入 docker0 網橋,從而出如今宿主機上.
    這時候,這個 IP 包的下一個目的地,就取決於宿主機上的路由規則了.此時, Flannel 已經在宿主機上建立出一系列的路由規則,以 Node1 爲例,來看一下:
    docker

    # 在 Node 1 上
    $ ip route
    default via 10.168.0.1 dev eth0
    100.96.0.0/16 dev flannel0  proto kernel  scope link  src 100.96.1.0
    100.96.1.0/24 dev docker0  proto kernel  scope link  src 100.96.1.1
    10.168.0.0/24 dev eth0  proto kernel  scope link  src 10.168.0.2

    咱們可以看到,因爲 IP 包的目的地址是 100.96.2.3 ,它如今匹配不到本機 docker0 網橋對應的 100.96.1.0/24 網段,只能匹配到第二條,也就是 100.96.0.0/16 對應的這條路由規則,從而進入到一個叫做 flannel0 的設備中.這個 flannel0 設備是一個 TUN 設備( Tunnel 設備)
    在 Linux 中, TUN 設備是一種工做在三層( Network Layer )的虛擬網絡設備. TUN 設備的功能很是簡單,就是:在操做系統內核和用戶應用程序之間傳遞 IP 包.
    此時, IP 包根據路由表進入 flannel0 設備後,宿主機上的 flanneld進程,就會收到這個 IP 包,而後根據目的地址將它發送給 Node2 宿主機.
    那麼, flanneld 是如何知道這個 IP 地址對應的容器,是運行在 Node2 上面的呢?
    編程

    在由 Flannel 管理的容器網絡中,一臺宿主機上的全部容器,都屬於該宿主機被分配的一個"子網",在上面舉的例子中, Node1 的子網是 100.96.1.0/24 , container-1 的 IP 地址是 100.96.1.2 . Node2 的子網是 100.96.2.0/24 , container-2 的 IP 地址是 100.96.2.3
    而這些子網與宿主機的對應關係,保存在 Etcd 中.因此, flanneld 進程在處理 IP 包時,能夠根據目的 IP 的地址,匹配到對應的子網,在 Etcd 中找到這個子網對應的宿主機的 IP 地址便可.
    固然,這個請求得以完成的緣由是,每臺宿主機上的 flanneld ,都監聽着一個 8285 端口,因此 flanneld 只要把 UDP 包發往 Node2 的 8285 端口便可.接下來就是 flanneld 會直接把這個 IP 包發送給它所管理的 TUN 設備,即 flannel0 設備.,此時 Linux 內核網絡棧就會負責處理這個 IP 包,根據相關規則,把這個 IP 包轉發給 docker0 網橋.接下來的流程你們就清楚了(若是忘記了,能夠再回去看看:[Kubernetes]淺談容器網絡), docker0 網橋會扮演二層交換機的角色,將數據包發送給正確的端口,進而經過 Veth Pair 設備到 container-2 的 Network Namespace 中.
    以上就是大概的一個流程.
    來一張圖,看看會不會理解的更好一些:
    在這裏插入圖片描述
    咱們可以看到, Flannel UDP 模式提供的實際上是一個三層的 Overlay 網絡,即:它首先對發出端的 IP 包進行 UDP 封裝,而後在接收端進行解封裝拿到原始的 IP 包,進而把這個 IP 包轉發給目標容器.
    可是UDP模式有嚴重的性能問題,相比於兩臺宿主機之間的直接通訊,基於 Flannel UDP 模式的容器通訊多了一個額外的步驟,即 flanneld 的處理過程.由於這個過程當中,因爲使用到了 flannel0 這個 TUN 設備,因此僅僅在發出 IP 包的這個過程當中,就須要通過用戶態與內核態之間的數據拷貝,具體以下所示:
    在這裏插入圖片描述
    可是咱們在進行系統級編程時,有一個很是重要的優化原則,就是要減小用戶態到內核態的切換次數,而且把核心的處理邏輯都放在內核態進行.
    網絡

    基於這個問題,我們來看看 VXLAN 模式.
    VXLAN(即 Virtual Extensible LAN 虛擬可擴展局域網),是 Linux 內核自己就支持的一種網絡虛擬化技術,所以 VXLAN 徹底能夠在內核態上實現上述封裝和解封裝的工做,從而經過與前面相似的"隧道"機制,構建出覆蓋網絡( Overlay Network ).
    VXLAN 的覆蓋網絡的設計思想是:在現有的三層網絡上,「覆蓋"一層虛擬的,由內核 VXLAN 模塊負責維護的二級網絡,使得鏈接在這個 VXLAN 二層網絡上的"主機」(虛擬機或者容器均可以)之間,能夠像在同一個局域網( LAN )裏那樣自由通訊,固然,實際上這些"主機"可能分佈在不一樣的宿主機上,甚至是分佈在不一樣的物理機房裏.而爲了可以在二層網絡上打通"隧道", VXLAN 會在宿主機上設置一個特殊的網絡設備做爲"隧道"的兩端,這個設備就叫做 VTEP(即: VXLAN Tunnel End Point 虛擬隧道端點). VTEP 設備的做用,和 flanneld 進程很是類似,只是它進行封裝和解封裝的對象,是二層數據幀,而且這個工做的執行流程,是在內核中完成的.來看一下示意圖:
    在這裏插入圖片描述
    圖中每臺宿主機上名叫 flannel.1 的設備,就是 VXLAN 所需的 VTEP 設備,它既有 IP 地址,也有 MAC 地址.而接下來 Flannel VXLAN 模式的具體工做方式,就和實際網絡中工做的方式差很少了.
    VXLAN 模式組建的覆蓋網絡,其實就是一個由不一樣宿主機上的 VTEP 設備,也就是 flannel.1 設備組成的虛擬二層網絡,對於 VTEP 設備來講,它發出的"內部數據幀"就彷彿是一直在這個虛擬的二層網絡上流動同樣,而這也正是「覆蓋網絡」的含義.
    svg

    以上內容來自我學習<深刻剖析Kubernetes>專欄文章以後的一些看法,有偏頗之處,還望指出.
    感謝您的閱讀~
    性能

    相關文章
    相關標籤/搜索