Google Kubernetes Engine (GKE) Autopilot 集群中的特权工作负载必须正确配置,以避免出现问题。配置错误可能会导致与许可清单的同步失败,或导致工作负载被拒绝。这些问题可能会导致必要的代理或服务无法以所需的权限运行。
您可以使用本文档排查在 Autopilot 上部署特权工作负载时遇到的问题。查找有关如何解决许可清单同步错误的指导,并诊断特权工作负载可能遭拒的原因。
对于在 Autopilot 集群上部署具有提升权限的工作负载的平台管理员和运维人员以及安全团队来说,此信息非常重要。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务。
许可名单同步问题
当您部署 AllowlistSynchronizer 时,GKE 会尝试安装并同步您指定的许可名单文件。如果此同步失败,AllowlistSynchronizer 的 status 字段会报告错误。
获取 AllowlistSynchronizer 对象的状态:
kubectl get allowlistsynchronizer ALLOWLIST_SYNCHRONIZER_NAME -o yaml
输出类似于以下内容:
...
status:
conditions:
- type: Ready
status: "False"
reason: "SyncError"
message: "some allowlists failed to sync: example-allowlist-1.yaml"
lastTransitionTime: "2024-10-12T10:00:00Z"
observedGeneration: 2
managedAllowlistStatus:
- filePath: "gs://path/to/allowlist1.yaml"
generation: 1
phase: Installed
lastSuccessfulSync: "2024-10-10T10:00:00Z"
- filePath: "gs://path/to/allowlist2.yaml"
phase: Failed
lastError: "Initial install failed: invalid contents"
lastSuccessfulSync: "2024-10-08T10:00:00Z"
conditions.message 字段和 managedAllowlistStatus.lastError 字段会提供有关错误的详细信息。请使用此信息来解决问题。
多个 AllowlistSynchronizer
在版本低于 1.33.4-gke.1035000 的 GKE 集群中,如果存在多个 AllowlistSynchronizer,WorkloadAllowlists 可能无法安装。
如需解决此问题,请仅使用包含多个 allowlistPaths 的单个 AllowlistSynchronizer。
或者,您也可以将集群升级到较新版本。
工作负载容器排序
在版本低于 1.34.0-gke.0000000 的 GKE 集群中,如果一个或多个工作负载容器映像与集群内 WorkloadAllowlist 中指定的容器映像匹配,则工作负载容器可能会以反向字母顺序进行创建和排序。
如需解决此问题,请尝试以下选项:
- 将集群升级到 1.34.0-gke.0000000 版或更高版本。
- 重命名工作负载的容器,以便它们按正确的顺序排序。
特权工作负载部署问题
成功安装许可名单后,您可以在集群中部署相应的特权工作负载。在某些情况下,GKE 可能会拒绝工作负载。
请尝试以下解决方案:
- 确保集群的 GKE 版本符合工作负载的版本要求。
- 确保您要部署的工作负载是许可名单文件所应用的工作负载。
如需了解特权工作负载遭拒的原因,请向 GKE 请求有关许可名单违规行为的详细信息:
获取集群中已安装的许可名单列表:
kubectl get workloadallowlist找到应该应用于特权工作负载的许可名单的名称。
在文本编辑器中打开特权工作负载的 YAML 清单。如果您无法访问 YAML 清单,例如,如果工作负载部署流程使用其他工具,请与工作负载提供商联系以提交问题。跳过其余步骤。
将以下标签添加到特权工作负载 Pod 规范的
spec.metadata.labels部分:labels: cloud.google.com/matching-allowlist: ALLOWLIST_NAME将
ALLOWLIST_NAME替换为您在上一步中获得的许可名单名称。使用kubectl get workloadallowlist命令输出中的名称,而不是许可名单文件的路径。保存清单并将工作负载应用于集群:
kubectl apply -f WORKLOAD_MANIFEST_FILE将
WORKLOAD_MANIFEST_FILE替换为清单文件的路径。输出会详细说明工作负载中的哪些字段与指定的许可名单不匹配,如下例所示:
Error from server (GKE Warden constraints violations): error when creating "STDIN": admission webhook "warden-validating.common-webhooks.networking.gke.io" denied the request: =========================================================================== Workload Mismatches Found for Allowlist (example-allowlist-1): =========================================================================== HostNetwork Mismatch: Workload=true, Allowlist=false HostPID Mismatch: Workload=true, Allowlist=false Volume[0]: data - data not found in allowlist. Verify volume with matching name exists in allowlist. Container[0]: - Envs Mismatch: - env[0]: 'ENV_VAR1' has no matching string or regex pattern in allowlist. - env[1]: 'ENV_VAR2' has no matching string or regex pattern in allowlist. - Image Mismatch: Workload=k8s.gcr.io/diff/image, Allowlist=k8s.gcr.io/pause2. Verify that image string or regex match. - SecurityContext: - Capabilities.Add Mismatch: the following added capabilities are not permitted by the allowlist: [SYS_ADMIN SYS_PTRACE] - VolumeMount[0]: data - data not found in allowlist. Verify volumeMount with matching name exists in allowlist.在此示例中,存在以下违规行为:
- 工作负载指定了
hostNetwork: true,但许可名单未指定hostNetwork: true。 - 工作负载指定了
hostPID: true,但许可名单未指定hostPID: true。 - 工作负载指定了一个名为
data的卷,但许可名单未指定名为data的卷。 - 容器指定了名为
ENV_VAR1和ENV_VAR2的环境变量,但许可名单未指定这些环境变量。 - 容器指定了映像
k8s.gcr.io/diff/image,但许可名单指定了k8s.gcr.io/pause2。 - 容器添加了
SYS_ADMIN和SYS_PTRACE功能,但许可名单不允许添加这些功能。 - 容器指定了名为
data的卷装载,但许可名单未指定名为data的卷装载。
- 工作负载指定了
如果您要部署由第三方提供商提供的工作负载,请向该提供商提交问题以解决违规问题。提供上一步中问题的输出。
Webhook 干扰许可清单上的工作负载
在某些情况下,即使工作负载已正确配置,符合许可清单,GKE 仍可能会拒绝该工作负载。如果在工作负载控制器创建的 Pod 得到许可清单的许可后,集群中的另一个准入控制器 (webhook) 修改了该 Pod,则可能会出现这种情况。这些修改可能会导致 Pod 规范不再与许可清单匹配,从而导致被 GKE Warden 准入 webhook 拒绝。
此问题在将边车容器或环境变量注入到 Pod 中的第三方监控和安全代理中很常见。
症状
最常见的症状是,虽然工作负载控制器(例如 DaemonSet 或 Deployment)已成功创建,但它未能创建任何 Pod。当您检查控制器的事件时,会看到指明 Pod 被准入 webhook 拒绝的消息。
诊断
- 按照特权工作负载部署问题部分中的步骤,将
cloud.google.com/matching-allowlist标签添加到您的工作负载。 - 从工作负载的 YAML 清单中复制
spec.template。 - 创建新的 Pod 清单,并将复制的规范粘贴到
spec字段中。 在 Pod 清单中设置
apiVersion、kind和metadata.name字段:apiVersion: v1 kind: Pod metadata: name: POD_NAME labels: cloud.google.com/matching-allowlist: ALLOWLIST_NAME spec: # Paste the content of spec.template here替换以下内容:
POD_NAME:测试 Pod 的名称。ALLOWLIST_NAME:许可清单的名称。
应用 Pod 清单:
kubectl apply -f YOUR_POD_MANIFEST_FILE将
YOUR_POD_MANIFEST_FILE替换为 Pod 清单文件的路径。检查上一步的输出。如果您在“工作负载不匹配”部分中看到意外的字段,例如额外的环境变量(如
DD_AGENT_HOST)、容器或卷,这强烈表明另一个 webhook 正在修改您的 Pod。
解决方法
如需解决此问题,您需要配置冲突的 webhook,以将其排除,使其无法修改已列入许可清单的工作负载的 Pod。具体操作通常是向工作负载或其命名空间添加标签或注解,以向 webhook 告知它应不介入变更。例如,使用 Datadog 时,您需要向工作负载的命名空间添加 admission.datadoghq.com/enabled: "false" 标签。
请参阅您所用特定第三方软件的相关文档,了解如何从其准入控制器中排除工作负载。
通过阻止其他 webhook 修改 Pod,您可以帮助确保这些 Pod 继续符合许可清单,并成功部署到 Autopilot 集群中。
关于特权工作负载和许可清单的 bug 和功能请求
合作伙伴负责创建、开发和维护其特权工作负载和许可名单。如果您遇到 bug 或想要提出关于特权工作负载或许可名单的功能请求,请与相应的合作伙伴联系。
后续步骤
如果您在文档中找不到问题的解决方案,请参阅获取支持以获取进一步的帮助,包括以下主题的建议:
- 请与 Cloud Customer Care 联系,以提交支持请求。
- 通过在 StackOverflow 上提问并使用
google-kubernetes-engine标记搜索类似问题,从社区获得支持。您还可以加入#kubernetes-engineSlack 频道,以获得更多社区支持。 - 使用公开问题跟踪器提交 bug 或功能请求。