GKE 網路總覽


本頁面提供 Google Kubernetes Engine (GKE) 網路主要面向的指南。這些資訊適用於剛開始使用 Kubernetes 的人、經驗豐富的叢集操作者或應用程式開發人員,提供更多 Kubernetes 網路相關知識,讓他們能夠設計出更完善的應用程式或設定 Kubernetes 工作負載。

本頁面和這組說明文件的其餘部分,適用於為機構設計及建構網路的雲端架構師和網路專家。如果您是 Kubernetes 或 GKE 新手,或是需要進一步瞭解更一般的 GKE 主題,請參閱核心 GKE 說明文件,其中涵蓋所有 GKE 使用者都能使用的核心功能。如要查看所有 GKE 說明文件集的總覽,請參閱「探索 GKE 說明文件」。如要進一步瞭解我們在Google Cloud 內容中提及的常見角色和範例工作,請參閱「常見的 GKE Enterprise 使用者角色和工作」。

Kubernetes 可讓您以陳述式定義應用程式的部署方式、應用程式彼此之間的通訊方式、應用程式與 Kubernetes 控制層的通訊方式,以及用戶端連線到應用程式的方式。本頁面也提供 GKE 如何透過網路設定 Google Cloud服務的資訊。

Kubernetes 網路的差異之處

如要使用 Kubernetes 自動化調度管理應用程式,您在思考應用程式及其主機的網路設計時,必須思考 Pod、Service 和外部用戶端該如何進行通訊,而不是主機或虛擬機器 (VM) 要如何連線。

Kubernetes 先進的軟體定義網路 (SDN) 技術能夠在同一個地區叢集中的不同區域,為 Pod、Service 和節點轉送送封包。此外,Kubernetes 和 Google Cloud 也會根據 Kubernetes 部署的陳述式模型以及 Google Cloud上的叢集設定,在每個節點上動態設定 IP 篩選規則、路由表和防火牆規則。

必要條件

閱讀本頁面之前,請先熟悉 Linux 網路管理概念,以及 iptables 規則和轉送等公用程式。

此外,請務必熟悉下列主題的基本術語:

Kubernetes 網路相關術語

Kubernetes 網路模型極度仰賴 IP 位址。服務、Pod、容器和節點會透過 IP 位址和通訊埠進行通訊。Kubernetes 提供不同類型的負載平衡,以將要求導向到正確的 Pod。本主題稍後會提供這些機制的詳細說明。閱讀時,請記住下列與 IP 位址相關的術語:

  • ClusterIP:指派給服務的 IP 位址。在其他文件中,ClusterIP 可能稱為「叢集 IP」。這個位址在服務的生命週期內會維持不變,詳見「服務」。
  • Pod IP 位址:指派給特定 Pod 的 IP 位址。這是一個臨時的位址,詳見「Pod」。
  • 節點 IP 位址:指派給特定節點的 IP 位址。

叢集連線需求

所有叢集都必須連線至 *.googleapis.com*.gcr.io*.pkg.dev 和控制平面 IP 位址。GKE 建立的默示允許輸出規則自動建立的防火牆規則,可滿足這項需求。

叢集內的網路

本節探討 Kubernetes 叢集內的網路,因為它與 IP 分配PodServiceDNS控制平面有關。

IP 位址分配

Kubernetes 使用多種 IP 範圍,將 IP 位址指派給節點、Pod 和 Service。

  • 每個節點都有一個 IP 位址,是從叢集的虛擬私有雲 (VPC) 網路指派而來。這個節點 IP 能讓 kube-proxykubelet 等控制元件連線到 Kubernetes API 伺服器。這個 IP 位址是節點與叢集其他部分的連接點。
  • 每個節點都有一個 IP 位址集區,GKE 會指派在該節點上執行的 Pod (預設為 /24 CIDR 區塊)。建立叢集時,您可以選擇指定 IP 的範圍。您可以利用 Pod CIDR 範圍的彈性調整功能,針對節點集區中的節點縮小 Pod IP 位址範圍。

  • 每個 Pod 都有一個 IP 位址,是從其節點的 Pod CIDR 範圍指派而來。這個 IP 位址會由所有在 Pod 內執行的容器共用,並將它們連接至在叢集中執行的其他 Pod。

  • 每個 Service 都有一個 IP 位址 (稱為 ClusterIP),是由叢集的虛擬私人雲端 (VPC) 網路指派而來。建立叢集時,您可以選擇自訂 VPC 網路。

  • 每個控制層都有公開或內部 IP 位址,視叢集類型、版本和建立日期而定。詳情請參閱控制層說明。

