本頁說明如何使用 GKE 的「強制執行網路政策」,控管叢集 Pod 和 Service 之間的通訊。
您也可以使用完整網域名稱 (FQDN) 網路政策,控管 Pod 輸出至叢集外部任何端點或服務的流量。詳情請參閱「使用 FQDN 控制 Pod 和服務之間的通訊」。
關於 GKE 網路政策強制執行
強制執行網路政策可讓您在叢集中建立 Kubernetes NetworkPolicy。根據預設,叢集中的所有 Pod 皆可自由通訊。網路政策會建立 Pod 層級的防火牆規則,決定叢集內的哪些 Pod 和服務可以互相存取。
定義網路政策可以協助您啟用多種功能,例如當叢集提供多層級應用程式時的深入防禦機制。例如,您可以建立網路政策,確保應用程式中遭駭的前端服務不會直接與往下數層的計費或會計服務直接通訊。
網路政策也讓應用程式能更簡單地同時託管來自多個使用者的資料。例如,您可以為每個命名空間定義一個租戶模型,提供安全的多租戶架構。在這樣的模型中,網路政策規則可確保特定命名空間中的 Pod 和服務無法存取不同命名空間中其他的 Pod 和服務。
事前準備
開始之前,請確認你已完成下列工作:
- 啟用 Google Kubernetes Engine API。 啟用 Google Kubernetes Engine API
- 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update
,取得最新版本。
需求條件和限制
Autopilot 和 Standard 叢集都適用下列規定和限制:
- 您必須允許連出至中繼資料伺服器。
- 如果您在已啟用 GKE Dataplane V2 的叢集上,於網路政策中指定
endPort
欄位,從 GKE 1.22 版開始,該欄位可能不會生效。詳情請參閱「網路政策的連接埠範圍未生效」。如果是 Autopilot 叢集,GKE Dataplane V2 一律會啟用。
下列規定和限制僅適用於標準叢集:
- 如果您使用網路政策搭配 Workload Identity Federation for GKE,就必須允許輸出至中繼資料伺服器。
- 啟用強制執行網路政策會增加
kube-system
程序的記憶體佔用空間大約 128 MB,並需要大約 300 millicore 的 CPU。也就是說,如果您為現有叢集啟用網路政策,可能需要增加叢集的大小,才能繼續執行排程的工作負載。 - 啟用強制執行網路政策需要重新建立節點。如果叢集有作用中的維護期間,系統會在下次的維護期間自動重新建立節點。或者您也可以隨時手動升級叢集。
- 如要強制執行網路政策,必要的最小叢集大小為三個
e2-medium
執行個體,或一個具有超過 1 個可分配 vCPU 的機器類型執行個體。詳情請參閱 GKE 已知問題。 - 針對節點為
f1-micro
或g1-small
執行個體的叢集,我們不支援網路政策,因為資源需求太高。 - Cilium 或 Calico 不會管理設定
hostNetwork: true
的 Pod,且網路政策無法控管這些 Pod。
如要進一步瞭解節點機器類型和可分配的資源,請參閱「標準叢集架構 - 節點」。
啟用網路政策強制執行功能
Autopilot 叢集預設會啟用網路政策強制執行功能,因此您可以直接跳到「建立網路政策」一節。
如要在 Standard 中啟用網路政策強制執行服務,可以使用 gcloud CLI、 Google Cloud 控制台或 GKE API。
網路政策強制執行功能已內建於 GKE Dataplane V2。如果叢集使用 GKE Dataplane V2,則不需要啟用網路政策強制執行服務。
這項變更需要重新建立節點,可能會導致執行中的工作負載中斷。如要瞭解這項特定變更的詳細資料,請在「manual changes that recreate the nodes using a node upgrade strategy and respecting maintenance policies」(手動變更,使用節點升級策略重建節點,並遵守維護政策) 表格中找到對應的資料列。如要進一步瞭解節點更新,請參閱「規劃節點更新中斷」。
gcloud
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
如要在「建立新叢集」時啟用網路政策強制執行功能,請執行下列指令:
gcloud container clusters create CLUSTER_NAME --enable-network-policy
將
CLUSTER_NAME
替換為新叢集的名稱。如要為「現有叢集」啟用網路政策強制執行服務,請執行下列工作:
執行下列指令來啟用外掛程式:
gcloud container clusters update CLUSTER_NAME --update-addons=NetworkPolicy=ENABLED
將
CLUSTER_NAME
替換為叢集名稱。執行下列指令,在叢集上啟用網路政策強制執行功能,這會重新建立啟用網路政策強制執行功能的叢集節點集區:
gcloud container clusters update CLUSTER_NAME --enable-network-policy
控制台
如何在「建立新叢集」時啟用網路政策強制執行服務:
前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。
按一下「add_box Create」(建立)。
在「Create cluster」(建立叢集) 對話方塊中,按一下 GKE Standard 對應的「Configure」(設定)。
視需要設定叢集。
在導覽窗格的「叢集」底下,按一下 [網路]。
選取「Enable network policy」(啟用網路政策) 核取方塊。
點選「建立」。
如要為「現有叢集」啟用網路政策強制執行服務:
前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。
在叢集清單中,按一下您要修改的叢集名稱。
在「Networking」(網路) 下方的「Network policy」(網路政策) 欄位中,按一下「Edit network policy」(編輯網路政策)edit。
勾選「Enable network policy for master」(啟用主要執行個體的網路政策) 核取方塊,然後按一下「Save Changes」(儲存變更)。
等待變更生效,然後再按一下「Edit network policy」(編輯網路政策)edit。
勾選「Enable network policy for nodes」(啟用節點的網路政策) 核取方塊。
按一下 [儲存變更]。
API
如要啟用強制執行網路政策,請執行下列步驟:
在您提供給 projects.zones.clusters.create 或 projects.zones.clusters.update 的
cluster
物件內,指定networkPolicy
物件。networkPolicy
物件需要一個 enum 來指定要使用的網路政策提供者,以及一個布林值來指定是否要啟用網路政策。若啟用網路政策,但並未設定提供者,create
和update
指令會傳回錯誤。
在標準叢集中停用網路政策強制執行服務
您可以使用 gcloud CLI、 Google Cloud 控制台或 GKE API 停用網路政策強制執行服務。您無法在 Autopilot 叢集或使用 GKE Dataplane V2 的叢集中,停用網路政策強制執行服務。
這項變更需要重新建立節點,可能會導致執行中的工作負載中斷。如要瞭解這項特定變更的詳細資料,請在「manual changes that recreate the nodes using a node upgrade strategy and respecting maintenance policies」(手動變更,使用節點升級策略重建節點,並遵守維護政策) 表格中找到對應的資料列。如要進一步瞭解節點更新,請參閱「規劃節點更新中斷」。
gcloud
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
如要停用網路政策強制執行服務,請執行下列工作:
- 停用叢集的網路政策強制執行功能:
gcloud container clusters update CLUSTER_NAME --no-enable-network-policy
將
CLUSTER_NAME
替換為叢集名稱。執行這項指令後,GKE 會重新建立叢集節點集區,並停用強制執行網路政策。
確認所有節點都已重新建立:
kubectl get nodes -l projectcalico.org/ds-ready=true
如果作業成功,輸出結果會與下列內容相似:
No resources found
如果輸出內容類似下列內容,您就必須等待 GKE 完成節點集區更新:
NAME STATUS ROLES AGE VERSION gke-calico-cluster2-default-pool-bd997d68-pgqn Ready,SchedulingDisabled <none> 15m v1.22.10-gke.600 gke-calico-cluster2-np2-c4331149-2mmz Ready <none> 6m58s v1.22.10-gke.600
如果叢集已設定維護時段或排除項目,停用強制執行網路政策後,GKE 可能不會立即更新節點。詳情請參閱「叢集更新速度緩慢」。
重新建立所有節點後,請停用外掛程式:
gcloud container clusters update CLUSTER_NAME --update-addons=NetworkPolicy=DISABLED
控制台
如要停用現有叢集的網路政策強制執行服務,請執行下列步驟:
前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。
在叢集清單中,按一下您要修改的叢集名稱。
在「Networking」(網路) 下方的「Network policy」(網路政策) 欄位中,按一下「Edit network policy」(編輯網路政策)edit。
取消勾選「Enables node policy for node」(啟用節點的網路政策) 核取方塊,然後按一下「Save Changes」(儲存變更)。
等待變更生效,然後再按一下「Edit network policy」(編輯網路政策)edit。
取消勾選「Enable network policy for master」(啟用主要執行個體的網路政策) 核取方塊。
按一下 [儲存變更]。
API
如要停用現有叢集的網路政策強制執行服務,請執行下列步驟:
更新叢集以使用
networkPolicy.enabled: false
,方法是使用setNetworkPolicy
API。使用 gcloud CLI 重新建立所有節點:
kubectl get nodes -l projectcalico.org/ds-ready=true
如果作業成功,輸出結果會與下列內容相似:
No resources found
如果輸出內容類似下列內容,您就必須等待 GKE 完成節點集區更新:
NAME STATUS ROLES AGE VERSION gke-calico-cluster2-default-pool-bd997d68-pgqn Ready,SchedulingDisabled <none> 15m v1.22.10-gke.600 gke-calico-cluster2-np2-c4331149-2mmz Ready <none> 6m58s v1.22.10-gke.600
如果叢集已設定維護時段或排除項目,停用強制執行網路政策後,GKE 可能不會立即更新節點。詳情請參閱「叢集更新速度緩慢」。
更新叢集以使用
update.desiredAddonsConfig.NetworkPolicyConfig.disabled: true
使用updateCluster
API。
建立網路政策
您可以使用 Kubernetes Network Policy API 建立網路政策。
如需深入瞭解如何建立網路政策,請參閱 Kubernetes 說明文件中的下列主題:
網路政策和 Workload Identity Federation for GKE
如果您搭配使用網路政策和 Workload Identity Federation for GKE,則必須允許輸出至下列 IP 位址,Pod 才能與 GKE 中繼資料伺服器通訊。
- 如果叢集執行的是 GKE 1.21.0-gke.1000 以上版本,請允許對
169.254.169.252/32
進行輸出,連接埠為988
。 - 如果叢集執行的 GKE 版本早於 1.21.0-gke.1000,請允許在連接埠
988
上輸出至127.0.0.1/32
。 - 如果是執行 GKE Dataplane V2 的叢集,請允許通訊埠
80
的輸出流量前往169.254.169.254/32
。
如果不允許連出至這些 IP 位址和通訊埠,自動升級期間可能會發生中斷情形。
從 Calico 遷移至 GKE Dataplane V2
如果您要將網路政策從 Calico 遷移至 GKE Dataplane V2,請注意下列限制:
您無法在
NetworkPolicy
資訊清單的ipBlock.cidr
欄位中使用 Pod 或 Service IP 位址。您必須使用標籤參照工作負載。舉例來說,下列設定無效:- ipBlock: cidr: 10.8.0.6/32
您無法在
NetworkPolicy
資訊清單中指定空白的ports.port
欄位。 如果您指定通訊協定,也必須指定通訊埠。舉例來說,下列設定無效:ingress: - ports: - protocol: TCP
使用應用程式負載平衡器
當 Ingress 套用於服務以建構應用程式負載平衡器時,您必須設定套用於該服務後方 Pod 的網路政策,允許適當的應用程式負載平衡器健康狀態檢查 IP 範圍。如果您使用內部應用程式負載平衡器,也必須設定網路政策,允許僅限 Proxy 的子網路。
如果您未使用容器原生負載平衡搭配網路端點群組,除非透過在服務定義中將 externalTrafficPolicy
設定為 Local
,否則服務的節點通訊埠可以轉接到其他節點上的 Pod 連線。如果 externalTrafficPolicy
未設定為 Local
,則網路策略也必須允許來自叢集中其他節點 IP 的連線。
在 ipBlock 規則中加入 Pod IP 範圍
如要控管特定 Pod 的流量,請務必使用 NetworkPolicy 輸入或輸出規則中的 namespaceSelector
和 podSelector
欄位,依據命名空間或 Pod 標籤選取 Pod。請勿使用 ipBlock.cidr
欄位刻意選取 Pod IP 位址範圍,因為這類位址本質上是臨時的。Kubernetes 專案未明確定義包含 Pod IP 位址範圍時,ipBlock.cidr
欄位的行為。在這個欄位中指定廣泛的 CIDR 範圍 (例如 0.0.0.0/0
,其中包含 Pod IP 位址範圍),可能會導致 NetworkPolicy 的不同實作方式產生非預期的結果。
以下各節說明 GKE 中 NetworkPolicy 的不同實作方式,如何評估您在 ipBlock.cidr 欄位中指定的 IP 位址範圍,以及這可能對廣泛 CIDR 範圍內含的 Pod IP 位址範圍造成哪些影響。瞭解不同導入方式之間的差異,有助於您在遷移至其他導入方式時,做好因應結果的準備。
GKE Dataplane V2 中的 ipBlock 行為
透過 GKE Dataplane V2 實作的 NetworkPolicy,Pod 流量絕不會受到 ipBlock
規則涵蓋。因此,即使您定義了廣泛的規則 (例如 cidr: '0.0.0.0/0'
),也不會納入 Pod 流量。這項功能相當實用,舉例來說,您可以允許命名空間中的 Pod 接收來自網際網路的流量,但禁止 Pod 傳送流量。如要一併納入 Pod 流量,請在 NetworkPolicy 的輸入或輸出規則定義中,使用額外的 Pod 或命名空間選取器,明確選取 Pod。
Calico 中的 ipBlock 行為
對於 NetworkPolicy 的 Calico 實作,ipBlock
規則會涵蓋 Pod 流量。採用這種做法時,如要設定廣泛的 CIDR 範圍,但不允許 Pod 流量,請明確排除叢集的 Pod CIDR 範圍,如下例所示:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-non-pod-traffic
spec:
ingress:
- from:
- ipBlock:
cidr: '0.0.0.0/0'
except: ['POD_IP_RANGE']
在本範例中,POD_IP_RANGE
是叢集的 Pod IPv4 位址範圍,例如 10.95.0.0/17
。如果您有多個 IP 範圍,可以個別納入陣列,例如 ['10.95.0.0/17', '10.108.128.0/17']
。
使用 externalTrafficPolicy
控制網路政策行為
服務的 externalTrafficPolicy
設定會影響 Kubernetes 套用網路政策的方式。這項設定會決定 Pod 接收傳入流量時看到的來源 IP 位址,並可能影響 Kubernetes 評估 NetworkPolicy 規則的方式。
externalTrafficPolicy
有兩個可能的值:
Cluster
:如果externalTrafficPolicy
設為Cluster
,目的地 Pod 會將來源 IP 位址視為最初接收流量的節點 IP 位址。如果您有 NetworkPolicy 會根據用戶端 IP 位址拒絕流量,但未納入遠端節點 IP 位址,可能會無意間封鎖來自政策規則中指定外部用戶端的外部流量。為避免發生這種情況,請建立政策,允許叢集中所有節點的流量。不過,這項政策會允許來自任何外部用戶端的流量。Local
:如果將externalTrafficPolicy
設為Local
,Pod 會將來源 IP 位址視為原始用戶端 IP 位址。這樣一來,您就能根據實際的用戶端 IP 位址定義規則,更精細地控管網路政策。
疑難排解
使用 Private Service Connect 的叢集,Pod 無法與控制層通訊
如果 Pod 的輸出流量受到輸出網路政策限制,無法連至控制層的內部 IP 位址,使用 Private Service Connect 的 GKE 叢集上的 Pod 可能會發生控制層通訊問題。
如要解決這個問題,請採取下列行動:
確認叢集使用 Private Service Connect。 在採用 Private Service Connect 的叢集上,如果您在建立子網路時使用
master-ipv4-cidr
標記,GKE 會從您在master-ipv4-cidr
中定義的值,為每個控制層指派內部 IP 位址。否則,GKE 會使用叢集節點子網路,為每個控制層指派內部 IP 位址。設定叢集的輸出政策,允許流量傳送至控制層的內部 IP 位址。
如要找出控制層的內部 IP 位址,請執行下列操作:
gcloud
如要尋找
privateEndpoint
,請執行下列指令:gcloud container clusters describe CLUSTER_NAME
將
CLUSTER_NAME
替換為叢集名稱。這項指令會擷取指定叢集的
privateEndpoint
。控制台
前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。
在導覽窗格的「Clusters」(叢集) 下方,按一下要尋找內部 IP 位址的叢集。
在「Cluster basics」(叢集基本資訊) 下方,前往
Internal endpoint
,其中列出了內部 IP 位址。
找到
privateEndpoint
或Internal endpoint
後,請設定叢集的輸出政策,允許流量傳送到控制層的內部 IP 位址。詳情請參閱「建立網路政策」。
叢集更新速度緩慢
在現有叢集上啟用或停用強制執行網路政策時,如果叢集已設定維護期間或排除時段,GKE 可能不會立即更新節點。
您可以將 --cluster-version
標記設定為控制層執行的 GKE 版本,手動升級節點集區。您必須使用 Google Cloud CLI 執行這項作業。詳情請參閱維護期間注意事項。
手動部署的 Pod 未排定時間
在現有叢集的控制層啟用強制執行網路政策時,GKE 會取消排程您手動部署的所有 ip-masquerade-agent 或 Calico 節點 Pod。
在叢集節點上啟用網路政策強制執行功能,並重新建立節點之前,GKE 不會重新排程這些 Pod。
如果您已設定維護期間或排除時段,這可能會導致服務中斷時間延長。
如要盡量縮短這類中斷時間,您可以手動將下列標籤指派給叢集節點:
node.kubernetes.io/masq-agent-ds-ready=true
projectcalico.org/ds-ready=true
網路政策未生效
如果 NetworkPolicy 未生效,請按照下列步驟進行疑難排解:
確認已啟用強制執行網路政策。使用的指令取決於叢集是否已啟用 GKE Dataplane V2。
如果叢集已啟用 GKE Dataplane V2,請執行下列指令:
kubectl -n kube-system get pods -l k8s-app=cilium
如果輸出內容為空白,表示網路政策強制執行服務未啟用。
如果叢集未啟用 GKE Dataplane V2,請執行下列指令:
kubectl get nodes -l projectcalico.org/ds-ready=true
如果輸出內容為空白,表示網路政策強制執行服務未啟用。
檢查 Pod 標籤:
kubectl describe pod POD_NAME
將
POD_NAME
替換為 Pod 的名稱。輸出結果會與下列內容相似:
Labels: app=store pod-template-hash=64d9d4f554 version=v1
確認政策上的標籤與 Pod 上的標籤相符:
kubectl describe networkpolicy
輸出結果會與下列內容相似:
PodSelector: app=store
在這個輸出內容中,
app=store
標籤與上一步驟中的app=store
標籤相符。檢查是否有任何網路政策選取您的工作負載:
kubectl get networkpolicy
如果輸出內容為空白,表示命名空間中未建立任何 NetworkPolicy,且沒有任何項目選取您的工作負載。如果輸出內容不為空白,請檢查政策是否選取您的工作負載:
kubectl describe networkpolicy
輸出結果會與下列內容相似:
... PodSelector: app=nginx Allowing ingress traffic: To Port: <any> (traffic allowed to all ports) From: PodSelector: app=store Not affecting egress traffic Policy Types: Ingress
已知問題
使用 Calico 終止 StatefulSet Pod
如果 GKE 叢集啟用 Calico 網路政策,當 StatefulSet Pod 遭到刪除時,可能會發生現有連線遭捨棄的問題。Pod 進入 Terminating
狀態後,系統不會採用 Pod 規格中的 terminationGracePeriodSeconds
設定,且會導致其他與 StatefulSet Pod 建立現有連線的應用程式中斷。如要進一步瞭解這個問題,請參閱 Calico 問題 #4710。
這個問題會影響下列 GKE 版本:
- 1.18
- 1.19 至 1.19.16-gke.99
- 1.20 至 1.20.11-gke.1299
- 1.21 至 1.21.4-gke.1499
如要解決這個問題,請將 GKE 控制層升級至下列其中一個版本:
- 1.19.16-gke.100 以上版本
- 1.20.11-gke.1300 以上版本
- 1.21.4-gke.1500 以上版本
Pod 處於 containerCreating
狀態
如果 GKE 叢集啟用 Calico 網路政策,可能會發生 Pod 卡在 containerCreating
狀態的問題。
在 Pod「事件」分頁中,您會看到類似下列內容的訊息:
plugin type="calico" failed (add): ipAddrs is not compatible with
configured IPAM: host-local
如要解決這個問題,請在 GKE 叢集中使用主機本機 IPAM (適用於 Calico),而非 calico-ipam。