在叢集級別應用 Pod 安全標準

Pod Security 是一個准入控制器,它在建立新 Pod 時根據 Kubernetes Pod 安全標準執行檢查。此功能在 v1.25 版本中正式釋出。本教程向你展示如何在叢集級別強制實施 baseline Pod 安全標準,這將對叢集中的所有名稱空間應用標準配置。

要將 Pod 安全標準應用於特定的名稱空間,請參閱 在名稱空間級別應用 Pod 安全標準

如果你正在執行 v1.34 以外的 Kubernetes 版本,請查閱該版本的文件。

準備工作

在你的工作站上安裝以下內容

本教程演示了你可以為完全控制的 Kubernetes 叢集配置哪些內容。如果你正在學習如何為無法配置控制平面的託管叢集配置 Pod 安全准入,請閱讀 在名稱空間級別應用 Pod 安全標準

選擇要應用的正確 Pod 安全標準

Pod 安全准入 允許你使用以下模式應用內建的 Pod 安全標準enforce(強制)、audit(審計)和 warn(警告)。

為了收集有助於你選擇最適合你配置的 Pod 安全標準的資訊,請執行以下操作:

  1. 建立一個未應用 Pod 安全標準的叢集

    kind create cluster --name psa-wo-cluster-pss
    

    輸出類似於:

    Creating cluster "psa-wo-cluster-pss" ...
    ✓ Ensuring node image (kindest/node:v1.34.0) 🖼
    ✓ Preparing nodes 📦
    ✓ Writing configuration 📜
    ✓ Starting control-plane 🕹️
    ✓ Installing CNI 🔌
    ✓ Installing StorageClass 💾
    Set kubectl context to "kind-psa-wo-cluster-pss"
    You can now use your cluster with:
    
    kubectl cluster-info --context kind-psa-wo-cluster-pss
    
    Thanks for using kind! 😊
    
  2. 將 kubectl 上下文設定為新叢集

    kubectl cluster-info --context kind-psa-wo-cluster-pss
    

    輸出類似於:

    Kubernetes control plane is running at https://127.0.0.1:61350
    
    CoreDNS is running at https://127.0.0.1:61350/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
    
    To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
    
  3. 獲取叢集中名稱空間的列表

    kubectl get ns
    

    輸出類似於:

    NAME                 STATUS   AGE
    default              Active   9m30s
    kube-node-lease      Active   9m32s
    kube-public          Active   9m32s
    kube-system          Active   9m32s
    local-path-storage   Active   9m26s
    
  4. 使用 --dry-run=server 瞭解應用不同 Pod 安全標準時會發生什麼

    1. 特權(Privileged)

      kubectl label --dry-run=server --overwrite ns --all \
      pod-security.kubernetes.io/enforce=privileged
      

      輸出類似於:

      namespace/default labeled
      namespace/kube-node-lease labeled
      namespace/kube-public labeled
      namespace/kube-system labeled
      namespace/local-path-storage labeled
      
    2. 基線(Baseline)

      kubectl label --dry-run=server --overwrite ns --all \
      pod-security.kubernetes.io/enforce=baseline
      

      輸出類似於:

      namespace/default labeled
      namespace/kube-node-lease labeled
      namespace/kube-public labeled
      Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "baseline:latest"
      Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes
      Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes
      Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged
      namespace/kube-system labeled
      namespace/local-path-storage labeled
      
    3. 受限(Restricted)

      kubectl label --dry-run=server --overwrite ns --all \
      pod-security.kubernetes.io/enforce=restricted
      

      輸出類似於:

      namespace/default labeled
      namespace/kube-node-lease labeled
      namespace/kube-public labeled
      Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "restricted:latest"
      Warning: coredns-7bb9c7b568-hsptc (and 1 other pod): unrestricted capabilities, runAsNonRoot != true, seccompProfile
      Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true
      Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
      Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
      namespace/kube-system labeled
      Warning: existing pods in namespace "local-path-storage" violate the new PodSecurity enforce level "restricted:latest"
      Warning: local-path-provisioner-d6d9f7ffc-lw9lh: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
      namespace/local-path-storage labeled
      

從之前的輸出中,你會注意到應用 privileged Pod 安全標準沒有顯示任何名稱空間的警告。但是,baselinerestricted 標準都有警告,特別是在 kube-system 名稱空間中。

設定模式、版本和標準

在本節中,你將對 latest 版本應用以下 Pod 安全標準

  • enforce 模式下的 baseline 標準。
  • warnaudit 模式下的 restricted 標準。

