Google Kubernetes Engine (GKE) 網路會使用並擴充虛擬私有雲 (VPC) 提供的軟體定義網路 (SDN) 基礎架構。GKE 網路可讓元件在 Kubernetes 叢集內,以及與外部服務和網路通訊。GKE 網路模型以 Kubernetes 網路原則為基礎 (每個 Pod 都有自己的 IP 位址),提供 IP 位址、負載平衡、DNS 解析和網路政策強制執行功能。本文說明節點、Pod 和服務等核心元件,如何在 GKE 網路環境中與控制層互動,涵蓋下列主題:
- 這些元件在虛擬私有雲中的互動方式
- IP 位址的分配和管理方式
- 流量如何流入、流經及流出叢集
GKE 網路架構
GKE 網路是以 Google Cloud的虛擬私有雲 (VPC) 為基礎建構而成。這個基礎可為所有容器化應用程式,提供強大且可擴充的連線能力。
虛擬私有雲基礎和 IP 位址範圍
您可以在虛擬私有雲中定義子網路,也就是區域 IP 位址範圍。GKE 會策略性地在這些子網路中使用不同的 IP 位址範圍,供各種叢集元件使用,通常會使用 VPC 別名 IP 位址範圍:
- 節點 IP 位址範圍:這是子網路的主要 IP 位址範圍,叢集節點會部署在該子網路中。所有 GKE worker 節點 (即 Compute Engine VM) 都會從這個範圍取得主要 IP 位址。這些 IP 位址用於節點之間的通訊,以及負載平衡器的健康狀態檢查。節點 IP 位址也是源自節點本身的流量來源。在 VPC 原生叢集中,Pod 的流量會使用 Pod IP 位址做為來源位址,除非 Pod IP 位址經過 Cloud NAT 等功能轉譯。
- Pod IP 位址範圍:子網路內的專用次要 IP 位址範圍,通常是較大的 CIDR 區塊。每個節點都會從這個範圍取得一組 IP 位址。GKE 會將這些 IP 位址指派給在該節點上執行的 Pod。叢集中的每個 Pod 都會從這個範圍取得專屬 IP 位址。這些 Pod IP 位址可在虛擬私有雲中原生路由傳送。根據預設,每個節點都會取得
/24範圍,提供 256 個 IP 位址。不過,GKE 會將每個節點的 Pod 數量上限設為 110。這個緩衝區可確保在快速建立及刪除 Pod (也稱為流失) 時,IP 位址可用。這些 IP 位址可讓不同節點的 Pod 直接通訊,不需使用網路位址轉譯 (NAT)。 - Service IP 位址範圍 (ClusterIP):指派給 Kubernetes Service 的虛擬 IP 位址 (ClusterIP) 次要 IP 位址範圍。這些穩定的 IP 位址僅用於叢集內的通訊。
- 控制層 IP 位址:每個控制層都有公開或內部 IP 位址,具體取決於叢集類型、版本和建立日期。worker 節點和外部用戶端 (例如
kubectl) 會使用這個 IP 位址,與 Kubernetes API 伺服器安全通訊。GKE 前端 (GKFE) 會為每個叢集提供 DNS 型端點,讓您安全可靠地存取控制層,不必直接管理 IP 位址。
GKE 網路的三大核心要素
GKE 網路包含三個相互連結的支柱,每個支柱代表不同的通訊層。這個架構可協助您瞭解應用程式在叢集內以及與外部網路之間的通訊方式:
- Pod 網路:基礎層,定義叢集內個別容器 (Pod) 之間的通訊方式。
- 服務網路:以 Pod 網路為基礎,這個層級說明 Kubernetes 服務如何提供穩定端點,以供內部或外部用戶端公開應用程式,包括負載平衡和服務探索。
- 叢集網路:最外層,涵蓋整個 GKE 叢集如何連線至更廣泛的網路生態系統,包括管理來自網際網路的 Ingress、輸出至外部服務,以及連線至 Google Cloud 服務和地端部署系統。
這些層級會共同運作,建立全方位的通訊模型,支援內部和外部連線、安全性及可擴充性。以下各節將詳細探討每個要素。
Pod 網路
Pod 網路是 GKE 叢集內所有通訊的基礎。定義 Pod 中執行的應用程式如何尋找彼此並互動。在 Kubernetes 中,Pod 是最小且最基本的可部署單位。Pod 可做為應用程式的邏輯主機。 Pod 會執行一或多個共用網路資源的容器。在節點上排定 Pod 時,Kubernetes 會在節點的 Linux 核心中為 Pod 建立專屬網路命名空間,將其網路與同一節點上的其他 Pod 隔離。
Pod 網路運作方式
Pod 網路是透過不重複的 IP 位址、虛擬網路裝置和專用外掛程式 (用於管理連線能力) 組合建立。
容器網路介面 (CNI):GKE 使用 CNI 外掛程式實作及管理 Pod 網路。如果是 VPC 原生叢集,預設為 Google CNI。其他選項包括 kubenet (適用於非 VPC 原生叢集)、Calico 和 GKE Dataplane V2 (以 Cilium 為基礎)。這些外掛程式負責將 Pod 連線至網路,並強制執行網路政策。
IP 位址分配:每個節點都會從 Pod IP 位址範圍取得一組 IP 位址,用於指派給 Pod。GKE 會保留部分位址,建立緩衝區,確保 Pod 快速流失 (建立和毀損) 時,IP 位址仍可使用。因此,每個節點可分配的 Pod IP 位址數量一律小於範圍大小。
網路命名空間和虛擬乙太網路 (veth) 配對:為方便通訊,Kubernetes 會將 Pod 的獨立網路命名空間連線至節點的主要或根網路命名空間。Kubernetes 會使用虛擬乙太網路配對 (或稱 veth 配對) 建立這項連線,其運作方式類似虛擬網路線。其中一端會放在 Pod 的命名空間內,並顯示為
eth0。另一端則連至網路橋接器,或直接連至節點根命名空間中的節點網路堆疊,讓封包能往返 Pod。具體連線方法取決於叢集使用的 CNI 外掛程式:
- Google CNI:這是 VPC 原生叢集的預設 CNI。Pod 的 veth 配對會連線至節點的根網路命名空間。由於 Pod IP 位址是虛擬私有雲網路已知的別名 IP 位址,節點上的標準 Linux 路由會將流量導向 Pod,並從 Pod 導出流量。
- GKE Dataplane V2:使用 eBPF 程式處理 Pod 網路,通常會略過傳統 Linux 橋接器和 veth 配對,直接在核心內管理封包流程,提高效能。
- Kubenet:用於非 VPC 原生叢集。veth 配對的另一端會連線至節點根命名空間中名為
cbr0的 Linux 橋接裝置。這個橋接器會管理同一節點上 Pod 之間的流量,並針對離開節點的流量使用 NAT。 - Calico:使用 Calico 啟用網路政策時,veth 配對的另一端會連線至節點的根命名空間,然後 Calico 會編寫主機路徑,將流量導向正確的 Pod。
最大傳輸單位 (MTU):決定可透過網路傳送的最大封包大小,不會遭到分割。在 GKE 中,Pod 介面的 MTU 是重要設定,取決於叢集使用的 GKE CNI 外掛程式,以及基礎虛擬私有雲網路的 MTU 設定。MTU 值不相符可能會導致封包遺失或效能降低。Pod 介面 MTU 值固定為 1460 位元組,或沿用節點的主要網路介面,如下表所示。
| CNI | MTU | 用量 |
|---|---|---|
| Google CNI | 1460 | 使用 1.26.1 之前的 GKE 版本時,VPC 原生叢集的預設值。 |
| Google CNI | 已繼承 | 使用 GKE 1.26.1 以上版本的 VPC 原生叢集預設值。 |
| Calico | 1460 | 啟用網路政策 (--enable-network-policy) 時使用。 |
| GKE Dataplane V2 | 已繼承 | 啟用 GKE Dataplane V2 時使用 (--enable-dataplane-v2)。 |
| netd | 已繼承 | 啟用「節點內」瀏覽、Workload Identity Federation for GKE 或 IPv4/IPv6 雙堆疊網路等功能時,就會使用這個值。 |
Pod 對 Pod 通訊流程
Kubernetes 使用平面網路模型,每個 Pod 都有專屬的可路由 IP 位址。這個模型可確保 Pod 之間的連線順暢。
同一節點內的通訊
當 Pod 將流量傳送至同一節點上的另一個 Pod 時,要求會從第一個 Pod 的網路命名空間流動,通過其 veth 配對,然後進入節點的根網路命名空間。這個流量會保留在節點內。視使用的 CNI 外掛程式而定,CNI 外掛程式會將流量轉送至第二個 Pod 的 veth 配對。舉例來說,使用 kubenet 時,橋接裝置會轉送流量。在 GKE Dataplane V2 中,eBPF 程式會直接管理封包流程。
不同節點之間的通訊
當某個節點上的 Pod 將流量傳送至另一個節點上的 Pod 時,流量會流向第一個節點的根網路命名空間。接著,流量會離開第一個節點的主要網路介面,並進入虛擬私有雲網路。由於 Pod IP 位址可在虛擬私有雲原生 GKE 叢集中以原生方式轉送,因此虛擬私有雲網路會將流量直接轉送至第二個節點。第二個節點接著會將流量轉送至目的地 Pod。
主機網路 Pod
在特定用途中,您可以使用 hostNetwork: true 設定來設定 Pod。這項設定會略過隔離的 Pod 網路,讓 Pod 直接共用節點的網路命名空間。有了這項直接存取權,Pod 就能使用節點的 IP 位址,並與所有其他 Pod 通訊,無須使用 NAT。在採用 kubenet CNI 外掛程式的叢集中,這項行為與一般 Pod 不同。一般 Pod 需要 NAT 才能處理輸出流量,因為其 IP 位址無法在 VPC 網路上直接路由。相較之下,GKE 的 VPC 原生網路可讓所有 Pod 無須進行這項轉換。不過,使用 hostNetwork: true 設定設定 Pod 時,請小心避免與在相同節點上執行的其他程序或 Pod 發生連接埠衝突。在使用 kubenet CNI 的叢集中,只有在節點具有 hostNetwork: false 設定的 Pod 時,才會建立 cbr0 虛擬網路橋接器。
Service Networking
雖然 Pod 網路提供個別 Pod 之間的基本連線能力,但不足以建構穩固且可擴充的應用程式。Pod 是暫時性的,隨時可以建立、毀損及重新排程。這會導致 IP 位址變更。服務網路提供穩定可靠的方式來公開應用程式,並管理應用程式在叢集內和外部環境的通訊方式,解決上述問題。
Kubernetes Service 是一種抽象層,用於定義邏輯上的一組 Pod 和這些 Pod 依據的存取政策。Service 會使用標籤,將多個相關 Pod 分組為單一邏輯單元。建立 Service 時,Kubernetes 會從為 Service 保留的位址集區中,指派穩定虛擬 IP 位址 (稱為 ClusterIP)。這個 ClusterIP 和相關聯的 DNS 名稱在整個服務生命週期內都會保持不變,可提供一致的端點,供其他應用程式用來連線至 Pod。
服務網路的運作方式
服務網路會透過兩項重要機制,將流量從 Service 的穩定端點轉送至動態後端 Pod:服務探索和負載平衡。
服務探索:為了讓應用程式彼此尋找及通訊,GKE 提供內部 DNS 服務 (kube-dns 或 Cloud DNS)。建立服務時,DNS 服務會自動建立對應的 DNS 記錄。這項記錄可讓應用程式使用 DNS 名稱 (例如 my-app-service) 連線至 Service,而不必知道其 ClusterIP。雖然 kube-dns 是 Standard 叢集的預設值,但 Cloud DNS for GKE 是大多數正式環境的建議解決方案。此外,這也是 GKE Autopilot 叢集唯一支援的解決方案。這項服務為全代管、可擴充且可用性高。這項服務與虛擬私有雲網路和 Cloud Logging 整合,可提升效能和觀測能力,且無須管理 kube-dns Pod。
負載平衡機制:服務負載平衡的實作方式取決於 GKE 叢集的網路模式。
GKE Dataplane V2:使用 GKE Dataplane V2 (以 Cilium 為基礎) 的叢集不會使用
kube-proxy進行服務負載平衡。而是使用在 Linux 核心中執行的 GKE Dataplane V2 eBPF 程式。這些 eBPF 程式可高效攔截傳送至 Service ClusterIP 的流量,並直接將流量負載平衡至適當的後端 Pod。這種做法可提升效能,並與 GKE Dataplane V2 的網路政策強制執行功能緊密整合。kube-proxy(適用於沒有 GKE Dataplane V2 的叢集):在未使用 GKE Dataplane V2 的 GKE 叢集中的每個節點上,名為kube-proxy的元件會實作服務的虛擬 IP 位址機制。kube-proxy會監控 Kubernetes API 伺服器,查看 Service 和端點是否有變更,然後在節點上設定網路規則,攔截傳送至 Service ClusterIP 的流量。kube-proxy可以運作在不同模式,包括:iptables模式:這是預設模式。kube-proxy會在節點的iptables子系統中新增及移除目的地 NAT (DNAT) 規則。當流量到達 Service 的 ClusterIP 時,這些規則會執行 NAT 轉譯,並將目的地 IP 位址變更為其中一個健康狀態良好的後端 Pod。後端 Pod 的負載平衡通常是隨機或循環式。ipvs模式:這個模式使用 Linux IP 虛擬伺服器 (IPVS) 進行高效能負載平衡。kube-proxy會設定 IPVS 規則,可處理大量服務,並提供更精密的負載平衡演算法。
內部通訊流程範例
下表說明在未使用 GKE Dataplane V2 的叢集中,要求如何透過 Service 從用戶端 Pod 流向伺服器 Pod:
- 用戶端應用程式會對
my-server-service進行 DNS 查詢。 - 叢集的內部 DNS 服務會將這個名稱解析為 Service 的穩定 ClusterIP (例如
10.0.32.8)。 - 用戶端 Pod 會將要求傳送至 Service 的 ClusterIP。
- 用戶端節點上的
iptables規則 (由kube-proxy管理) 會攔截這項要求。 - 這些
iptables規則會執行 DNAT,並為my-server-service選取其中一個運作正常的後端 Pod (例如 IP 位址為10.4.0.3的 Pod 2)。規則也會將封包的目的地 IP 位址重新寫入 Pod 的 IP 位址。 - 封包會透過平面 Pod 網路轉送至 Pod 2,由 Pod 2 處理要求。
在採用 GKE Dataplane V2 的叢集中,eBPF 程式會處理 Service ClusterIP 的流量攔截和負載平衡作業,並略過 kube-proxy 和 iptables。
服務資訊清單範例
以下範例顯示服務資訊清單。selector 欄位會根據 Pod 的標籤,指定哪些 Pod 接收流量。
apiVersion: v1
kind: Service
metadata:
name: my-server-service
spec:
selector:
app: my-server # This should match the labels on your server Pods
ports:
- protocol: TCP
port: 80 # The port the Service exposes
targetPort: 8080 # The port the containers in the Pods are listening on
服務網路功能
GKE 服務網路提供多項功能,可管理流量,並對內和對外公開應用程式。
- 內部和外部負載平衡。對於只能從叢集內部存取的 Service,
kube-proxy(或 GKE Dataplane V2) 會在內部處理負載平衡。對於需要向網際網路公開的服務,GKE 會自動佈建 Cloud 負載平衡器,將外部流量分配至叢集中的節點。 - 用於 HTTP(S) 轉送的應用程式負載平衡器。針對 HTTP(S) 流量,GKE 會使用專門的第 7 層負載平衡器,即應用程式負載平衡器。您可以使用 Kubernetes Gateway API 設定這個負載平衡器,這是所有新應用程式的建議做法。GKE Gateway 控制器是 Google 實作的 Gateway API,旨在成為 Ingress 資源的後繼產品,提供更豐富的表達能力、彈性和擴充性。Gateway API 會使用下列資源設定負載平衡器:
- 閘道:定義接聽程式設定,例如通訊埠、通訊協定和主機名稱。做為流量的進入點。
- HTTPRoute:指定閘道收到的流量如何轉送至服務。支援路徑式轉送、標頭比對和流量拆分等進階功能。
- 政策:定義附加至閘道、路由或服務的基礎 Google Cloud 架構運作方式。
- 服務網格整合。適用於複雜的微服務架構,GKE 支援服務網格技術。服務網格是選用的基礎架構層,可提供流量管理、觀測能力和安全防護等進階功能。如要享有全代管和支援服務,GKE 提供以 Istio 為基礎的 Cloud Service Mesh。
叢集網路
叢集網路是 GKE 網路的最外層。重點在於整個 Kubernetes 叢集如何與外部資源和網路互動,包括網際網路用戶端如何連至應用程式、Pod 如何存取外部 API,以及叢集如何連至地端部署資料中心。叢集網路是以 Google Cloud的虛擬私有雲基礎架構為基礎。
管理傳入流量
Ingress 是指從外部世界進入叢集的流量。GKE 會使用多項整合式 Google Cloud 功能管理及保護這類流量。
外部存取資料流程:當網際網路用戶端向應用程式 (通常透過 LoadBalancer 類型的 Service 或 Ingress 或 Gateway 資源公開) 傳送要求時,要求會先到達 Google Cloud 負載平衡器。負載平衡器會將要求轉送至叢集內健康狀態良好的節點。節點會將流量轉送至適當的 Pod。在不使用 GKE Dataplane V2 的叢集上,kube-proxy 會處理這項轉送作業;在使用 GKE Dataplane V2 的叢集上,則由 eBPF 程式處理。目的地 Pod 可能位於相同或不同的節點。
防火牆規則:GKE 叢集使用虛擬私有雲防火牆規則控管傳入流量。雖然 GKE 會自動建立一些預設防火牆規則,用於執行必要的叢集作業 (例如允許控制層連至節點),但您也可以定義自訂規則,滿足特定的安全性需求。這些 VPC 防火牆規則可搭配 Kubernetes 網路政策,在節點和 Pod 層級控管流量,提供縱深防禦機制。
最佳化外部流量:負載平衡器將流量傳送至節點時,節點可能需要將流量轉送至其他節點上的 Pod,這需要額外的網路躍點。為避免發生這種狀況,請在服務資訊清單中將 externalTrafficPolicy 欄位設為 Local。這項政策啟用後,負載平衡器會使用健康狀態檢查,找出目標服務中健康狀態良好的 Pod 所在的節點。負載平衡器只會將流量傳送至健康狀態良好的 Pod,避免額外的網路躍點。不過,如果後端 Pod 未平均分布在叢集中的節點,這項政策可能會導致流量分配不均。
管理傳出流量
輸出是指離開叢集的流量。如要讓 GKE 叢集正常運作,並讓應用程式連線至外部服務,您必須管理多個連線路徑。
基本連線需求:所有 GKE 叢集都必須具備連至 *.googleapis.com、*.gcr.io 和 *.pkg.dev 網域的傳出連線。連至控制層 IP 位址的傳出連線也必須正常運作。使用 Cloud NAT 為 Pod 提供網際網路存取權:在 Pod 沒有公用 IP 位址的私人叢集中,使用 Cloud NAT 啟用輸出網際網路存取權。Cloud NAT 是一項代管服務,可讓 Pod 連線至網際網路,執行下載更新或存取外部 API 等工作,同時不會將 Pod 暴露於連入連線。
連線能力 Google Cloud 至服務:如要允許叢集與其他 Google Cloud 服務 (例如 Cloud Storage 或 Cloud SQL) 安全通訊,且不經過公開網際網路,請使用 Private Google Access。這是與 Google API 互動的私有叢集的重要輸出機制。
混合式和多叢集連線能力
如要將 GKE 叢集連線至地端部署基礎架構,請使用 Cloud VPN 建立加密通道,或使用 Cloud Interconnect 建立專屬的高頻寬連線。如要啟用多個 GKE 叢集之間的通訊,請使用多叢集服務,這項服務可促進不同叢集、區域或專案之間的服務探索和流量流動。
網路安全性控管
為保護叢集和在其中執行的應用程式,GKE 提供多層安全控管機制,可防範內部 (東西向) 和外部 (南北向) 流量。
使用網路政策保護內部流量 (東西向)
根據預設,GKE 叢集中的所有 Pod 都能自由通訊。如要保護內部流量並落實最小權限原則,可以使用 NetworkPolicy。NetworkPolicy 是 Kubernetes 資源,可控管 Pod 之間的網路流量,做為 Pod 的防火牆。NetworkPolicy 資源可讓您定義規則,根據標籤、IP 位址範圍和通訊埠號碼的組合,限制所選 Pod 群組的傳入和傳出流量。在命名空間中建立第一個 NetworkPolicy 時,系統會拒絕該政策未明確允許的所有流量。這些政策的強制執行機制直接建構於 GKE Dataplane V2 中,或由叢集的 CNI 外掛程式 (例如 Calico) 處理。
NetworkPolicy 資訊清單範例
下列範例顯示 NetworkPolicy 資訊清單。這項政策適用於具有 app: backend 標籤的 Pod,且僅允許具有 app: frontend 標籤的 Pod 透過 TCP 通訊埠 6379 輸入流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 6379
安全地從外部存取叢集
控管進出叢集的流量,對於保護應用程式免受外部威脅至關重要。
虛擬私有雲防火牆規則
GKE 叢集位於 Google Cloud 虛擬私有雲 網路中,並受到虛擬私有雲防火牆規則保護,可控管 叢集節點的傳入和傳出流量。虛擬私有雲防火牆規則和網路政策會相互搭配,提供縱深防禦。VPC 防火牆則在節點 (第 3 層或第 4 層) 層級運作,控管傳送至 VM 本身的流量。網路政策在 Pod (第 3 層或第 4 層) 層級運作,可更精細地控管叢集內應用程式之間的流量。
kubectl exec 等功能無法運作。限制負載平衡器的存取權
使用 Kubernetes Service 或 Ingress 公開應用程式時,您可以在負載平衡器層級套用額外的安全控管機制。如果是外部負載平衡器,請考慮下列選項:
- 如果您使用
type: LoadBalancer欄位公開 Service,可以在 Service 資訊清單中指定loadBalancerSourceRanges欄位。這個欄位會限制服務存取權,僅允許您定義的 IP 位址範圍存取。 如果使用應用程式負載平衡器 (Ingress),公開 HTTP(S) 應用程式時,可以採用更進階的安全防護服務:
- Google Cloud Armor:這項服務是網頁應用程式防火牆 (WAF),可協助保護應用程式免受 DDoS 攻擊和其他網路式威脅。
- Identity-Aware Proxy (IAP):如要進行精細的存取權控管,可以在端點上啟用 IAP。IAP 會驗證使用者身分,並據此判斷是否應允許使用者存取應用程式。
自訂 CNI
GKE 提供原生支援的 CNI 選項,包括預設的 Google CNI、Calico 和 GKE Dataplane V2。雖然其他第三方自訂 CNI 可能可在叢集中運作,但 GKE 並未正式支援這些 CNI。使用自訂 CNI 時,您必須管理其設定,並排解任何潛在問題。
如果系統在叢集中偵測到自訂 CNI,GKE 會提供建議,建議您移除自訂 CNI,確保設定符合支援條件。如果是服務網格用途,自訂 Istio 安裝項目也視為不支援,建議改用 Cloud Service Mesh。
後續步驟
- 瞭解如何建立 VPC 原生叢集。
- 進一步瞭解 GKE Dataplane V2。
- 實施網路政策,保護 Pod 對 Pod 的通訊。
- 探索使用 Service 公開應用程式,以及使用 Gateway API 設定 Ingress 的不同方式。