5分鐘讓你理解K8S必備架構概念,以及網路模型(下)

阿風的架構筆記發表於2021-05-24

寫在前面

在這用XMind畫了一張導圖記錄Redis的學習筆記和一些面試解析(原始檔對部分節點有詳細備註和參考資料,歡迎關注我的公眾號:阿風的架構筆記 後臺傳送【導圖】拿下載連結, 已經完善更新):

前言

前兩篇介紹了K8S的核心的概念,以及各自起到的作用,小夥伴們一定需要了解哦。今天來分享一下K8S核心的網路模型,這一塊也是比較複雜的,但也是非常重要的。我們從最基本的點慢慢梳理。

Node網路

這個是最基礎的網路,就是每個機器Node節點之間網路通訊,也會整個K8S的基礎網路,這個運維工程師會保證每個機器Node網路的互通。

圖片

上面的WorkNode虛機節點,通過IP+Port即可以實現網路互通,類似搭建了一個內部區域網環境。

Pod網路

K8S最小單位是Pod,每個WorkNode節點中會存在多個Pod,以及一個Pod會有多個容器,那他們的網路通訊模型是什麼呢?

我們只需要保證各個Pod之間,都是能夠互通的。如下圖

圖片

我們先來看看在同一個Pod之間不同容器的互通原理。

同一個Pod不同容器之間的網路互通

圖片

上圖中有eth0、docker0、veth0三種網路裝置:

  • eth0:是代表node節點的網路裝置, 即是node之間的互通是通過此裝置。
  • docker0:虛擬網橋,可以理解為虛擬交換機。 此裝置是用在同一個node中的不同pod之間互相通訊的。
  • veth0:是Pod內部的虛擬網路卡。 它是Pod內不同容器之間互聯的網路裝置,它的IP地址是由docker0分配的。
  • 在k8s中每個Pod中管理著一組Docker容器, 這些Docker容器會共享同一個網路名稱空間
  • Pod中的每個Docker容器擁有與Pod相同的IP和port地址空間,並且由於他們在同一個網路名稱空間,他們之間可以通過localhost相互訪問。 什麼機制讓同一個Pod內的多個docker容器相互通訊那?其實是使用Docker的一種網路模型:–net=container

container模式指定新建立的Docker容器和已經存在的一個容器共享一個網路名稱空間,而不是和宿主機共享。新建立的Docker容器不會建立自己的網路卡,配置自己的 IP,而是和一個指定的容器共享 IP、埠範圍等。

每個Pod容器中有一個系統提供的pause容器有獨立的網路名稱空間,在Pod內啟動Docker容器時候使用 –net=container就可以讓當前Docker容器加入到Pod容器擁有的網路名稱空間 (pause容器)

所以我們能夠看到每個Pod中的pause容器是很重要的哦

同一個Node節點不同Pod之間網路互通

圖片

上圖就是同一個node啟動多個Pod時,docker0又會給Pod2分配ip地址,因為Pod的IP都是由docker0分配的,docker0承擔著虛擬網橋的作用,則同一個node的不同Pod之間的通訊即是通過docker0實現的。

比較細心的小夥伴們會發現,pod的ip地址空間是172.17.0.0/24;而node節點的ip地址空間是在10.100.0.0/24。

那麼不同node節點之間的pod是如何互通的呢?

不同node之間的pod網路互通

圖片

上圖闡述了不同的Node節點之間的Pod是互通需求,Node節點IP地址空間為10.100.0.0/24;Pod的IP地址是在172.17.0.0/16;pod的ip地址在整個K8S叢集是唯一的,這個是由K8S保證的。 Node節點網路和Pod網路不在同一個網路空間,那2個Pod是如何互通的呢?

這個底層實現比較複雜,小夥伴們可以理解為是通過覆蓋網路方式實現,即pod1給pod2時,先把資料包封裝為所在node節點的網路資料包,然後到目標Node之後再解資料包,再到目標Pod。整個流程需要知道哪個Pod在哪個Node對映關係。

簡單一點理解:Pod1與Pod2不在同一臺主機,Pod的地址是與docker0在同一個網段的,但docker0網段與宿主機Node網路卡是兩個完全不同的ip網段,並且不同Node之間的通訊只能通過宿主機的物理網路卡進行。

將Pod的ip和所在Node的ip關聯起來,通過這個關聯可以讓Pod互相訪問。

Service的ClusterIP網路模型

在我們之前文章介紹了一個服務是可以存在多個pod的,那麼另一個服務請求此服務時,到底是請求到其中哪一個pod的呢?看下圖

圖片

我們看到User服務啟動了3個Pod,都有獨立的PodIP;那我們黃色的pod怎麼發現User服務的Pod呢?如果重啟了User服務的Pod,ip會有變動怎麼辦?增加或減少Pod又怎麼辦?

K8S提供了ClusterIP網路模型解決了服務發現,黃色Pod不需要知道User服務到底有多少Pod以及Pod的Ip變化;黃色Pod訪問User服務是通過User Service的ClusterIP進行的,ClusterIP會感知後端User服務的Pod變化。

ClusterIP也起到了負載均衡的作用,預設為隨機演算法。

註冊發現

那ClusterIP的服務發現原理是什麼呢?

圖片

看上圖的服務註冊以及發現,非常類似微服務的註冊中心的服務註冊/發現。在Pod例項化後會通過kubelet註冊到K8S Master節點上面。註冊的資訊就是ServiceName和ClusterIP關係、ClusterIP和PodIP的關係。

kube-proxy和kube-dns會監聽K8S Master上面的資訊。kube-dns目的就是解析ServiceName到哪個ClusterIP。

消費者Pod訪問某個ServiceName時,則通過註冊資訊找到對應的ClusterIP、然後再找到PodIP。

ClusterIP的訪問核心是系統的Iptables、ipvs進行截獲請求

外部流量接入

上面介紹了K8S內部,pod訪問不同pod的方式,是通過ClusterIP方式的Service。

那外部網路如何連線K8S叢集內部的Pod呢?上一篇文章中已經介紹了一種NodePort方式的Service。

圖片

定義了NodePort的Service,會在所有的Node節點上面建立這個NodePort,提供給外部訪問。多個Node節點上面都有一個NodePort;那怎麼實現負載均衡訪問呢?

這個時候會要延伸出LoadBalancer這個元件了,一般做生產雲端部署的時候會用到;需要一些費用的哦。開發測試環境只需要NodePort訪問就行了

圖片

這個外部請求時,會通過Load Balancer選擇一個Node節點上的NodePort進行訪問。

Ingress

上面的NodePort和LoadBalancer針對的是某一個Service;但是我們業務中會有很多個這樣的Service,如果每個Service都要去申請一個LoadBalancer,那麼費用就太高了。

那能不能只要購買一個LoadBalancer就可以支援很多個Service呢?這個就是用到Ingress元件了。

圖片

上圖中就能看出來,Ingress本質就是7層反向代理,做了個路由轉發,類似閘道器路由轉發;把不同的path轉發到不同的Service。

實現Ingress的方式有很多,如:Nginx/Kong/Envoy/Zuul/SpringCloudGateway等

總結

K8S中的網路模型比較多,我們來看個對比圖,方便小夥伴們記憶理解。

圖片

圖片

看完三件事❤️


如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:

  1. 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
  2. 關注公眾號 『 阿風的架構筆記 』,不定期分享原創知識。
  3. 同時可以期待後續文章ing?
  4. 關注後回覆【666】掃碼即可獲取架構進階學習資料包

相關文章