本頁說明如何為 Pod 設定服務轉向。
如要瞭解服務轉向的運作方式,請參閱「服務轉向的運作方式」。
需求條件
- GKE 1.30 以上版本。
限制
- 一個
ServiceFunctionChain
最多只能有一個服務功能。 - 建議最多使用 100 個節點,以及 10 個
ServiceFunctionChain
和TrafficSelector
配對。 - GKE 服務轉向功能僅適用於執行 Container-Optimized OS 節點映像檔的節點。
- GKE 服務導向僅支援輸出和目的地 IP 位址。
- 如果多個前置字元長度相同的流量選取器套用至同一主體,服務導向功能不會處理由此產生的衝突。為避免衝突,請主動設計流量選取器,確保 IP 位址範圍不會重疊,並明確定義選取條件。
實作服務導引
GKE 服務導向功能可讓您自訂及控管叢集內的網路流量流動。本節將示範如何使用網路閘道範例實作服務轉向。
假設您想建立網路閘道,確保從使用者用戶端裝置到網際網路的流量安全無虞。VPN 終端機會使用安全通道,將流量導入代管閘道。使用者流量會重新導向至防火牆,然後再導向至 Proxy。Proxy 會對流量執行來源網路位址轉譯 (SNAT),遮蓋原始來源位址,然後傳送至網際網路。
如要導入 GKE 服務導引功能,請按照下列步驟操作:
- 建立 MTU 為 8896 的 VPC。
- 建立 GKE 叢集。
- 建立服務函式 Pod 和服務。
- 建立
ServiceFunctionChain
。 - 建立參照
ServiceFunctionChain
的TrafficSelector
資源。
事前準備
開始之前,請確認你已完成下列工作:
- 啟用 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
資源
如要定義服務轉向選取的流量來源和類型,請建立參照 ServiceFunctionChains
的 TrafficSelector
資源,套用至所選流量。
將下列範例資訊清單儲存為 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 分析流量,並找出可能發生問題的位置。
後續步驟
- 請參閱「關於 Pod 的多網路支援功能」一文
- 請參閱「關於服務轉向」。
- 請參閱「為 Pod 設定多網路支援功能」一文。