天天看點

Kubernetes必備知識: Kubernetes網絡模型

所屬技術領域:

雲原生

|名詞定義|

我們知道的是,在K8S上的網絡通信包含以下幾類:

• 容器間的通信:同一個Pod内的多個容器間的通信,它們之間通過lo網卡進行通信。

• Pod之間的通信:通過Pod IP位址進行通信。

• Pod和Service之間的通信:Pod IP位址和Service IP進行通信,兩者并不屬于同一網絡,實作方式是通過IPVS或iptables規則轉發。

• Service和叢集外部用戶端的通信,實作方式:Ingress、NodePort、Loadbalance

K8S網絡的實作不是叢集内部自己實作,而是依賴于第三方網絡插件----CNI(Container Network Interface)

flannel、calico、canel等是目前比較流行的第三方網絡插件。

這三種的網絡插件需要實作Pod網絡方案的方式通常有以下幾種:

虛拟網橋、多路複用(MacVLAN)、硬體交換(SR-IOV)

無論是上面的哪種方式在容器當中實作,都需要大量的操作步驟,而K8S支援CNI插件進行編排網絡,以實作Pod和叢集網絡管理功能的自動化。每次Pod被初始化或删除,kubelet都會調用預設的CNI插件去建立一個虛拟裝置接口附加到相關的底層網絡,為Pod去配置IP位址、路由資訊并映射到Pod對象的網絡名稱空間。

在配置Pod網絡時,kubelet會在預設的/etc/cni/net.d/目錄中去查找CNI JSON配置檔案,然後通過type屬性到/opt/cni/bin中查找相關的插件二進制檔案,如下面的"portmap"。然後CNI插件調用IPAM插件(IP位址管理插件)來配置每個接口的IP位址:

Kubernetes必備知識: Kubernetes網絡模型

CNI主要是定義容器網絡模型規範,連結容器管理系統和網絡插件,兩者主要通過上面的JSON格式檔案進行通信,實作容器的網絡功能。CNI的主要核心是:在建立容器時,先建立好網絡名稱空間(netns),然後調用CNI插件為這個netns配置網絡,最後在啟動容器内的程序。

常見的CNI網絡插件包含以下幾種:

• Flannel:為Kubernetes提供疊加網絡的網絡插件,基于TUN/TAP隧道技術,使用UDP封裝IP封包進行建立疊 加網絡,借助etcd維護網絡的配置設定情況,缺點:無法支援網絡政策通路控制。

• Calico:基于BGP的三層網絡插件,也支援網絡政策進而實作網絡的通路控制;它在每台主機上都運作一個虛拟路由,利用Linux核心轉發網絡資料包,并借助iptables實作防火牆功能。實際上Calico最後的實作就是将每台主機都變成了一台路由器,将各個網絡進行連接配接起來,實作跨主機通信的功能。

• Canal:由Flannel和Calico聯合釋出的一個統一網絡插件,提供CNI網絡插件,并支援網絡政策實作。

• 其他的還包括Weave Net、Contiv、OpenContrail、Romana、NSX-T、kube-router等等。而Flannel和Calico是目前最流行的選擇方案。

|發展曆程|

Kubernetes必備知識: Kubernetes網絡模型
Kubernetes必備知識: Kubernetes網絡模型

|相關詞|

Docker網絡模型

了解Docker的友友們都應該清楚,Docker容器的原生網絡模型主要有3種:Bridge(橋接)、Host(主機)、none。

Bridge:借助虛拟網橋裝置為容器建立網絡連接配接。

Host:設定容器直接共享目前節點主機的網絡名稱空間。

none:多個容器共享同一個網絡名稱空間。

Kubernetes必備知識: Kubernetes網絡模型
Kubernetes必備知識: Kubernetes網絡模型

從上可以看到容器内有一個網卡eth0@if39,實際上eth0@if39和veth3f1b114是一對veth pair。veth pair是一種成對出現的特殊網絡裝置,可以想象它們由一根虛拟的網線進行連接配接的一對網卡,eth0@if39在容器中,veth3f1b114挂在網橋docker0上,最終的效果就是eth0@if39也挂在了docker0上。

