使用 PodSecurity 套用預先定義的 Pod 層級安全性政策

本頁說明如何使用 PodSecurity 准入控制器,在 Google Kubernetes Engine (GKE) 叢集中套用預先定義的 Pod 層級安全控管措施。對 Pod 套用安全控管機制,有助於滿足安全性與法規遵循需求。本頁面將進一步說明 PodSecurity,以及如何將其套用至 Pod。

本頁內容適用於想對 GKE 叢集套用安全控管機制的安全專家。如要進一步瞭解我們在內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。 Google Cloud

閱讀本頁面之前,請先熟悉下列概念:

關於「PodSecurity」

PodSecurity 是 Kubernetes 許可控制器,可讓您將 Pod 安全性標準套用至 GKE 叢集上執行的 Pod。Pod 安全性標準是預先定義的安全政策,可滿足 Kubernetes 中 Pod 安全性的高階需求。這些政策的限制程度從寬鬆到嚴格都有。

您可以對 GKE 叢集套用下列 Pod 安全性標準:

  • 具備權限:不受限制的政策,可提供最廣泛的權限。允許已知的權限提升。
  • 基準:限制最少的政策,允許預設的最低指定 Pod 設定。防止已知的權限提升。
  • 受限制:這項政策非常嚴格,遵循 Pod 強化的最佳做法。

您可以使用 PodSecurity 許可控制器,在下列模式中套用 Pod 安全性標準:

  • 強制執行:違反政策會導致 Pod 建立作業遭到拒絕。稽核事件會新增至稽核記錄。
  • 稽核:違反政策會觸發稽核事件,並新增至稽核記錄。 允許建立 Pod。
  • 警告:違反政策會觸發向使用者顯示的警告。允許建立 Pod。

PodSecurity 許可控制器會將這些政策嵌入 Kubernetes API。

如要在 Pod 層級建立及套用自訂安全性政策,請考慮改用 Gatekeeper 許可控制器。

事前準備

開始之前,請務必先完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
  • 確認您有執行 1.23 以上版本的 GKE Autopilot 或標準叢集。

需求條件

在執行下列 GKE 版本的叢集上,PodSecurity 准入控制器預設會啟用:

  • 1.25 以上版本:穩定版
  • 1.23 版和 1.24 版:Beta 版

如要查看 GKE 版本是否可用,以及是否為發布通路的預設版本,請參閱發布時間表。

使用 PodSecurity 套用 Pod 安全性標準

如要使用 PodSecurity 許可控制器,您必須在特定模式下,對特定命名空間套用特定 Pod 安全性標準。您可以使用命名空間標籤執行這項操作。 在本練習中,您將執行下列作業:

  • 建立兩個新的命名空間
  • 為每個命名空間套用安全性政策
  • 測試已設定的政策

在下列 GKE 版本中,GKE 會忽略您套用至 kube-system 命名空間的政策:

  • 1.23.6-gke.1900 以上版本
  • 1.24.0-gke.1200 以上版本

在舊版 GKE 中,請避免在 kube-system 中強制執行政策。

建立新的命名空間

在叢集中建立命名空間:

kubectl create ns baseline-ns
kubectl create ns restricted-ns

這個指令會建立下列命名空間:

  • baseline-ns:適用於寬鬆型工作負載
  • restricted-ns:適用於高度受限的工作負載

使用標籤套用安全性政策

套用下列 Pod 安全性標準:

  • baseline:在warn模式下套用至「baseline-ns」
  • restricted:在enforce模式下套用至「restricted-ns」
kubectl label --overwrite ns baseline-ns pod-security.kubernetes.io/warn=baseline
kubectl label --overwrite ns restricted-ns pod-security.kubernetes.io/enforce=restricted

這些指令可達成下列結果:

  • 系統允許 baseline-ns 命名空間中違反 baseline 政策的工作負載,且用戶端會顯示警告訊息。
  • 如果 restricted-ns 命名空間中的工作負載違反 restricted 政策,系統會拒絕該工作負載,並在稽核記錄中新增項目。

確認已新增標籤:

kubectl get ns --show-labels

輸出結果會與下列內容相似:

baseline-ns       Active   74s   kubernetes.io/metadata.name=baseline-ns,pod-security.kubernetes.io/warn=baseline
restricted-ns     Active   18s   kubernetes.io/metadata.name=restricted-ns,pod-security.kubernetes.io/enforce=restricted
default           Active   57m   kubernetes.io/metadata.name=default
kube-public       Active   57m   kubernetes.io/metadata.name=kube-public
kube-system       Active   57m   kubernetes.io/metadata.name=kube-system

