在專屬節點集區中隔離工作負載
本頁說明如何設定 GKE on Azure,將工作負載排程在與具備權限的管理工作負載不同的專屬節點集區中,降低叢集發生權限提升攻擊的風險。
總覽
GKE on Azure 叢集會使用我們管理的具備特殊權限工作負載,啟用特定叢集功能,例如收集指標。這些工作負載會獲得特殊權限,可在叢集中正確執行。
部署至節點的工作負載可能會遭到惡意實體入侵。如果這些工作負載與具備特殊權限的系統工作負載一起執行,表示攻擊者從遭入侵的容器脫逃後,就能使用節點上具備特殊權限工作負載的憑證,在叢集中提升權限。
防止容器突破
應用程式應是主要防禦措施。您可以使用 Azure 上的 GKE 多項功能,強化叢集和 Pod。在大多數情況下,我們強烈建議使用 Policy Controller 和核心安全功能,強化工作負載。如需更多安全性建議,請參閱「安全性總覽」。
避免權限提升攻擊
除了其他強化措施外,如要額外增加一層隔離措施,可以使用節點 taint 和節點親和性,在專屬節點集區中排定工作負載。
節點汙染會告知 GKE on Azure,避免在這些節點上排定沒有相應容許度的作業 (例如 GKE on Azure 管理的工作負載)。自有工作負載的節點親和性會告知 GKE on Azure,將 Pod 排定至專屬節點。
節點隔離的限制
- 攻擊者仍可從遭入侵的節點發動阻斷服務 (DoS) 攻擊。
- 遭入侵的節點仍可讀取許多資源,包括叢集中的所有 Pod 和命名空間。
- 遭入侵的節點可以存取在該節點上執行的每個 Pod 所使用的 Secret 和憑證。
- 使用獨立節點集區隔離工作負載可能會影響成本效益、自動調度資源和資源用量。
- 遭入侵的節點仍可略過輸出網路政策。
- 部分 GKE on Azure 代管工作負載必須在叢集中的每個節點上執行,且設定為可容許所有汙點。
- 如果您部署的 DaemonSet 具有提升的權限,且可容許任何汙點,這些 Pod 可能會成為權限提升的路徑,讓遭入侵的節點得逞。
節點隔離的運作方式
如要為工作負載實作節點隔離,請完成下列步驟:
- 為工作負載汙染節點集區並加上標籤。
- 使用對應的容許度和節點親和性規則更新工作負載。
本指南假設您從叢集中的一個節點集區開始。除了節點汙染之外,使用節點親和性並非必要,但我們建議您這麼做,因為這樣可以更有效控管排程。
事前準備
如要執行本頁的步驟,請先完成下列事項:
為工作負載汙染節點集區並加上標籤
為工作負載建立新的節點集區,並套用節點汙點和節點標籤。在節點集區層級套用汙點或標籤時,任何新節點 (例如自動調度資源建立的節點) 都會自動取得指定的汙點和標籤。
您也可以將節點汙點和節點標籤新增至現有節點集區。如果您使用 NoExecute
效果,GKE on Azure 會清空節點上所有未容許新汙染的 Pod。
如要將汙點和標籤新增至新的節點集區,請執行下列指令:
gcloud container azure node-pools create POOL_NAME \
--cluster CLUSTER_NAME \
--node-taints TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
--node-labels LABEL_KEY=LABEL_VALUE
更改下列內容:
POOL_NAME
:工作負載的新節點集區名稱。CLUSTER_NAME
:Azure 中 GKE 叢集的名稱。TAINT_KEY=TAINT_VALUE
:與排程TAINT_EFFECT
相關聯的鍵/值組合。例如:workloadType=untrusted
。TAINT_EFFECT
:下列其中一個效果值:NoSchedule
、PreferNoSchedule
或NoExecute
。NoExecute
比NoSchedule
提供更完善的驅逐保證。LABEL_KEY
=LABEL_VALUE
:節點標籤的鍵/值組合,對應至您在工作負載資訊清單中指定的選取器。
為工作負載新增容許度和節點親和性規則
為專屬節點集區設定污點後,除非工作負載具有與您新增污點相應的容許條件,否則無法排程至該節點集區。在工作負載的規格中新增容許條件,讓這些 Pod 在受汙染的節點集區中排程。
如果您已為專屬節點集區加上標籤,也可以新增節點親和性規則,告知 GKE on Azure 只將工作負載排定至該節點集區。
以下範例會為 workloadType=untrusted:NoExecute
taint 新增容許度,並為 workloadType=untrusted
節點標籤新增節點親和性規則。
kind: Deployment
apiVersion: apps/v1
metadata:
name: my-app
namespace: default
labels:
app: my-app
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
tolerations:
- key: TAINT_KEY
operator: Equal
value: TAINT_VALUE
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: LABEL_KEY
operator: In
values:
- "LABEL_VALUE"
containers:
- name: sleep
image: ubuntu
command: ["/bin/sleep", "inf"]
更改下列內容:
TAINT_KEY
:您套用至專屬節點集區的汙點鍵。TAINT_VALUE
:您套用至專屬節點集區的汙點值。LABEL_KEY
:您套用至專屬節點集區的節點標籤鍵。LABEL_VALUE
:您套用至專屬節點集區的節點標籤值。
使用 kubectl apply
更新 Deployment 時,GKE on Azure 會重新建立受影響的 Pod。節點親和性規則會強制 Pod 進入您建立的專屬節點集區。容許條件只允許將這些 Pod 放置在節點上。
確認分離功能是否正常運作
如要確認排程是否正常運作,請執行下列指令,並檢查工作負載是否位於專屬節點集區:
kubectl get pods -o=wide
建議做法與最佳做法
設定節點隔離後,建議您採取下列做法:
- 新增
components.gke.io/gke-managed-components
汙點,將特定節點集區限制為僅適用於 GKE on Azure 管理的工作負載。新增這項汙點可防止您自己的 Pod 排定在這些節點上,進而提升隔離效果。 - 建立新節點集區時,請在這些節點集區中新增自己的汙點,防止大部分 GKE on Azure 管理的工作負載在這些節點上執行。
- 每當您將新工作負載部署到叢集時 (例如安裝第三方工具),請稽核 Pod 要求的權限。盡可能避免將使用提升權限的工作負載部署至共用節點。