GKE 系列教學 (二) – 簡介Pod的網路機制

上一回我們了解到Kubernetes是微服務架構的一個核心以及各元件的機制後,想更一步的了解它的運作方式。本系列教學就是以實作的方式,結合 Google Container Engine(GKE, 因為GCE是指Compute Engine),可以從較底層的對照比較:虛擬機器、網路、服務到負載平衡器,讓您可以直接了解Kubernetes如何在Google雲端運作。

開始前,先回答兩個問題:

第一個問題: GKE究竟是什麼服務?

它與開源的Kubernetes究竟有什麼差別,甚至還需要收費?其實最明顯的差別就是Fully Management且成本非常的低。

  • Fully Management: 服務只要上GKE,就完全交由Google託管,不需要持續設定繁雜的虛擬機器等較底層的東西。一次設定,終身託管。Google甚至保證每月Uptime高達99.5%以上。
  • 成本低廉: 5個節點(node)以下管理完全免費,從第6個開始不管使用多少個節點,每月通通只算109.5美元。平均下來只等於一天的珍珠奶茶錢!(*虛擬機器的費用依規格另計)

第二個問題: Kubernetes Pod的網路原理

Kubernetes內Pod之間是如何通信的?我們重新檢視一下k8s的網路原理。

上篇文章可以了解,Pod是Kubernetes的最小單位,裡面的container是共用Pod的命名空間以及儲存捲(Volume)。在Linux中,每個容器是被設計成獨立且隔離的個體,當兩者要通信時,veth [(virtual eth), (virtual ethernet device)]是連結兩者的橋梁。藉由這樣的原理,在k8s可分成以下的類型來探討[1]:

  • Pod的網路模型

每個POD都被分配到一個IP,裡面的容器可以自由通信,如下圖所示。

  • 同一個Node內的Pod間通信

從圖可以看出,Pod1和Pod2都是透過Veth連結在同一個Docker0橋接器(Bridge)上面,IP1, IP2都是由Docker0網段上動態取得,與IP3為同一網域。由於為同一網段,所以它們之間能直接通信。

  • 不同Node內的Pod間通信

我們知道給予Pod IP位址的docker0與Node主機是兩個不同的網段,透過不同Node間的溝通只能依賴Node主機上的網路才行。這裡不贅言,主要是結合Node IP與Pod IP,讓Pod可以找到目的IP,而GKE中的Google網路會自動幫您處理。整個通信過程如以上示意。

現在讓我們開始吧!

  • 設定網路環境
gcloud compute networks create kube-sandbox
gcloud compute firewall-rules \

create default-allow-ssh \

–network kube-sandbox \

–allow tcp:22

  • 建立叢集(Cluster) : 建立一個叢集以及一個節點
gcloud beta container clusters \

create –machine-type=g1-small \

–num-nodes=1 \

–network=kube-sandbox kube-sandbox

這個叢集需要幾項參數:機器規格節點數目以及網域,當然包含叢集的名稱

建立完成後,同時可在console看到叢集的資訊:

接著,我們要如何將GKE與GCE連結起來呢?

  • GKE和GCE的參數比較 – 一個節點就是對應到一台GCE VM

Step1 獲取GCE資料:使用以下指令,您可以發現除了一些default route外,還有著一條與GKE相關的資訊。接著請複製NEXT_HOP的名稱部分。

gcloud compute routes list –filter=network=kube-sandbox

*請留意,因為要檢視GCE, 故指令為gcloud compute

Step2 獲取GCE資料:檢視 gke-kube-sandbox-default-pool-6e6f7cda-spn5

利用以下指令,便可得出該名稱底下的一些參數。這裡可以證明,該節點即為一台GCE虛擬機器

gcloud compute instances describe gke-kube-sandbox-default-pool-6e6f7cda-spn5 \

–format=’table(name,networkInterfaces[0].networkIP, networkInterfaces[0].accessConfigs[0].natIP, tags.items.map(0).join(“,"):label=TAGS)’

該虛擬機器(節點)包含了兩項重要的參數:NETWORK_IP, NAT_IP。

  • NETWORK_IP: 此為GCE被GCP內網所分配的IP位址,可作為內部IP
  • NAT_IP: 可解讀為GCE的外部IP,是連上Internet的IP位址

甚至,您在Console上的VM執行個體頁面上,也看得到該節點的名稱。它,就是一台虛擬機器!(您可以對照一下,下圖外部IP的位址與上圖CLI的NAT_IP一致)

Step3 獲取GKE資料:利用以下指令,可讀到Kubernetes在GKE內的關係位置

kubectl get node -o custom-columns=’NAME:.metadata.name,EXTERNAL-IP:.status.addresses[?(@.type=="ExternalIP")].address,INTERNAL-IP:.status.addresses[?(@.type=="InternalIP")].address,POD-CIDR:.spec.podCIDR’

這裡面有三項參數:EXTERNAL-IP, INTERNAL-IP, POD-CIDR

  • EXTERNAL-IP: 104.155.226.39為外部IP,仔細一瞧與GCE的NAT_IP一致
  • INTERNAL-IP: 10.140.0.2為內部IP,仔細一瞧與GCE的NETWORK_IP一致
  • POD-CIDR: 10.76.0.0/24,仔細一瞧與該台GCE的routing相同範圍(DEST_RANGE),從網域來看即為該節點所支持的Pod連結數

以上無論是從GCE看或者從GKE看,各項參數其實背後的原理都是串聯在一起的,只是角度不同罷了!現在我們對Kubernetes在GKE的實作,又多了一層理解。

那麼這些數字與比較到底可以帶給我們什麼啟發呢?Service又是怎麼做的呢?它又可以帶給我們什麼啟發呢?我們下篇來分曉!

[1] 《Kubernetes權威指南》https://www.tenlong.com.tw/products/9787121299414

另外還有 K8S專欄:Kubernetes Service 介紹,讓您了解更進階的 Service 操作 🙂

連絡我們