baseline Pod 安全標準提供了一個方便的中間地帶,允許保持豁免列表簡短並防止已知的許可權升級。

此外,為了防止 Pod 在 kube-system 中失敗,你將豁免該名稱空間不應用 Pod 安全標準。

當你在自己的環境中實施 Pod 安全准入時,請考慮以下事項

  1. 根據應用於叢集的風險態勢,更嚴格的 Pod 安全標準(如 restricted)可能是更好的選擇。

  2. 豁免 kube-system 名稱空間允許 Pod 在此名稱空間中以 privileged 身份執行。對於實際使用,Kubernetes 專案強烈建議你遵循最小許可權原則,應用嚴格的 RBAC 策略來限制對 kube-system 的訪問。要實施上述標準,請執行以下操作

  3. 建立一個可供 Pod 安全准入控制器使用的配置檔案,以實施這些 Pod 安全標準

    mkdir -p /tmp/pss
    cat <<EOF > /tmp/pss/cluster-level-pss.yaml
    apiVersion: apiserver.config.k8s.io/v1
    kind: AdmissionConfiguration
    plugins:
    - name: PodSecurity
      configuration:
        apiVersion: pod-security.admission.config.k8s.io/v1
        kind: PodSecurityConfiguration
        defaults:
          enforce: "baseline"
          enforce-version: "latest"
          audit: "restricted"
          audit-version: "latest"
          warn: "restricted"
          warn-version: "latest"
        exemptions:
          usernames: []
          runtimeClasses: []
          namespaces: [kube-system]
    EOF
    
  4. 配置 API 伺服器以在叢集建立期間使用此檔案

    cat <<EOF > /tmp/pss/cluster-config.yaml
    kind: Cluster
    apiVersion: kind.x-k8s.io/v1alpha4
    nodes:
    - role: control-plane
      kubeadmConfigPatches:
      - |
        kind: ClusterConfiguration
        apiServer:
            extraArgs:
              admission-control-config-file: /etc/config/cluster-level-pss.yaml
            extraVolumes:
              - name: accf
                hostPath: /etc/config
                mountPath: /etc/config
                readOnly: false
                pathType: "DirectoryOrCreate"
      extraMounts:
      - hostPath: /tmp/pss
        containerPath: /etc/config
        # optional: if set, the mount is read-only.
        # default false
        readOnly: false
        # optional: if set, the mount needs SELinux relabeling.
        # default false
        selinuxRelabel: false
        # optional: set propagation mode (None, HostToContainer or Bidirectional)
        # see https://kubernetes.club.tw/docs/concepts/storage/volumes/#mount-propagation
        # default None
        propagation: None
    EOF
    
  5. 建立一個使用 Pod 安全准入來應用這些 Pod 安全標準的叢集

    kind create cluster --name psa-with-cluster-pss --config /tmp/pss/cluster-config.yaml
    

    輸出類似於:

    Creating cluster "psa-with-cluster-pss" ...
     ✓ Ensuring node image (kindest/node:v1.34.0) 🖼
     ✓ Preparing nodes 📦
     ✓ Writing configuration 📜
     ✓ Starting control-plane 🕹️
     ✓ Installing CNI 🔌
     ✓ Installing StorageClass 💾
    Set kubectl context to "kind-psa-with-cluster-pss"
    You can now use your cluster with:
    
    kubectl cluster-info --context kind-psa-with-cluster-pss
    
    Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
    
  6. 將 kubectl 指向叢集

    kubectl cluster-info --context kind-psa-with-cluster-pss
    

    輸出類似於:

    Kubernetes control plane is running at https://127.0.0.1:63855
    CoreDNS is running at https://127.0.0.1:63855/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
    
    To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
    
  7. 在預設名稱空間中建立一個 Pod

    apiVersion: v1
     kind: Pod
     metadata:
       name: nginx
     spec:
       containers:
         - image: nginx
           name: nginx
           ports:
             - containerPort: 80
     
    kubectl apply -f https://k8s.io/examples/security/example-baseline-pod.yaml
    

    Pod 正常啟動,但輸出包含一個警告

    Warning: would violate 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/nginx created
    

清理

現在執行以下命令刪除你建立的叢集

kind delete cluster --name psa-with-cluster-pss
kind delete cluster --name psa-wo-cluster-pss

下一步

上次修改時間:太平洋標準時間 2023 年 11 月 30 日凌晨 1:22:[en] 更新 cluster-level-pss.md 顯示使用者將應用的示例程式碼 (310a1221ac)