GKE 網路模型不允許在網路中重複使用 IP 位址。遷移至 GKE 時,您必須規劃 IP 位址分配,以減少 GKE 中的內部 IP 位址用量

最大傳輸單位 (MTU)

為 Pod 介面選取的 MTU 取決於叢集節點使用的容器網路介面 (CNI) 和基礎 VPC MTU 設定。詳情請參閱「Pod」。

Pod 介面 MTU 值為 1460,或從節點的主要介面繼承。

CNI MTU GKE Standard
kubenet 1460 預設
kubenet
(GKE 1.26.1 以上版本)
已繼承 預設
Calico 1460

使用 --enable-network-policy 啟用。

詳情請參閱使用網路政策控管 Pod 和服務之間的通訊

netd 已繼承 使用下列任一項目啟用:
GKE Dataplane V2 已繼承

使用 --enable-dataplane-v2 啟用。

詳情請參閱「使用 GKE Dataplane V2」。

詳情請參閱虛擬私有雲原生叢集

支援的網路外掛程式

  • 如要使用網路外掛程式,必須自行安裝。GKE 提供下列原生支援的網路外掛程式:
    • Calico (Dataplane V1)
    • Cilium (Dataplane V2 中)
    • Istio-CNI (位於 GKE Enterprise 的代管資料平面控制器中)

Pod

在 Kubernetes 中,Pod 是 Kubernetes 叢集內最基本的可部署單位。一個 Pod 可執行一或多個容器。 一個節點可執行零或多個 Pod。叢集中的每個節點都是節點集區的一部分。

在 GKE 中,這些節點是虛擬機器,做為 Compute Engine 中的執行個體運作。

Pod 也能連結至外部儲存磁碟區及其他自訂資源。 本圖表顯示執行兩個 Pod 的單一節點,這兩個 Pod 又各自連結至兩個磁碟區。

圖片

當 Kubernetes 排程要在節點上執行某個 Pod 時,會在節點的 Linux kernel 中為這個 Pod 建立網路命名空間。這個網路命名空間會連接節點的實體網路介面 (例如 eth0),而 Pod 則使用虛擬網路介面,讓封包傳入或傳出 Pod。在節點的根網路命名空間中,關聯的虛擬網路介面會連接到 Linux 橋接介面,允許在同一個節點上的 Pod 互相通訊。Pod 也能使用相同的虛擬介面,將封包傳送到節點外。

Kubernetes 會從節點上專為 Pod 預留的位址範圍,將 IP 位址 (Pod IP 位址) 指派給 Pod 的網路命名空間中的虛擬網路介面。這個位址範圍是指派給 Pod 叢集的 IP 位址範圍中的一部分,您可以在建立叢集時進行相關設定。

在 Pod 中執行的容器會使用 Pod 的網路命名空間。從容器的角度來看,Pod 像是一個具有網路介面的實體機器。Pod 中的所有容器都會看到同一個網路介面。 每個容器的 localhost 都會透過 Pod 連線至節點的實體網路介面,例如 eth0

