在集群级别应用 Pod 安全标准

Pod 安全性是一个准入控制器,它会在创建新的 Pod 时根据 Kubernetes Pod 安全性标准 执行检查。它是在 v1.25 中推出的 GA 功能。本教程演示了如何强制在集群级别执行 baseline Pod 安全性标准,这会将标准配置应用于集群中的所有命名空间。

要将 Pod 安全性标准应用于特定命名空间,请参考 在命名空间级别应用 Pod 安全性标准

如果您运行的 Kubernetes 版本不是 v1.31,请查看该版本的文档。

开始之前

在您的工作站上安装以下内容

本教程演示了您可以为完全控制的 Kubernetes 集群配置的内容。如果您正在学习如何为托管集群配置 Pod 安全性准入,而您无法配置控制平面,请阅读 在命名空间级别应用 Pod 安全性标准

选择要应用的正确 Pod 安全性标准

Pod 安全性准入 允许您使用以下模式应用内置的 Pod 安全性标准enforceauditwarn

要收集帮助您选择最适合您的配置的 Pod 安全性标准的信息,请执行以下操作

  1. 创建一个没有应用 Pod 安全性标准的集群

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

    输出类似于

    Creating cluster "psa-wo-cluster-pss" ...
    ✓ Ensuring node image (kindest/node:v1.31.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. 特权

      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. 基线

      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. 受限

      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 命名空间中。

设置模式、版本和标准

在本节中,您将以下 Pod 安全性标准应用于 latest 版本

  • baseline 标准在 enforce 模式下。
  • restricted 标准在 warnaudit 模式下。

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.ac.cn/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.31.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.kubernetes.ac.cn/#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)