Google Kubernetes Engine (GKE) 網路會使用並擴充虛擬私有雲 (VPC) 提供的軟體定義網路 (SDN) 基礎架構。GKE 網路可讓元件在 Kubernetes 叢集內,以及與外部服務和網路之間進行通訊。GKE 網路模型以 Kubernetes 網路原則為基礎,每個 Pod 都有自己的 IP 位址,可提供 IP 定址、負載平衡、DNS 解析和網路政策強制執行功能。本文說明節點、Pod 和 Service 等核心元件,如何在 GKE 網路環境中與控制層互動,涵蓋以下內容:
- 這些元件在虛擬私有雲中的互動方式
- IP 位址的分配和管理方式
- 流量如何流入、流出叢集,以及在叢集內流動
GKE 網路架構
GKE 網路是以 Google Cloud的虛擬私有雲 (VPC) 為基礎。這個基礎可為所有容器化應用程式,提供強大且可擴充的連線能力。
虛擬私有雲基礎和 IP 位址範圍
您可以在虛擬私有雲中定義子網路,也就是區域 IP 位址範圍。GKE 會策略性地在這些子網路中,為各種叢集元件使用不同的 IP 位址範圍,通常會使用虛擬私有雲別名 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) 之間的通訊方式。
- Service 網路:這個層級以 Pod 網路為基礎,說明 Kubernetes Service 如何提供穩定的端點,向內部或外部用戶端公開應用程式,包括負載平衡和服務探索。
- 叢集網路:最外層,涵蓋整個 GKE 叢集如何連線至更廣泛的網路生態系統,包括管理來自網際網路的輸入流量、輸出至外部服務的流量,以及與 Google Cloud 服務和地端部署系統的連線能力。
這些層級會共同運作,建立全面的通訊模型,支援內部和外部連線、安全性和擴充性。以下各節將詳細探討每個要素。
Pod 網路
Pod 網路是 GKE 叢集內所有通訊的基礎。定義 Pod 內執行的應用程式如何找到彼此並互動。在 Kubernetes 中,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 的 IP 位址無法直接在虛擬私有雲網路中轉送,因此需要 NAT 處理傳出流量。相較之下,GKE 的虛擬私有雲原生網路可讓所有 Pod 免除這項轉譯作業。不過,使用 hostNetwork: true 設定 Pod 時,請務必避免與在相同節點上執行的其他程序或 Pod 發生通訊埠衝突。在使用 kubenet CNI 的叢集中,只有在節點具有 hostNetwork: false 設定的 Pod 時,才會建立 cbr0 虛擬網路橋接器。
Service Networking
雖然 Pod 網路提供個別 Pod 之間的基本連線能力,但不足以建構穩固、可擴充的應用程式。Pod 是暫時性的,隨時可以建立、刪除及重新排程。這種情況會導致 IP 位址變更。Service 網路可提供穩定可靠的方法,公開應用程式並管理其通訊方式 (包括叢集內部和與外部通訊),進而解決這個問題。
Kubernetes Service 是一種抽象層,用於定義邏輯上的一組 Pod 和這些 Pod 依據的存取政策。Service 會使用標籤,將多個相關 Pod 分組為單一邏輯單元。建立 Service 時,Kubernetes 會從保留給 Service 的位址集區中,指派一個穩定的虛擬 IP 位址 (稱為 ClusterIP)。這個 ClusterIP 和相關聯的 DNS 名稱在 Service 的整個生命週期內保持不變,提供一致的端點,讓其他應用程式可用來連線至 Pod。
Service Networking 的運作方式
Service 網路仰賴兩項重要機制,將流量從 Service 的穩定端點轉送至動態後端 Pod:服務探索和負載平衡。
服務探索:為讓應用程式能找到彼此並相互通訊,GKE 提供內部 DNS 服務 (kube-dns 或 Cloud DNS)。建立 Service 時,DNS 服務會自動建立對應的 DNS 記錄。這項記錄可讓應用程式使用 Service 的 DNS 名稱 (例如 my-app-service) 連線至 Service,而不必知道其 ClusterIP。雖然 kube-dns 是 Standard 叢集的預設值,但 Cloud DNS for GKE 是大多數正式環境的建議解決方案。這也是 GKE Autopilot 叢集唯一支援的解決方案。這項服務為全代管、可擴充且具備高可用性。這項服務與虛擬私有雲網路和 Cloud Logging 整合,可提升效能和觀測能力,您不必管理 kube-dns Pod。
負載平衡機制:Service 負載平衡的實作方式取決於 GKE 叢集的網路模式。
GKE Dataplane V2:使用 GKE Dataplane V2 (以 Cilium 為基礎) 的叢集不會使用
kube-proxy進行 Service 負載平衡。而是使用在 Linux 核心中執行的 GKE Dataplane V2 eBPF 程式。這些 eBPF 程式能有效攔截傳送至 Service ClusterIP 的流量,並直接將流量負載平衡至適當的後端 Pod。這種做法可提升效能,並與 GKE Dataplane V2 的網路政策強制執行功能緊密整合。kube-proxy(適用於不含 GKE Dataplane V2 的叢集):在不使用 GKE Dataplane V2 的 GKE 叢集中,每個節點上都有一個名為kube-proxy的元件,可為 Service 實作虛擬 IP 位址機制。kube-proxy會監控 Kubernetes API 伺服器,查看 Service 和端點是否有變更,然後在節點上設定網路規則,攔截目的地為 Service ClusterIP 的流量。kube-proxy可以在不同模式下運作,包括:iptables模式:這是預設模式。kube-proxy會在節點的iptables子系統中新增及移除目的地網路位址轉譯 (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。
Service 資訊清單範例
以下範例顯示 Service 資訊清單。selector 欄位會根據標籤,指定哪些 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
Service Networking 的功能
GKE Service 網路提供多項功能,可管理流量及公開應用程式,無論是內部或外部流量皆可。
- 內部和外部負載平衡。對於只能從叢集內部存取的 Service,
kube-proxy(或 GKE Dataplane V2) 會在內部處理負載平衡。對於需要公開至網際網路的 Service,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。kube-proxy 會在不使用 GKE Dataplane V2 的叢集上處理這項轉送作業,而 eBPF 程式則會在採用 GKE Dataplane V2 的叢集上處理這項作業。目的地 Pod 可能位於相同或不同的節點。
防火牆規則:GKE 叢集使用虛擬私有雲防火牆規則控管傳入流量。雖然 GKE 會自動建立一些預設防火牆規則,用於執行必要的叢集作業 (例如允許控制層連至節點),但您也可以定義自訂規則,滿足特定的安全性需求。這些虛擬私有雲防火牆規則會與 Kubernetes 網路政策搭配運作,在節點和 Pod 層級控管流量,提供縱深防禦。
最佳化外部流量:負載平衡器將流量傳送至節點時,節點可能需要將流量轉送至其他節點上的 Pod,這需要額外的網路躍點。為避免這種情況,請在 Service 資訊清單中將 externalTrafficPolicy 欄位設為 Local。啟用這項政策後,負載平衡器會使用健康狀態檢查,找出哪些節點具有目標 Service 的健康 Pod。負載平衡器只會將流量傳送至健康狀態良好的 Pod,避免額外的網路躍點。缺點是,如果後端 Pod 未平均分布在叢集中的節點,這項政策可能會導致流量分布不均。
管理傳出流量
輸出是指離開叢集的流量。如要讓 GKE 叢集正常運作,並讓應用程式連線至外部服務,您必須管理多個連線路徑。
基本連線需求:所有 GKE 叢集都必須具備連至 *.googleapis.com、*.gcr.io 和 *.pkg.dev 網域的傳出連線。連至控制層 IP 位址的傳出連線也必須正常運作。使用 Cloud NAT 讓 Pod 存取網際網路:在 Pod 沒有公開 IP 位址的私人叢集中,使用 Cloud NAT 啟用傳出網際網路存取權。Cloud NAT 是一項代管服務,可讓 Pod 連線至網際網路,執行下載更新或存取外部 API 等工作,而不會向傳入連線公開。
連線至 Google Cloud 服務:如要允許叢集與其他 Google Cloud 服務 (例如 Cloud Storage 或 Cloud SQL) 安全通訊,而不透過公開網際網路,請使用私人 Google 存取權。對於與 Google API 互動的私人叢集來說,這是重要的輸出機制。
傳出頻寬限制:GKE 不會對輸入或輸出流量強制執行預設的個別 Pod 或個別容器網路頻寬限制。由於每個 GKE 節點都是 Compute Engine VM,因此節點上的所有 Pod 都會共用適用於該節點的網路頻寬限制。節點的輸出容量上限取決於 VM 的機型、網路設定、流量目的地和適用的 Google Cloud配額。如要進一步瞭解節點輸出頻寬的計算方式,以及如何提高節點頻寬,請參閱「各執行個體的輸出頻寬上限」和「提高叢集和節點的網路頻寬」。
混合式和多叢集連線能力
如要將 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,GKE 會提供建議,請您移除自訂 CNI,確保設定符合支援條件。如果是服務網格用途,自訂 Istio 安裝項目也視為不支援,建議改用 Cloud Service Mesh。
後續步驟
- 瞭解如何建立 VPC 原生叢集。
- 進一步瞭解 GKE Dataplane V2。
- 實施網路政策,保護 Pod 對 Pod 的通訊。
- 探索使用 Service 公開應用程式,以及使用 Gateway API 設定 Ingress 的不同方式。