請注意,此連接性差別很大,具體取決於您使用 GKE 的容器網路介面 (CNI),或選擇使用 Calico 的實作方式 (方法是在建立叢集時啟用網路政策)。

  • 如果您使用 GKE 的 CNI,虛擬乙太網路裝置 (veth) pair 的一端會連結到其命名空間中的 Pod,另一端則連接到 Linux 橋接裝置 cbr01 在這種情況下,下列指令會顯示連結到 cbr0 的各種 Pod 的 MAC 位址:

    arp -n
    

    在工具箱容器中執行下列指令,會顯示連結到 cbr0 的每一個 veth pair 的根命名空間端:

    brctl show cbr0
    
  • 如果啟用了網路政策,veth pair 的一端會連結到 Pod,另一端則連結到 eth0。在這種情況下,下列指令會顯示連結到不同 veth 裝置的各種 Pod MAC 位址:

    arp -n
    

    在工具箱容器中執行下列指令,會顯示沒有名為 cbr0 的 Linux 橋接裝置:

    brctl show
    

促成叢集內部轉送的 iptables 規則隨情況而異。進行連線問題的疑難排解時,必須牢記這些區別。

根據預設,每個 Pod 都可以存取同一個叢集中,在所有節點上執行的所有 Pod,但您可以限制 Pod 之間的互相存取。Kubernetes 會定期拆散 Pod 再重新建立。這會在變更 Pod 的陳述式設定或變更容器的映像檔,或是節點無法使用時,在升級節點集區時發生。因此,Pod 的 IP 位址算是一個實作細節,請勿仰賴這個設定。Kubernetes 會透過 Service 提供穩定的 IP 位址。

  1. 只有在有 Pod 設定 hostNetwork: false 時,才會建立虛擬網路橋接器 cbr0

服務

在 Kubernetes 中,您可以將任意鍵/值組合 (稱為標籤) 指派給任何 Kubernetes 資源。Kubernetes 使用標籤將多個相關的 Pod 組合成一個邏輯單元,這個邏輯單元即稱為「服務」。Service 有一個穩定的 IP 位址和數個通訊埠,並會在這組 Pod 之間提供負載平衡,前提是這些 Pod 的標籤符合您在建立 Service 時,在標籤選取器中定義的所有標籤。

以下圖表顯示兩個不同的 Service,各自由多個 Pod 構成。圖表中的每個 Pod 都有 app=demo 標籤,但其他標籤卻都不同。「frontend」Service 符合具有 app=democomponent=frontend 的所有 Pod,「users」Service 則符合具有 app=democomponent=users 的所有 Pod。用戶端 Pod 不完全符合這兩個 Service 選取器,因此,它不屬於任何一個 Service。不過,用戶端 Pod 可以與服務進行通訊,因為它們在同一個叢集中執行。

圖片

Kubernetes 會為每個新建立的 Service 指派一個穩定可靠的 IP 位址 (也就是 ClusterIP),這個 IP 位址來自叢集的可用 Service IP 位址集區。Kubernetes 也會新增 DNS 項目,以將主機名稱指派給 ClusterIP。叢集內的 ClusterIP 與主機名稱不能重複,且在 Service 的整個生命週期中都不會變更,只有從叢集的設定中刪除 Service 時,Kubernetes 才會釋出 ClusterIP 和主機名稱。您可以透過 ClusterIP 或服務的主機名稱,連至執行應用程式、健康狀態良好的 Pod。

乍看之下,服務似乎會造成應用程式單點故障。不過,Kubernetes 會盡可能將流量平均分散在整組 Pod 中,而這些 Pod 又是在眾多節點上執行,這樣叢集就能承受影響一或多個 (但非全部) 節點的服務中斷。

Kube-Proxy

Kubernetes 使用 kube-proxy 元件管理 Pod 與 Service 之間的互相連線,這個元件通常會在每個節點上以靜態 Pod 的形式執行。

kube-proxy 不是內建 Proxy,而是輸出型負載平衡控制器,其會在節點的 iptables 子系統新增及移除目的地 NAT (DNAT) 規則,以監控 Kubernetes API 伺服器,並持續將 ClusterIP 對應至健康狀態良好的 Pod。在 Pod 中執行的容器將流量傳送至 Service 的 ClusterIP 時,節點會隨機選取一個 Pod,並將流量轉送至該 Pod。

