瞭解 GKE 網路架構

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 工作站節點 (即 Compute Engine VM) 都會從這個範圍取得主要 IP 位址。這些 IP 位址用於節點間的通訊,以及負載平衡器的健康狀態檢查。節點 IP 位址也是源自節點本身的流量來源。在虛擬私有雲原生叢集中,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)。
  • 服務 IP 位址範圍 (ClusterIP):指派給 Kubernetes 服務的虛擬 IP 位址 (ClusterIP) 次要 IP 位址範圍。這些穩定 IP 位址僅用於叢集內的通訊。
  • 控制層 IP 位址:每個控制層都有公開或內部 IP 位址,視叢集類型、版本和建立日期而定。工作節點和外部用戶端 (例如 kubectl) 會使用這個 IP 位址,與 Kubernetes API 伺服器安全地通訊。GKE 前端 (GKFE) 會為每個叢集提供 DNS 型端點,讓您安全可靠地存取控制層,不必直接管理 IP 位址。

GKE 網路的三大支柱

GKE 網路由三個相互連結的支柱組成,分別代表不同的通訊層。這個架構可協助您瞭解應用程式如何在叢集內通訊,以及如何與外部網路通訊:

  • Pod 網路:基礎層,定義叢集內個別容器 (Pod) 之間的通訊方式。
  • 服務網路:以 Pod 網路為基礎,這個層級說明 Kubernetes 服務如何提供穩定的端點,以對內部或外部用戶端公開應用程式,包括負載平衡和服務探索。
  • 叢集網路:最外層,涵蓋整個 GKE 叢集如何連線至更廣泛的網路生態系統,包括管理來自網際網路的 Ingress、傳送至外部服務的 Egress,以及連線至 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:這是虛擬私有雲原生叢集的預設 CNI。Pod 的 veth pair 會連線至節點的根網路命名空間。由於 Pod IP 位址是虛擬私有雲網路已知的別名 IP 位址,節點上的標準 Linux 路由會將流量導向 Pod,並從 Pod 導出流量。
    • GKE Dataplane V2:這項功能會使用 eBPF 程式處理 Pod 網路,並經常略過傳統的 Linux 橋接器和 veth 配對,直接管理核心內的封包流量,進而提升效能。
    • Kubenet:用於非虛擬私有雲原生叢集。veth pair 的另一端會連接到節點根命名空間中名為 cbr0 的 Linux 橋接裝置。這個橋接器會管理相同節點上 Pod 之間的流量,並針對離開節點的流量使用 NAT。
    • Calico:啟用 Calico 網路政策後,veth pair 的另一端會連線至節點的根命名空間,然後 Calico 會編寫主機路徑,將流量導向正確的 Pod。

最大傳輸單位 (MTU):決定可透過網路傳送的最大封包大小,不會遭到分段。在 GKE 中,Pod 介面的 MTU 是重要設定,取決於叢集使用的 GKE CNI 外掛程式,以及基礎 VPC 網路的 MTU 設定。MTU 值不符可能會導致封包遺失或效能降低。Pod 介面 MTU 值為固定的 1460 位元組,或從節點的主要網路介面繼承,如下表所示。

CNI MTU 用量
Google CNI 1460 使用 1.26.1 之前的 GKE 版本時,虛擬私有雲原生叢集的預設值。
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 for GKE 或 IPv4/IPv6 雙堆疊網路等功能時使用。

Pod 對 Pod 通訊流程

Kubernetes 使用扁平網路模型,每個 Pod 都有可路由傳輸的不重複 IP 位址。這個模型可確保 Pod 之間的連線順暢。

同一節點內的通訊

當 Pod 將流量傳送給同一節點上的另一個 Pod 時,要求會從第一個 Pod 的網路命名空間流動,通過其 veth 配對,然後進入節點的根網路命名空間。這類流量會留在節點內。視使用的 CNI 外掛程式而定,CNI 外掛程式接著會將流量轉送至第二個 Pod 的 veth pair。舉例來說,使用 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 位址無法在虛擬私有雲網路中直接路由。相較之下,GKE 的 VPC 原生網路可讓所有 Pod 無須進行這項轉換。不過,使用 hostNetwork: true 設定設定 Pod 時,請小心避免與在同一節點上執行的其他程序或 Pod 發生通訊埠衝突。在使用 kubenet CNI 的叢集中,只有在節點有 hostNetwork: false 設定的 Pod 時,才會建立 cbr0 虛擬網路橋接器。

Service Networking

