設定服務導引


本頁說明如何為 Pod 設定服務轉向。

如要瞭解服務轉向的運作方式,請參閱「服務轉向的運作方式」。

需求條件

  • GKE 1.30 以上版本。

限制

  • 一個 ServiceFunctionChain 最多只能有一個服務功能。
  • 建議最多使用 100 個節點,以及 10 個 ServiceFunctionChainTrafficSelector 配對。
  • GKE 服務轉向功能僅適用於執行 Container-Optimized OS 節點映像檔的節點。
  • GKE 服務導向僅支援輸出和目的地 IP 位址。
  • 如果多個前置字元長度相同的流量選取器套用至同一主體,服務導向功能不會處理由此產生的衝突。為避免衝突,請主動設計流量選取器,確保 IP 位址範圍不會重疊,並明確定義選取條件。

實作服務導引

GKE 服務導向功能可讓您自訂及控管叢集內的網路流量流動。本節將示範如何使用網路閘道範例實作服務轉向。

假設您想建立網路閘道,確保從使用者用戶端裝置到網際網路的流量安全無虞。VPN 終端機會使用安全通道,將流量導入代管閘道。使用者流量會重新導向至防火牆,然後再導向至 Proxy。Proxy 會對流量執行來源網路位址轉譯 (SNAT),遮蓋原始來源位址,然後傳送至網際網路。

如要導入 GKE 服務導引功能,請按照下列步驟操作:

  1. 建立 MTU 為 8896 的 VPC。
  2. 建立 GKE 叢集。
  3. 建立服務函式 Pod 和服務。
  4. 建立 ServiceFunctionChain
  5. 建立參照 ServiceFunctionChainTrafficSelector 資源。

事前準備

開始之前,請確認你已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update,取得最新版本。

準備虛擬私有雲

準備 VPC。 服務導向功能會使用封裝,將流量重新導向至適當的服務函式。封裝會在每個封包中加入額外標頭,因此會增加封包大小。服務導向不需要在 VPC 中進行特殊設定。準備虛擬私有雲時,建議您在決定 MTU 大小時,將封裝額外負荷納入考量。詳情請參閱指定 MTU 的虛擬私有雲網路

下列指令會在 VPC 中設定 MTU 大小:

gcloud compute networks create VPC_NETWORK_NAME --mtu=8896

VPC_NETWORK_NAME 替換為包含子網路的虛擬私有雲網路名稱。

建立 GKE 叢集

如要啟用進階網路路由和 IP 位址管理功能,以便在 GKE 上實作 Service Steering,請建立已啟用 GKE Dataplane V2 的 GKE 叢集,如下所示:

gcloud container clusters create CLUSTER_NAME \
    --network VPC_NAME \
    --release-channel RELEASE_CHANNEL \
    --cluster-version CLUSTER_VERSION \
    --enable-dataplane-v2 \
    --enable-ip-alias

更改下列內容:

  • CLUSTER_NAME:叢集名稱。
  • VPC_NAME:要與叢集建立關聯的 VPC 名稱。
  • RELEASE_CHANNEL:發布版本名稱。
  • VERSION:GKE 版本,必須為 1.30 以上。您也可以使用 --release-channel 旗標選取發布版本。發布管道的預設版本必須為 1.30 以上。

建立 ServiceFunction Pod

如要建立服務鏈,請在叢集中部署 VPN 終端機 Pod 和必要的服務函式 Pod。Pod 會封裝執行網路功能的容器化應用程式。

VPN 終止程式 Pod 通常是鏈結中的第一個服務函式,可終止透過 VPN 進入叢集的流量。然後將流量導向其他服務功能 (例如防火牆和負載平衡),進行進一步處理,最後抵達最終目的地。

下列設定檔範例定義了三項元件,這些元件對於叢集內的網路流量管理至關重要:

  • VPN Pod:在叢集內建立虛擬私人網路 (VPN) 端點,確保叢集與外部網路之間的通訊安全無虞。
  • 防火牆部署:部署多個防火牆 Pod 副本,提供安全性和負載平衡。
  • Proxy DaemonSet:在叢集的每個節點上部署 Proxy Pod,確保網路流量可在本機處理,再轉送至防火牆等其他服務。

將下列範例資訊清單儲存為 service_function.yaml

apiVersion: v1
kind: Pod
  name: vpn
  namespace: vpn
  labels:
    app: vpn
spec:
  containers:
  -   name: vpn
    image: openvpn
    ports:
    -   containerPort: 51820
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: firewall
  namespace: firewall
spec:
  replicas: 3
  selector:
    matchLabels:
      app: firewall
  template:
    metadata:
      labels:
        app: firewall
    spec:
      containers:
      -   name: firewall
        image: firewall
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: proxy
  namespace: proxy
spec:
  selector:
    matchLabels:
      app: proxy
  template:
    metadata:
      labels:
        app: proxy
    spec:
      containers:
      -   name: proxy
        image: proxy

套用資訊清單:

kubectl apply -f service_function.yaml

建立「ServiceFunctionChains

如要定義流量要經過的網路功能序列,請建立管道,其中每個功能 (例如防火牆、Proxy 和負載平衡器) 會執行特定工作,然後將流量傳遞至下一個功能。

將下列範例資訊清單儲存為 ServiceFunctionChain.yaml

apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: firewall
spec:
  sessionAffinity:
    clientIpNoDestination:
      timeoutSeconds: 3600 # 1hr
  serviceFunctions:
  -   name: firewall
    namespace: firewall
    podSelector:
      matchLabels:
        app: firewall
---
apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: proxy
spec:
  sessionAffinity:
    clientIpNoDestination: {}
  serviceFunctions:
  -   name: proxy
    namespace: proxy
    podSelector:
      matchLabels:
        app: proxy

套用資訊清單:

kubectl apply -f ServiceFunctionChain.yaml

服務函式是在 ServiceFunctionChain 中使用 serviceFunctions 欄位內嵌定義。服務函式是端點選取器。

建立 TrafficSelector 資源

如要定義服務轉向選取的流量來源和類型,請建立參照 ServiceFunctionChainsTrafficSelector 資源,套用至所選流量。

將下列範例資訊清單儲存為 TrafficSelector.yaml

apiVersion: networking.gke.io/v1
kind: TrafficSelector
metadata:
  name: vpn-to-firewall
spec:
  serviceFunctionChain: firewall
  subject:
    pods:
      namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: vpn
      podSelector:
        matchLabels:
          app: vpn
  egress:
    to:
      ipBlock:
        cidr: 0.0.0.0/0
    ports:
    -   allPorts:
        protocol: UDP
    -   allPorts:
        protocol: TCP
---
apiVersion: networking.gke.io/v1
kind: TrafficSelector
metadata:
  name: firewall-to-proxy
spec:
  serviceFunctionChain: proxy
  subject:
    pods:
      namespaceSelector:
        kubernetes.io/metadata.name: firewall
      podSelector:
        app: firewall
  egress:
    to:
      ipBlock:
        cidr: 0.0.0.0/0
    ports:
    -   allPorts:
        protocol: UDP
    -   allPorts:
        protocol: TCP

套用資訊清單:

kubectl apply -f TrafficSelector.yaml

排解服務導引問題

本節說明如何解決 GKE 服務轉向的相關問題。

網路流量未流動

您可以採取下列動作來偵錯問題:

步驟 1:確認 ServiceFunctionChain 已設為 servicePathId

確認 servicePathId 已設為 ServiceFunctionChain。每個 ServiceFunctionChain 物件都會指派專屬的 servicePathId,如下列範例所示:

apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: firewall
spec:
  serviceFunctions:
  - name: firewall
    namespace: firewall
    podSelector:
      matchLabels:
        app: firewal
status:
  servicePathId: 1

步驟 2:確認每個服務功能都已建立 Kubernetes 服務

系統會自動為每個服務函式建立 ClusterIP 服務。您可以使用 kubectl 查看服務清單:

kubectl get svc -A -l networking.gke.io/managed-by=service-steering-controller.gke.io

步驟 3:確認每個節點上都已為每個服務函式建立 bpf 對應項目,以儲存服務 IP 位址

每個節點都會為每個服務函式建立 bpf 對應項目,以儲存服務 IP 位址。

取得 anetd Pod 的名稱:

kubectl get pods -n kube-system -o wide -l k8s-app=cilium

記下 Pod 的名稱,類似於 anetd

執行下列指令:

kubectl -n kube-system exec -it ANETD-POD-NAME -- cilium bpf sfcpath list

ANETD-POD-NAME 替換為 anetd Pod 的名稱。

輸出結果會與下列內容相似:

PATH     SERVICE FUNCTION ADDRESS
(1, 1)   10.4.10.124

步驟 4:確認 sfcselect 地圖中已建立 bpf 地圖項目

在節點上,如果選取了 Pod,系統會在 sfcselect 地圖中建立 bpf 地圖項目。TrafficSelector以下範例顯示,端點 (Pod) 3783 任何通訊埠的 TCP/UDP 流量,都會導向目的地 IP 位址 10.0.2.12 的 ServiceFunctionChain

執行下列指令:

kubectl -n kube-system exec -it ANETD-POD-NAME -- cilium bpf sfcselect list

ANETD-POD-NAME 替換為叢集中 anetd Pod 的實際名稱。

輸出結果會與下列內容相似:

SELECTOR                            PATH
3783, egress, 0/TCP, 10.0.2.12/32   /32 (1, 1)
3783, egress, 0/UDP, 10.0.2.12/32   /32 (1, 1)

步驟 5:在通訊埠 7081 上使用 tcpdump 擷取及分析網路流量

服務轉向會在 UDP 通訊埠 7081 進行 Geneve 封裝。您可以在相關節點上使用 tcpdump 分析流量,並找出可能發生問題的位置。

後續步驟