設定 Service 時,您可以選擇透過定義 porttargetPort 的值,重新對應其接聽埠。

  • port 是用戶端連至應用程式的位置。
  • targetPort 是應用程式實際聆聽 Pod 內流量的通訊埠。

kube-proxy 透過在節點上新增及移除 iptables 規則,管理這個通訊埠的重新對應。

這個圖表說明在不同節點上從用戶端 Pod 到伺服器 Pod 的流量。用戶端可在 172.16.12.100:80 連線到 Service。Kubernetes API 伺服器會維護執行應用程式的 Pod 清單。每個節點上的 kube-proxy 程序都會使用這個清單來建立 iptables 規則,將流量導向適當的 Pod (例如 10.255.255.202:8080)。用戶端 Pod 不需要知道叢集的拓撲,或其中個別 Pod 或容器的任何詳細資料。

圖片

kube-proxy 的部署方式取決於叢集的 GKE 版本:

  • 如果是 GKE 1.16.0 和 1.16.8-gke.13 版,kube-proxy 會以 DaemonSet 形式部署。
  • 如果是 1.16.8-gke.13 以上版本的 GKE,kube-proxy 會部署為節點的靜態 Pod。

DNS

GKE 提供下列代管叢集 DNS 選項,可解析服務名稱和外部名稱:

  • kube-dns:叢集外掛程式,預設會部署在所有 GKE 叢集中。詳情請參閱使用 kube-dns

  • Cloud DNS:雲端管理的叢集 DNS 基礎架構,可取代叢集中的 kube-dns。詳情請參閱「將 Cloud DNS 用於 GKE」的說明。

GKE 也提供 NodeLocal DNSCache 做為 kube-dns 或 Cloud DNS 的選用外掛程式,可提升叢集 DNS 效能。

如要進一步瞭解 GKE 如何提供 DNS,請參閱「服務探索和 DNS」。

控制層

在 Kubernetes 中,控制層會管理控制層程序,包括 Kubernetes API 伺服器。存取控制層的方式取決於控制層網路隔離設定

叢集外的網路

本節說明來自叢集外的流量如何到達在 Kubernetes 叢集內執行的應用程式。在設計叢集的應用程式和工作負載時,這資訊非常重要。

您已瞭解 Kubernetes 如何使用 Service,為在 Pod 內執行的應用程式提供穩定的 IP 位址。根據預設,Pod 不會公開揭露外部 IP 位址,因為 kube-proxy 會管理每個節點上的所有流量。Pod 及其容器可以自由地通訊,但叢集外的連線無法存取 Service。舉例來說,在上一個插圖中,叢集外的用戶端無法透過其 ClusterIP 存取前端服務。

GKE 提供三種不同類型的負載平衡器來控制存取權,並使連入流量盡可能地在叢集中均勻分散。您可以將一個 Service 設定為同時使用多種類型的負載平衡器。

  • 外部負載平衡器管理來自叢集外以及 Google Cloud虛擬私有雲網路外的流量。外部負載平衡器使用與Google Cloud 網路關聯的轉送規則,將流量轉送至 Kubernetes 節點。
  • 內部負載平衡器則管理來自同一個虛擬私人雲端網路內的流量。如同外部負載平衡器,內部負載平衡器使用與 Google Cloud 網路關聯的轉送規則,將流量轉送至 Kubernetes 節點。
  • 應用程式負載平衡器是 HTTP(S) 流量專用的特殊外部負載平衡器。HTTP(S) 負載平衡器不使用轉送規則,而是使用輸入資源將流量轉送至 Kubernetes 節點。

當流量抵達 Kubernetes 節點時,無論使用哪種負載平衡器,都會以同樣的方式處理流量。負載平衡器不知道叢集中的哪些節點正在執行 Pod 以提供服務。負載平衡器會將叢集中所有節點的流量進行平衡,包含未執行相關 Pod 的節點。在地區叢集上,負載會分散在叢集所在地區中,所有區域的所有節點間。流量轉送至節點時,節點會將流量轉送到在同一個或不同節點上執行的 Pod。節點使用 kube-proxy 在節點上管理的 iptables 規則,將流量轉送到隨機選擇的 Pod。