雖然 Pod 網路可在個別 Pod 之間提供基本連線,但不足以建構強大且可擴充的應用程式。Pod 是暫時性的,隨時可以建立、毀損及重新排程。因此 IP 位址會變更。服務網路提供穩定可靠的方式來公開應用程式,並管理應用程式在叢集內和外部的通訊方式,解決上述問題。

Kubernetes Service 是一種抽象層,用於定義邏輯上的一組 Pod 和存取這些 Pod 的政策。服務會使用標籤將多個相關的 Pod 組合成一個邏輯單元。建立 Service 時,Kubernetes 會從為 Service 保留的位址集區中,指派穩定虛擬 IP 位址 (又稱 ClusterIP)。這個 ClusterIP 和相關聯的 DNS 名稱在整個 Service 生命週期內都會保持不變,提供一致的端點,供其他應用程式用來連線至 Pod。

Service Networking 的運作方式

服務網路會透過兩項主要機制,將流量從服務的穩定端點轉送至動態後端 Pod:服務探索和負載平衡。

服務探索:為了讓應用程式彼此尋找及通訊,GKE 提供內部 DNS 服務 (kube-dns 或 Cloud DNS)。建立 Service 時,DNS 服務會自動建立對應的 DNS 記錄。應用程式可透過這項記錄使用 DNS 名稱 (例如 my-app-service) 連線至 Service,不必知道 ClusterIP。雖然 kube-dns 是標準叢集的預設值,但 Cloud DNS for GKE 是大多數正式環境的建議解決方案。此外,這也是 GKE Autopilot 叢集唯一支援的解決方案。這項服務完全代管、可擴充且具備高可用性。這項服務與 VPC 網路和 Cloud Logging 整合,可提升效能和觀測能力,且無須管理 kube-dns Pod。

負載平衡機制:服務負載平衡的實作方式取決於 GKE 叢集的網路模式。

  • GKE Dataplane V2:使用 GKE Dataplane V2 (以 Cilium 為基礎) 的叢集不會使用 kube-proxy 進行 Service 負載平衡。而是使用在 Linux 核心中執行的 eBPF 程式。這些 eBPF 程式可有效攔截傳送至服務 ClusterIP 的流量,並直接將流量以負載平衡方式傳送至適當的後端 Pod。這種做法可提升效能,並與 GKE Dataplane V2 的網路政策強制執行功能緊密整合。

  • kube-proxy (適用於沒有 GKE Dataplane V2 的叢集):在不使用 GKE Dataplane V2 的 GKE 叢集中的每個節點上,名為 kube-proxy 的元件會實作服務的虛擬 IP 位址機制。kube-proxy 會監控 Kubernetes API 伺服器,瞭解服務和端點的變更,然後在節點上設定網路規則,攔截傳送至服務 ClusterIP 的流量。

    kube-proxy 可以運作在不同模式,包括:

    • iptables 模式:這是預設模式。kube-proxy 會在節點的 iptables 子系統中新增及移除目的地 NAT (DNAT) 規則。當流量抵達服務的 ClusterIP 時,這些規則會執行 NAT 轉換,並將目的地 IP 位址變更為其中一個健康狀態良好的後端 Pod。後端 Pod 的負載平衡通常是隨機或循環式。
    • ipvs 模式:這個模式會使用 Linux IP 虛擬伺服器 (IPVS) 進行高效能負載平衡。kube-proxy 會設定 IPVS 規則,可處理大量服務,並提供更精密的負載平衡演算法。

內部通訊流程範例

下列清單說明在未使用 GKE Dataplane V2 的叢集中,要求如何透過服務從用戶端 Pod 流向伺服器 Pod:

  1. 用戶端應用程式對 my-server-service 進行 DNS 查詢。
  2. 叢集的內部 DNS 服務會將這個名稱解析為 Service 的穩定 ClusterIP (例如 10.0.32.8)。
  3. 用戶端 Pod 會將要求傳送至 Service 的 ClusterIP。
  4. 用戶端節點上的 iptables 規則 (由 kube-proxy 管理) 會攔截這項要求。
  5. 這些 iptables 規則會執行 DNAT,並為 my-server-service 選取其中一個狀況良好的後端 Pod (例如 IP 位址為 10.4.0.3 的 Pod 2)。規則也會將封包的目的地 IP 位址重新寫入 Pod 的 IP 位址。
  6. 封包會透過扁平 Pod 網路轉送至 Pod 2,並由 Pod 2 處理要求。

