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


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

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

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

關於「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,取得最新版本。
  • 確認您有執行 1.23 以上版本的 GKE Autopilot 或 Standard 叢集。

需求條件

在執行下列 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 准入控制器是否正常運作,請將違反 baselinerestricted 政策的工作負載部署至兩個命名空間。以下範例資訊清單會部署允許權限提升的 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 不會部署在命名空間中。稽核項目會新增至記錄。

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

系統會在叢集的稽核記錄中,記錄 auditenforce 模式下的違規情形。您可以使用Google Cloud 控制台中的記錄檔探索工具查看這些記錄。

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

    前往記錄檔探索工具

  2. 在「Query」(查詢) 欄位中,指定下列項目來擷取 auditenforce 模式稽核記錄:

    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 安全性標準,您也可以使用 Gatekeeper (以 Open Policy Agent (OPA) 為基礎的許可控制器),建立及套用自訂 Pod 層級安全性控制項。

後續步驟