測試已設定的政策

如要確認 PodSecurity 准入控制器是否正常運作,請將違反 baseline 和 restricted 政策的工作負載部署至兩個命名空間。以下範例資訊清單會部署 nginx 容器,允許權限提升。

  1. 將下列資訊清單儲存為 psa-workload.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        securityContext:
          privileged: true
    
  2. 將資訊清單套用至 baseline-ns 命名空間:

    kubectl apply -f psa-workload.yaml --namespace=baseline-ns
    

    輸出結果會與下列內容相似:

    Warning: would violate PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)
    

    baseline 政策允許 Pod 在命名空間中部署。

  3. 確認 Pod 部署成功:

    kubectl get pods --namespace=baseline-ns -l=app=nginx
    
  4. 將資訊清單套用至 restricted-ns 命名空間:

    kubectl apply -f psa-workload.yaml --namespace=restricted-ns
    

    輸出結果會與下列內容相似:

    Error from server (Forbidden): error when creating "workload.yaml": pods "nginx"
    is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation
    != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false),
    unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]),
    runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true),
    seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type
    to "RuntimeDefault" or "Localhost")
    

    Pod 不會部署在命名空間中。稽核項目會新增至記錄。

在稽核記錄中查看政策違規事項

系統會在叢集的稽核記錄中,記錄 audit 和 enforce 模式下的政策違規事項。您可以在Google Cloud 控制台使用記錄檔探索工具查看這些記錄。

  1. 前往 Google Cloud 控制台的「Logs Explorer」頁面。

    前往 Logs Explorer

  2. 在「查詢」欄位中,指定下列項目來擷取 audit 和 enforce 模式稽核記錄:

    resource.type="k8s_cluster"
    protoPayload.resourceName:"/pods/nginx"
    protoPayload.methodName="io.k8s.core.v1.pods.create"
    (labels."pod-security.kubernetes.io/audit-violations":"PodSecurity" OR protoPayload.response.reason="Forbidden")
    
  3. 點選「執行查詢」。

  4. 在「查詢結果」部分,展開 Forbidden 記錄項目,檢查 enforce 模式拒絕記錄。詳細資料如下:

    {
      ...
      protoPayload: {
        @type: "type.googleapis.com/google.cloud.audit.AuditLog"
        authenticationInfo: {1}
        authorizationInfo: [1]
        methodName: "io.k8s.core.v1.pods.create"
        request: {6}
        requestMetadata: {2}
        resourceName: "core/v1/namespaces/restricted-ns/pods/nginx"
        response: {
          @type: "core.k8s.io/v1.Status"
          apiVersion: "v1"
          code: 403
          details: {2}
          kind: "Status"
          message: "pods "nginx" is forbidden: violates PodSecurity "restricted:latest": privileged
                  (container "nginx" must not set securityContext.privileged=true),
                  allowPrivilegeEscalation != false (container "nginx" must set
                  securityContext.allowPrivilegeEscalation=false), unrestricted capabilities
                  (container "nginx" must set securityContext.capabilities.drop=["ALL"]),
                  runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true),
                  seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type
                  to "RuntimeDefault" or "Localhost")"
          metadata: {0}
          reason: "Forbidden"
          status: "Failure"
          }
          serviceName: "k8s.io"
          status: {2}
        }
      receiveTimestamp: "2022-02-01T19:19:25.353235326Z"
      resource: {2}
      timestamp: "2022-02-01T19:19:21.469360Z"
    }
    
  5. 展開 audit-violations 記錄項目,檢查 audit 模式記錄。 詳細資料如下:

    {
      ...
      labels: {
        ...
        pod-security.kubernetes.io/audit-violations: "would violate PodSecurity "baseline:latest": privileged
                                                    (container "nginx" must not set securityContext.privileged=true)"
        pod-security.kubernetes.io/enforce-policy: "privileged:latest"
      }
      operation: {4}
      protoPayload: {10}
      receiveTimestamp: "2023-12-26T05:18:04.533631468Z"
      resource: {2}
      timestamp: "2023-12-26T05:17:36.102387Z"
    }
    

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取費用,請刪除命名空間:

kubectl delete ns baseline-ns
kubectl delete ns restricted-ns

「PodSecurity」的替代方案

除了使用內建的 Kubernetes PodSecurity 許可控制器套用 Pod 安全性標準,您也可以使用 Open Policy Agent (OPA) 型許可控制器 Gatekeeper,建立及套用自訂 Pod 層級安全性控管機制。

後續步驟