在採用 GKE Dataplane V2 的叢集中,eBPF 程式會處理流量的攔截和負載平衡,將流量導向 Service ClusterIP,並略過 kube-proxyiptables

Example Service 資訊清單

以下範例顯示 Service 資訊清單。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

Service Networking 的功能

GKE 服務網路提供多項功能,可管理流量並公開應用程式 (無論是內部或外部)。

  • 內部和外部負載平衡。對於只能從叢集內存取的服務,kube-proxy (或 GKE Dataplane V2) 會在內部處理負載平衡。對於需要向網際網路公開的服務,GKE 會自動佈建雲端負載平衡器,將外部流量分配至叢集中的節點。
  • 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的 VPC 基礎架構為基礎。

管理傳入流量

輸入流量是指從外部世界進入叢集的流量。 GKE 會使用多項整合式 Google Cloud 功能管理及保護這類流量。

外部存取資料流:當網際網路的用戶端將要求傳送至應用程式時 (通常是透過 LoadBalancer 類型的服務或 Ingress/Gateway 資源公開發布),要求會先抵達 Google Cloud 負載平衡器。負載平衡器會將要求轉送至叢集中狀態良好的節點。節點會將流量轉送至適當的 Pod。kube-proxy 會在未使用 GKE Dataplane V2 的叢集上處理這項轉送作業,或由 eBPF 程式在採用 GKE Dataplane V2 的叢集上處理。目的地 Pod 可能位於相同或不同節點。

防火牆規則:GKE 叢集會使用虛擬私有雲防火牆規則控管輸入流量。雖然 GKE 會自動為基本叢集作業建立一些預設防火牆規則,例如允許控制層連線至節點,但您可以定義自訂規則,滿足特定安全防護需求。這些 VPC 防火牆規則會與 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 等工作,同時避免 Pod 暴露於連入連線。

服務連線 Google Cloud :如要允許叢集與其他 Google Cloud 服務 (例如 Cloud Storage 或 Cloud SQL) 安全通訊,且不經過公開網際網路,請使用 Private Google Access。這是與 Google API 互動的私有叢集的重要輸出機制。

混合式和多叢集連線

如要將 GKE 叢集連線至內部部署基礎架構,請使用 Cloud VPN 建立加密通道,或使用 Cloud Interconnect 建立專屬的高頻寬連線。如要啟用多個 GKE 叢集之間的通訊,請使用多叢集服務,這項服務可促進不同叢集、區域或專案之間的服務探索和流量流動。

網路安全性控管

為保護叢集和其中執行的應用程式,GKE 提供多層安全控制項,可同時防護內部 (東西向) 和外部 (南北向) 流量。

使用網路政策保護內部流量 (東向)

根據預設,GKE 叢集中的所有 Pod 皆可自由通訊。如要保護內部流量並強制執行最低權限原則,可以使用 NetworkPolicyNetworkPolicy 是 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 虛擬私有雲端網路中,並受到虛擬私有雲端防火牆規則保護,可控管叢集節點的流量。虛擬私有雲防火牆規則和網路政策會相互搭配,提供縱深防禦機制。虛擬私有雲防火牆會在節點 (第 3 層或第 4 層) 層級運作,並控管 VM 本身的流量。網路政策會在 Pod (第 3 層或第 4 層) 層級運作,可更精細地控管叢集內應用程式之間的流量。

建立以叢集節點為目標的輸入或輸出防火牆規則,可能會產生負面影響。舉例來說,對叢集中的節點套用輸出拒絕規則,可能會導致 NodePort 和 kubectl exec 等功能無法運作。

限制負載平衡器的存取權

使用 Kubernetes 服務或 Ingress 公開應用程式時,您可以在負載平衡器層級套用額外的安全控管措施。如果是外部負載平衡器,請考慮下列選項:

  • 如果您使用 type: LoadBalancer 欄位公開服務,可以在服務資訊清單中指定 loadBalancerSourceRanges 欄位。這個欄位會限制只有您定義的 IP 位址範圍可以存取服務。
  • 如果是應用程式負載平衡器 (Ingress),公開 HTTP(S) 應用程式時,可以使用更進階的安全性服務:

    • Google Cloud Armor:這項服務是網路應用程式防火牆 (WAF),可協助保護應用程式,防範 DDoS 攻擊和其他網路威脅。
    • Identity-Aware Proxy (IAP):如要進行精細的存取權控管,可以在端點上啟用 IAP。IAP 會驗證使用者身分,並據此判斷是否應授予應用程式存取權。

後續步驟