本頁說明如何使用 Gatekeeper 准入控制器,將 Pod 層級的安全控管措施套用至 Google Kubernetes Engine (GKE) 叢集。本頁說明如何使用 Gatekeeper 套用限制,以便套用安全政策,協助機構滿足安全需求。
本頁適用於想對 GKE 叢集套用安全控管措施的安全性專家。如要進一步瞭解我們在內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。 Google Cloud
閱讀本頁面之前,請務必先熟悉下列概念:
Gatekeeper 總覽
Gatekeeper 是一種許可控制器,可使用 Open Policy Agent (OPA),驗證在 Kubernetes 叢集中建立及更新 Pod 的要求。
管理員可使用 Gatekeeper 透過限制定義政策,這是一組條件,可允許或拒絕 Kubernetes 中的部署行為。接著,您可以使用 ConstraintTemplate
在叢集上強制執行這些政策。本文提供相關範例,說明如何限制工作負載的安全功能,確保使用 Gatekeeper 強制執行、測試及稽核安全政策。
Gatekeeper 還能執行下列操作:
- 推出政策:逐步強制執行政策,並限制範圍,以降低工作負載中斷的風險。
- 試行政策變更:提供機制,在強制執行前測試政策影響和範圍。
- 稽核現有政策:確保安全性控管機制適用於新舊工作負載 (稽核控管機制)。
Gatekeeper 重要概念
為提供強大且彈性的叢集控管方式,Gatekeeper 導入了兩個概念:限制和限制範本,這兩個概念都承襲自 Open Policy Agent Constraint Framework。
限制代表您的安全政策,可定義強制執行的需求和範圍。限制範本是可重複使用的陳述式 (以 Rego 編寫),可根據限制中定義的需求,套用邏輯來評估 Kubernetes 物件中的特定欄位。
舉例來說,您可能會有一項限制,用於宣告可套用至特定命名空間中 Pod 的允許 seccomp 設定檔,以及提供邏輯的類似限制範本,用於擷取這些值及處理強制執行作業。
下列限制範本來自 Gatekeeper 存放區,會檢查 Pod 規格中是否有 securityContext.privileged
:
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8spspprivilegedcontainer
spec:
crd:
spec:
names:
kind: K8sPSPPrivilegedContainer
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8spspprivileged
violation[{"msg": msg, "details": {}}] {
c := input_containers[_]
c.securityContext.privileged
msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext])
}
input_containers[c] {
c := input.review.object.spec.containers[_]
}
input_containers[c] {
c := input.review.object.spec.initContainers[_]
}
如要擴充先前的限制範本範例,下列限制會定義範圍 (kinds
),以便在 dryrun
模式中強制執行這個限制範本:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
name: psp-privileged-container
spec:
enforcementAction: dryrun
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
您可以透過 Gatekeeper 建立自己的限制和限制範本,滿足特定需求。您也可以使用 Gatekeeper 存放區中定義的標準限制和限制範本組合,快速採用並強制執行安全性。每項限制也附有 Pod 設定範例。
Google Cloud 提供開放原始碼 Gatekeeper 的代管版本,並提供官方支援,這個版本稱為 Policy Controller。Google 並未正式支援開放原始碼 Gatekeeper 專案。
事前準備
開始之前,請確認您已完成下列工作:
- 啟用 Google Kubernetes Engine API。 啟用 Google Kubernetes Engine API
- 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update
,取得最新版本。
在啟用 Policy Controller 的叢集上啟用 Gatekeeper
Policy Controller 是以 Gatekeeper 開放原始碼專案為基礎建構的政策引擎。Google 建議使用 Policy Controller,因為這項工具提供額外功能,有助於大規模強制執行政策,包括政策即程式碼、多叢集支援、與 Cloud Logging 整合,以及在 Google Cloud 控制台中查看政策狀態。Policy Controller 適用於 GKE,但您也可以在叢集上安裝 Gatekeeper。
如要在叢集上啟用 Policy Controller,請按照 Policy Controller 安裝指南操作。
啟用限制和限制範本
安裝及啟用 Gatekeeper 和其限制範本時,不會對現有或新的工作負載造成負面影響。因此,建議您將所有適用的 Pod 安全性限制範本套用至叢集。
此外,您也可以實作 Gatekeeper 限制,針對特定物件 (例如命名空間和 Pod) 強制執行控管措施。
請參閱以下範例,在限制比對陳述式中定義範圍,將範圍限制為位於「production」命名空間中的「Pods」:
...
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "production"
如要進一步瞭解 Constraint
和 ConstraintTemplate
物件的可用選項,請參閱「如何使用 Gatekeeper」。
測試政策
在現有叢集中導入新政策可能會導致不良行為,例如限制現有工作負載。使用 Gatekeeper 確保 Pod 安全的一項優點是,您可以使用模擬測試模式,測試政策的效力和影響,而不必實際變更。這樣一來,您就能針對執行中的叢集測試政策設定,而不必強制執行。系統會記錄並找出違反政策的行為,不會受到干擾。
下列步驟說明開發人員、營運人員或管理員如何套用限制範本和限制,判斷其效力或潛在影響:
套用 Gatekeeper 設定,複製稽核和試營運功能資料:
kubectl create -f- <<EOF apiVersion: config.gatekeeper.sh/v1alpha1 kind: Config metadata: name: config namespace: "gatekeeper-system" spec: sync: syncOnly: - group: "" version: "v1" kind: "Namespace" - group: "" version: "v1" kind: "Pod" EOF
不套用任何限制,以進階權限執行工作負載:
kubectl create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx securityContext: privileged: true EOF
載入先前的
k8spspprivilegedcontainer
限制範本:kubectl create -f- <<EOF apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8spspprivilegedcontainer spec: crd: spec: names: kind: K8sPSPPrivilegedContainer targets: - target: admission.k8s.gatekeeper.sh rego: | package k8spspprivileged violation[{"msg": msg, "details": {}}] { c := input_containers[_] c.securityContext.privileged msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext]) } input_containers[c] { c := input.review.object.spec.containers[_] } input_containers[c] { c := input.review.object.spec.initContainers[_] } EOF
建立新的限制條件,即可擴充這個限制範本。這次請將
enforcementAction
設為dryrun
:kubectl create -f- <<EOF apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPSPPrivilegedContainer metadata: name: psp-privileged-container spec: enforcementAction: dryrun match: kinds: - apiGroups: [""] kinds: ["Pod"] EOF
Gatekeeper 會同步處理執行中的物件資料,並被動檢查違規情形,請檢查限制的
status
,確認是否發現任何違規事項:kubectl get k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container -o yaml
apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPSPPrivilegedContainer metadata: ... name: psp-privileged-container ... spec: enforcementAction: dryrun match: kinds: - apiGroups: - "" kinds: - Pod status: auditTimestamp: "2019-12-15T22:19:54Z" byPod: - enforced: true id: gatekeeper-controller-manager-0 violations: - enforcementAction: dryrun kind: Pod message: 'Privileged container is not allowed: nginx, securityContext: {"privileged": true}' name: nginx namespace: default
如要確認政策不會干擾部署作業,請執行另一個具備權限的 Pod:
kubectl create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: privpod labels: app: privpod spec: containers: - name: nginx image: nginx securityContext: privileged: true EOF
這個新 Pod 會成功部署。
如要清除本節中建立的資源,請執行下列指令:
kubectl delete k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container kubectl delete constrainttemplate k8spspprivilegedcontainer kubectl delete pod/nginx kubectl delete pod/privpod
執行政策
現在您可以在不影響現有或新工作負載的情況下,確認政策的效力和影響,因此可以全面強制執行政策。
以驗證上述政策的範例為基礎,下列步驟說明開發人員、營運人員或管理員如何套用限制範本和限制,以強制執行政策:
載入先前提及的
k8spspprivilegedcontainer
限制範本:kubectl create -f- <<EOF apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8spspprivilegedcontainer spec: crd: spec: names: kind: K8sPSPPrivilegedContainer targets: - target: admission.k8s.gatekeeper.sh rego: | package k8spspprivileged violation[{"msg": msg, "details": {}}] { c := input_containers[_] c.securityContext.privileged msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext]) } input_containers[c] { c := input.review.object.spec.containers[_] } input_containers[c] { c := input.review.object.spec.initContainers[_] } EOF
建立新的限制條件,即可擴充這個限制範本。這次請勿設定
enforcementAction
鍵。根據預設,enforcementAction
鍵會設為deny
:kubectl create -f- <<EOF apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPSPPrivilegedContainer metadata: name: psp-privileged-container spec: match: kinds: - apiGroups: [""] kinds: ["Pod"] EOF
嘗試部署聲明特殊權限的容器:
kubectl create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx securityContext: privileged: true EOF
您應該會收到下列錯誤訊息:
Error from server ([denied by psp-privileged-container] Privileged container is not allowed: nginx, securityContext: {"privileged": true}): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [denied by psp-privileged-container] Privileged container is not allowed: nginx, securityContext: {"privileged": true}
如要清除,請執行下列指令:
kubectl delete k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container kubectl delete constrainttemplate k8spspprivilegedcontainer
Gatekeeper 的替代方案
您可以透過 Gatekeeper 宣告及套用自訂 Pod 層級安全性政策。您也可以使用 Kubernetes 內建的PodSecurity
許可控制器,套用預先定義的 Pod 層級安全性政策。這些預先定義的政策符合 Pod 安全性標準定義的層級。
後續步驟
Gatekeeper 提供非常強大的方法,可使用宣告式政策,在 GKE 叢集上強制執行及驗證安全性。不過,Gatekeeper 的用途不只在於安全,還可用於管理和營運的其他方面。