在下圖中,外部直通式網路負載平衡器將流量導向至中間節點,接著該流量會被轉送到第一個節點上的某個 Pod。

圖片

負載平衡器將流量傳送到一個節點時,流量可能會被轉送到不同節點上的 Pod。這樣會需要額外的網路躍點。如果您希望避免使用額外的躍點,可以指定流量必須前往最初收到該流量的同一個節點上的 Pod。

如要指定流量必須前往相同節點上的 Pod,請在 Service 資訊清單中將 externalTrafficPolicy 設定為 Local

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  selector:
    app: demo
    component: users
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

當您將 externalTrafficPolicy 設定為 Local 時,負載平衡器只會將流量傳送到具有屬於該 Service 且健康狀態良好的 Pod 的節點。 負載平衡器會透過健康狀態檢查決定哪一個節點擁有合適的 Pod。

外部負載平衡器

如要讓 Service 可從叢集外及虛擬私人雲端網路外進行存取,您可以在定義 Service 時,將 Service 的 type 欄位設定為 Loadbalancer,而將 Service 設定為 LoadBalancer。接著,GKE 會在 Service 的前面佈建外部直通式網路負載平衡器。外部直通網路負載平衡器知道叢集中的所有節點,並會設定虛擬私有雲網路的防火牆規則,允許使用 Service 的外部 IP 位址從虛擬私有雲網路外連線至 Service。您可以為 Service 指派一個靜態外部 IP 位址。

詳情請參閱「使用靜態 IP 位址設定網域名稱」。

如要進一步瞭解防火牆規則,請參閱「自動建立的防火牆規則」一文。

技術詳細資料

使用外部負載平衡器時,抵達的流量一開始會透過與 Google Cloud 網路關聯的轉送規則轉送至節點。 流量抵達節點後,節點會使用其 iptables NAT 資料表來選擇 Pod。kube-proxy 會管理節點上的 iptables 規則。

內部負載平衡器

針對需要從相同 VPC 網路內連至叢集的流量,您可以設定 Service 以佈建內部直通網路負載平衡器。 內部 passthrough 網路負載平衡器會從叢集的虛擬私有雲子網路選擇 IP 位址,而不是選擇外部 IP 位址。虛擬私有雲網路內的應用程式或服務可以使用這個 IP 位址,與叢集內的 Service 通訊。

技術詳細資料

內部負載平衡是由 Google Cloud提供。當流量抵達特定節點時,該節點會使用其 iptables NAT 資料表來選擇 Pod (不論 Pod 是否位於不同的節點)。 kube-proxy 會管理節點上的 iptables 規則。

如要進一步瞭解內部負載平衡器,請參閱使用內部直通式網路負載平衡器

應用程式負載平衡器

許多應用程式 (例如符合 REST 樣式的網路服務 API) 都是透過 HTTP(S) 進行通訊。 您可以透過 Kubernetes 輸入,讓虛擬私有雲網路外的用戶端存取這類應用程式。

Ingress 可讓您將主機名稱和網址路徑對應至叢集內的服務。使用應用程式負載平衡器時,您必須將 Service 設定為使用 NodePort 以及 ClusterIP。當流量在位於 NodePort 的節點 IP 存取 Service 時,GKE 會為該 Service 將流量轉送至健康狀態良好的 Pod。您可以指定 NodePort,或讓 GKE 指派隨機的未使用通訊埠。

建立 Ingress 資源時,GKE 會在 Google Cloud 專案中佈建外部應用程式負載平衡器。負載平衡器會將要求傳送至位於 NodePort 的節點 IP 位址。要求抵達節點後,節點會使用其 iptables NAT 資料表來選擇 Pod。kube-proxy 會管理節點上的 iptables 規則。

