使用 Gatekeeper 套用自訂 Pod 層級安全性政策

本頁說明如何使用 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 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。

在啟用 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" 

如要進一步瞭解 ConstraintConstraintTemplate 物件的可用選項,請參閱「如何使用 Gatekeeper」。

測試政策

在現有叢集中導入新政策可能會導致不良行為,例如限制現有工作負載。使用 Gatekeeper 確保 Pod 安全的一項優點,就是能夠透過模擬測試模式,測試政策的效力和影響,而不必實際變更。這樣一來,您就能針對執行中的叢集測試政策設定,而不必強制執行。系統會記錄並找出違反政策的行為,不會受到干擾。

下列步驟說明開發人員、營運人員或管理員如何套用限制範本和限制,判斷其效力或潛在影響:

  1. 套用 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 
  2. 不套用任何限制,以進階權限執行工作負載:

    kubectl create -f- <<EOF apiVersion: v1 kind: Pod metadata:   name: nginx   labels:     app: nginx spec:   containers:   - name: nginx     image: nginx     securityContext:       privileged: true EOF 
  3. 載入先前的 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 
  4. 建立新的限制條件,即可擴充這個限制範本。這次請將 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 
  5. 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 
  6. 如要確認政策不會干擾部署作業,請執行另一個具備權限的 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 會成功部署。

  7. 如要清除本節中建立的資源,請執行下列指令:

    kubectl delete k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container kubectl delete constrainttemplate k8spspprivilegedcontainer kubectl delete pod/nginx kubectl delete pod/privpod 

執行政策

現在您可以在不影響現有或新工作負載的情況下,確認政策的效力和影響,因此可以全面強制執行政策。

以上述政策驗證範例為基礎,下列步驟說明開發人員、營運人員或管理員如何套用限制範本和限制,以強制執行政策:

  1. 載入先前提及的 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 
  2. 建立新的限制條件,即可擴充這個限制範本。這次請勿設定 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 
  3. 嘗試部署聲明特殊權限的容器:

    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} 
  4. 如要清除,請執行下列指令:

    kubectl delete k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container kubectl delete constrainttemplate k8spspprivilegedcontainer 

Gatekeeper 的替代方案

您可以透過 Gatekeeper 宣告及套用自訂 Pod 層級安全性政策。您也可以使用 Kubernetes 內建的PodSecurity許可控制器,套用預先定義的 Pod 層級安全性政策。這些預先定義的政策符合 Pod 安全性標準定義的層級。

後續步驟

Gatekeeper 提供非常強大的方法,可使用宣告式政策,在 GKE 叢集上強制執行及驗證安全性。不過,Gatekeeper 的用途不只在於安全,還可用於管理和營運的其他方面。