橋接式網絡是目前較為流行和預設的解決方案。但是這種方案的弊端是無法跨主機通信的,僅能在主控端本地進行,而解決該問題的方法就是NAT。所有接入到該橋接裝置上的容器都會被NAT隐藏,它們發往Docker主機外部的所有流量都會經過源位址轉換後發出,并且預設是無法直接接受節點之外的其他主機發來的請求。當需要接入Docker主機外部流量,就需要進行目标位址轉換甚至端口轉換将其暴露在外部網絡當中。如下圖:

Kubernetes必備知識: Kubernetes網絡模型

容器内的屬于私有位址,需要在左側的主機上的eth0上進行源位址轉換,而右側的位址需要被通路,就需要将eth0的位址進行NAT轉換。SNAT---->DNAT

這樣的通信方式會比較麻煩,進而需要借助第三方的網絡插件實作這樣的跨主機通信的網絡政策。

Flannel網絡插件

在各節點上的Docker主機在docker0上預設使用同一個子網,不同節點的容器都有可能會擷取到相同的位址,那麼在跨節點通信時就會出現位址沖突的問題。并且在多個節點上的docker0使用不同的子網,也會因為沒有準确的路由資訊導緻無法準确送達封包。

而為了解決這一問題,Flannel的解決辦法是,預留一個使用網絡,如10.244.0.0/16,然後自動為每個節點的Docker容器引擎配置設定一個子網,如10.244.1.0/24和10.244.2.0/24,并将配置設定資訊儲存在etcd持久存儲。

第二個問題的解決,Flannel是采用不同類型的後端網絡模型進行處理。其後端的類型有以下幾種:

VxLAN:使用核心中的VxLAN子產品進行封裝封包。也是flannel推薦的方式,其封包格式如下:

Kubernetes必備知識: Kubernetes網絡模型

host-gw:即Host GateWay,通過在節點上建立目标容器位址的路由直接完成封包轉發,要求各節點必須在同一個2層網絡,對封包轉發性能要求較高的場景使用。

UDP:使用普通的UDP封包封裝完成隧道轉發。

Pod 内部 docker 容器之間網絡通信

Kubernetes 使用了一種 “IP-per-pod” 網絡模型:為每一個 Pod 配置設定了一個IP位址,Pod 内部的 docker 容器共享Pod的網絡空間,即它們共享 Pod 的網卡和 IP。其原理是根據 docker 的“container 網絡”模型而來。

Pod 所在的網絡之間通信

Kubernetes 把各 node 主機上的 docker的 bridge 網絡“外包”給了 flannel,然後通過 etcd 将各 node 主機上的 bridge 網絡資訊收集起來,是以每個 node 之間的網絡使用的是同網絡的不同 IP,保證了網絡通訊的可靠性。其原理是根據 docker 的“bridge 網絡”模型而來。

Pod 和 Service 之間網絡通信

在 Kubernetes 體系中Pod是不穩定的,Pod 的 IP 位址會發生變化,是以 Kubernetes 引進了 Service 的概念。Service 是一個抽象的實體,Kubernetes 在建立 Service 實體時,為其配置設定了一個虛拟的 IP,當外界需要通路 Pod 裡的容器提供的功能時,不直接使用 Pod 的 IP 位址和端口,而是通路 Service 的這個虛拟 IP 和端口,由 Service 把請求轉發給它背後的 Pod。

Kubernetes 在建立 Service 時,根據 Service 的标簽選擇器(Label Selector)來查找 Pod,據此建立與 Service 同名的 EndPoints 對象。當Pod的位址發生變化時,EndPoints 也随之變化。Service 接受到請求時,就能通過 EndPoints 找到對應的 Pod。再深入探究,Service 隻是一個虛拟的概念,真正完成請求轉發的是運作在 node 節點上的 kube-proxy。Service的虛拟IP就是由kube-proxy實作的。

kube-proxy 有兩種請求轉發模式:userspace 模式和 iptables 模式。在 Kubernetes v1.1版本之前預設是userspace 模式,v1.2 版本後預設是 iptables 模式。

資料來源:

  1. 名詞定義: https://www.cnblogs.com/tylerzhou/p/10995797.html
  2. 相關詞: 延伸閱讀:

簡書:Kubernetes 網絡模型解析

https://www.jianshu.com/p/478c56287c5c