這個輸入定義會將 demo.example.com 的流量轉送至通訊埠 80 上名為 frontend 的 Service,並將 demo-backend.example.com 轉送至通訊埠 8080 上名為 users 的 Service。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  rules:
  - host: demo.example.com
    http:
      paths:
      - backend:
          service:
            name: frontend
            port:
              number: 80
  - host: demo-backend.example.com
    http:
      paths:
      - backend:
          service:
            name: users
            port:
              number: 8080

詳情請參閱「適用於應用程式負載平衡器的 GKE Ingress」。

技術詳細資料

建立 Ingress 物件時,GKE Ingress 控制器會根據 Ingress 資訊清單和相關聯的 Service 資訊清單中的規則,設定應用程式負載平衡器。用戶端會將要求傳送至應用程式負載平衡器。負載平衡器是實際的 Proxy,會選擇節點並將要求轉送至該節點的 NodeIP:NodePort 組合。節點會使用其 iptables NAT 資料表來選擇 Pod。kube-proxy 會管理節點上的 iptables 規則。

網路安全性

為提升叢集安全性,您可以限制節點之間、Pod 之間,以及與負載平衡器的連線。

限制節點之間的連線

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

限制連到 Pod 與 Service 的連線

根據預設,在相同叢集內執行的所有 Pod 皆可自由通訊。 不過,您可以依照自己的需求,以不同的方式限制叢集內的連線。

限制 Pod 之間的互相存取

您可以使用網路政策,限制 Pod 之間的互相存取。網路政策定義可讓您任意組合標籤、IP 範圍和通訊埠編號,以限制 Pod 的輸入輸出

系統預設並未啟用網路政策,因此允許叢集中 Pod 彼此之間的所有流量。您在命名空間中建立第一個網路政策之後,系統就會拒絕所有其他流量。

建立網路政策後,您必須為叢集明確啟用政策。 詳情請參閱設定應用程式的網路政策

限制對外部負載平衡器的存取

根據預設,如果 Service 使用外部負載平衡器,則來自任何外部 IP 位址的流量都可以存取 Service。您可以在設定 Service 時設定 loadBalancerSourceRanges 選項,以限制哪些 IP 位址範圍可以存取叢集內的端點。您可以指定多個範圍,也可以隨時更新正在執行的 Service 的設定。在每個節點上執行的 kube-proxy 執行個體會設定該節點的 iptables 規則,拒絕不在指定的 loadBalancerSourceRanges 中的所有流量。此外,建立 LoadBalancer 服務時,GKE 會建立對應的 VPC 防火牆規則,在網路層級強制執行這些限制。

限制對應用程式負載平衡器的存取

如果服務使用應用程式負載平衡器,您可以使用 Google Cloud Armor 安全性政策,限制哪些外部 IP 位址可以存取服務,以及因安全性政策使存取遭拒時要傳回哪些回應。您可以設定 Cloud Logging 來記錄這些互動的資訊。

如果 Google Cloud Armor 安全性政策不夠精細,您可以在端點上啟用 Identity-Aware Proxy,為應用程式導入使用者驗證與授權。詳情請參閱設定 IAP 的詳細教學課程

已知問題

本節說明已知問題。

支援容器的節點無法連線至 172.17/16 範圍

啟用 containerd 的節點 VM 無法連線至 IP 位於 172.17/16 的主機。詳情請參閱「與 172.17/16 IP 位址範圍衝突」一文。

已刪除的 GKE 叢集 (使用 Private Service Connect) 剩餘資源

如果您在 2024 年 5 月 7 日前建立及刪除 GKE 叢集,並使用 Private Service Connect,且您在刪除叢集本身前刪除了含有該叢集的專案,則可能已洩漏相關聯的 Private Service Connect 資源。這些資源會維持隱藏狀態,且您無法刪除相關聯的子網路。如果遇到這個問題,請聯絡Google Cloud 支援團隊

後續步驟