本页面介绍如何使用 PodSecurity
准入控制器在 Google Kubernetes Engine (GKE) 集群中应用预定义的 Pod 级层安全控制机制。
如需详细了解 PodSecurity
的工作原理,请参阅 Pod 安全准入。
概览
PodSecurity
是一个 Kubernetes 准入控制器,允许您向 GKE 集群上运行的 Pod 应用 Pod 安全标准。Pod 安全标准是预定义的安全政策,涵盖 Kubernetes 中 Pod 安全性的高层次需求。这些政策的范围各有不同,从高度宽松到高度严格。
您可以将以下 Pod 安全标准应用于您的 GKE 集群:
- 特权:不受限制的政策,提供最宽泛的权限。允许已知的提权。
- 基准:具有最低限制性的政策,这是默认指定的最低限度的 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 集群。
- 对于 Autopilot 集群,请注册默认版本为 1.23 或更高版本的发布渠道。
- 对于标准集群,请注册发布渠道或者将集群升级到特定版本。
使用要求
默认情况下,运行以下 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
政策的工作负载,并且 GKE 会在审核日志中添加条目。
确认是否已添加标签:
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
容器,该容器允许提权。
将以下清单保存为
psa-workload.yaml
:apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx securityContext: privileged: true
将该清单应用于
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 部署到命名空间中。确认 Pod 是否已成功部署:
kubectl get pods --namespace=baseline-ns -l=app=nginx
将该清单应用于
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 控制台中的日志浏览器查看这些日志。
转到 Google Cloud 控制台中的日志浏览器页面。
在查询字段中,指定以下内容以检索
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")
点击运行查询。
在查询结果部分中,展开
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" }
展开
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 级层的安全控制措施。