在集群级别应用 Pod 安全标准
注意:本教程仅适用于新集群。
Pod 安全是一种准入控制器,当创建新的 Pod 时,它会依据 Kubernetes Pod 安全标准进行检查。该功能在 v1.25 版本中达到了稳定版本(GA)。本教程将向你展示如何在集群级别强制实施基线 Pod 安全标准,这会将标准配置应用于集群中的所有命名空间。
若要将 Pod 安全标准应用于特定的命名空间,请参考 “在命名空间级别应用 Pod 安全标准”。
如果你运行的 Kubernetes 版本不是 v1.32,请查阅对应版本的文档。
开始之前
在你的工作站上安装以下工具:
- kind
- kubectl
本教程将演示对于你完全可控的 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.32.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使用 --dry-run=server 了解应用不同 Pod 安全标准时会发生什么
特权(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基线(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受限(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从上述输出中,你会注意到应用特权 Pod 安全标准时,任何命名空间都没有警告。然而,基线和受限标准都有警告,特别是在 kube-system 命名空间中。
设置模式、版本和标准
在本节中,你将对最新版本应用以下 Pod 安全标准:
- 以强制(enforce)模式应用基线(baseline)标准。
- 以警告(warn)和审计(audit)模式应用受限(restricted)标准。
基线 Pod 安全标准提供了一个较为合适的中间选择,它能使豁免列表保持简短,并防止已知的权限提升风险。
此外,为了避免 kube-system 命名空间中的 Pod 运行失败,你将豁免该命名空间,使其不应用 Pod 安全标准。
当你在自己的环境中实施 Pod 安全准入时,请考虑以下几点:
根据应用于集群的风险态势,像受限这样更严格的 Pod 安全标准可能是更好的选择。
豁免 kube-system 命名空间会允许该命名空间中的 Pod 以特权模式运行。在实际应用中,Kubernetes 项目强烈建议你遵循最小权限原则,应用严格的 RBAC 策略来限制对 kube-system 的访问。
为了实现上述标准,请执行以下操作:
创建一个可被 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注意:pod-security.admission.config.k8s.io/v1 配置要求 Kubernetes 版本为 v1.25 及以上。对于 v1.23 和 v1.24 版本,使用 v1beta1。对于 v1.22 版本,使用 v1alpha1。
配置 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.io/docs/concepts/storage/volumes/#mount-propagation
# default None
propagation: None
EOF注意:如果你在 macOS 上使用 Docker Desktop 搭配 kind,你可以在菜单项 “Preferences> Resources > File Sharing” 下将 /tmp 添加为共享目录。
创建一个使用 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.32.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 🙂将 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'.在默认命名空间中创建一个 Pod
# security/example-baseline-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80kubectl 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上述两条命令分别删除了名为 psa-with-cluster-pss 和 psa-wo-cluster-pss 的集群。
kind delete cluster 命令用于删除由 kind 工具创建的 Kubernetes 集群,通过指定 --name 参数来明确要删除的集群名称。
执行这些命令后,相应集群的所有资源(包括节点、Pod、服务等)都会被移除,从而释放相关的计算资源和存储空间,使得环境恢复到创建集群之前的状态。