本页面介绍如何解决 Google Kubernetes Engine (GKE) Autopilot 集群的问题。
如果您需要其他帮助,请与 Cloud Customer Care 联系。集群问题
无法创建集群:已注册 0 个节点
您在尝试通过已停用或没有所需权限的 IAM 服务账号创建 Autopilot 集群时会发生以下问题。集群创建失败,并显示以下错误消息:
All cluster resources were brought up, but: only 0 nodes out of 2 have registered.
如需解决此问题,请执行以下操作:
检查默认 Compute Engine 服务账号或您要使用的自定义 IAM 服务账号是否已停用:
gcloud iam service-accounts describe SERVICE_ACCOUNT
将
SERVICE_ACCOUNT
替换为服务账号电子邮件地址,例如my-iam-account@my-first-project.iam.gserviceaccount.com
。如果服务账号已停用,则输出类似于以下内容:
disabled: true displayName: my-service-account email: my-service-account@my-project.iam.gserviceaccount.com ...
如果服务账号已停用,请启用它:
gcloud iam service-accounts enable SERVICE_ACCOUNT
如果在启用该服务账号后仍然出现该错误,请向该服务账号授予 GKE 所需的最低权限:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member "serviceAccount:SERVICE_ACCOUNT" \
--role roles/container.nodeServiceAccount
当集群有 0 个节点时,命名空间卡在终止状态
当您在集群缩减到零个节点后删除集群中的命名空间时,会出现以下问题。metrics-server
组件无法接受命名空间删除请求,因为该组件没有副本。
如需诊断此问题,请运行以下命令:
kubectl describe ns/NAMESPACE_NAME
将 NAMESPACE_NAME
替换为命名空间的名称。
输出如下所示:
Discovery failed for some groups, 1 failing: unable to retrieve the complete
list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to
handle the request
如需解决此问题,请扩容任何工作负载以触发 GKE 来创建新节点。节点准备就绪后,命名空间删除请求会自动完成。在 GKE 删除命名空间后,请缩减工作负载。
扩缩问题
节点纵向扩容失败:Pod 存在不被安排的风险
当您在 Google Cloud 项目中停用串行端口日志记录功能时,会发生以下问题。GKE Autopilot 集群需要串行端口日志记录功能才能有效调试节点问题。如果停用串行端口日志记录功能,则 Autopilot 无法预配节点来运行工作负载。
Kubernetes 事件日志中的错误消息类似于以下内容:
LAST SEEN TYPE REASON OBJECT MESSAGE
12s Warning FailedScaleUp pod/pod-test-5b97f7c978-h9lvl Node scale up in zones associated with this pod failed: Internal error. Pod is at risk of not being scheduled
通过实施 compute.disableSerialPortLogging
限制条件的组织政策,可以在组织级层停用串行端口日志记录功能。您也可以在项目或虚拟机 (VM) 实例级层停用串行端口日志记录功能。
如需解决此问题,请执行以下操作:
- 要求您的 Google Cloud 组织政策管理员在您的 Autopilot 集群中移除项目中的
compute.disableSerialPortLogging
限制条件。 - 如果您没有强制执行此限制条件的组织政策,请尝试在项目元数据中启用串行端口日志记录。此操作需要
compute.projects.setCommonInstanceMetadata
IAM 权限。
节点纵向扩容失败:GCE 资源不足
如果您的工作负载请求的资源超过该 Compute Engine 区域或可用区中可供使用的资源,则会出现以下问题。您的 Pod 可能会保持 Pending
状态。
检查您的 Pod 事件:
kubectl events --for='pod/POD_NAME' --types=Warning
将
RESOURCE_NAME
替换为待处理 Kubernetes 资源的名称。例如pod/example-pod
。输出类似于以下内容:
LAST SEEN TYPE REASON OBJECT Message 19m Warning FailedScheduling pod/example-pod gke.io/optimize-utilization-scheduler 0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling. 14m Warning FailedScheduling pod/example-pod gke.io/optimize-utilization-scheduler 0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling. 12m (x2 over 18m) Warning FailedScaleUp cluster-autoscaler Node scale up in zones us-central1-f associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled. 34s (x3 over 17m) Warning FailedScaleUp cluster-autoscaler Node scale up in zones us-central1-b associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
如需解决此问题,请尝试执行以下操作:
- 在其他区域或可用区中部署 Pod。如果您的 Pod 具有可用区级限制(例如拓扑选择器),请尽可能移除该限制。如需了解相关说明,请参阅将 GKE Pod 放置在特定的可用区中。
- 在其他区域中创建集群并重试部署。
- 尝试使用其他计算类。由较小的 Compute Engine 机器类型提供支持的计算类更有可能具有可用资源。例如,Autopilot 的默认机器类型具有最高可用性。如需查看计算类和相应机器类型的列表,请参阅何时使用特定计算类。
- 如果您运行 GPU 工作负载,则请求的 GPU 可能在您的节点位置不可用。请尝试在其他位置部署工作负载或请求其他类型的 GPU。
如需避免将来发生由资源可用性导致的纵向扩容问题,请考虑以下方法:
- 使用 Kubernetes PriorityClass 在集群中一致地预配额外的计算容量。如需了解详情,请参阅预配额外的计算容量以实现快速 Pod 扩缩。
- 将 Compute Engine 容量预留与性能或加速器计算类搭配使用。如需了解详情,请参阅使用预留的可用区级资源。
节点无法纵向扩容:已超出 Pod 可用区级资源
当 Autopilot 未在特定可用区为 Pod 预配新节点时,会发生以下问题,因为新节点会违反资源限制。
日志中的错误消息类似于以下内容:
"napFailureReasons": [
{
"messageId": "no.scale.up.nap.pod.zonal.resources.exceeded",
...
此错误指的是 noScaleUp
事件,其中节点自动预配功能未为可用区中的 Pod 预配任何节点组。
如果遇到此错误,请确认以下内容:
- 您的 Pod 具有足够的内存和 CPU。
- Pod IP 地址 CIDR 范围足够大,可以支持您预期的集群大小上限。
工作负载问题
工作负载因临时存储错误而卡住
如果您的 Pod 临时存储请求超过 GKE 1.28.6-gke.1317000 版及更高版本中的 Autopilot 最大值 10GiB,GKE 将不会创建 Pod。
如需诊断此问题,请描述工作负载控制器,例如 Deployment 或 Job:
kubectl describe CONTROLLER_TYPE/CONTROLLER_NAME
替换以下内容:
CONTROLLER_TYPE
:工作负载控制器的类型,如replicaset
或daemonset
。如需查看控制器类型列表,请参阅工作负载管理。CONTROLLER_NAME
:卡住的工作负载的名称。
如果由于临时存储请求超出最大值而未创建 Pod,则输出类似于以下内容:
# lines omitted for clarity
Events:
{"[denied by autogke-pod-limit-constraints]":["Max ephemeral-storage requested by init containers for workload '' is higher than the Autopilot maximum of '10Gi'.","Total ephemeral-storage requested by containers for workload '' is higher than the Autopilot maximum of '10Gi'."]}
如需解决此问题,请更新您的临时存储请求,以使工作负载容器和 webhook 注入的容器所请求的临时存储总量小于或等于允许的最大值。如需详细了解最大值,请参阅 Autopilot 中的资源请求以了解正确的工作负载配置。
Pod 卡滞在“待处理”状态
如果您为 Pod 选择了特定节点,但 Pod 和 DaemonSet 中必须在该节点上运行的资源请求总和超过该节点的可分配容量上限,则 Pod 可能会卡在 Pending
状态。这可能会导致您的 Pod 变为 Pending
状态并保持未安排状态。
为避免此问题,请评估已部署的工作负载的大小,以确保它们不超过受支持的 Autopilot 资源请求上限。
您还可以尝试在安排常规工作负载 Pod 之前安排 DaemonSet。
Pod 在终止或创建期间卡住
已知问题导致 Pod 偶尔卡在以下任一状态:
Terminating
CreateContainerError
当您在满足以下所有条件的 GKE 环境中使用可爆发的 Pod 时,此问题发生的可能性较小:
- 您的节点运行的是 GKE 1.29.2-gke.1060000 版及更高版本,但不包括 1.30.2-gke.1394000。
- 您的 Pod 使用以下计算类之一:
- 默认的通用计算类
Balanced
计算类Scale-Out
计算类
为了缓解这一问题,请将控制平面升级到 GKE 1.30.2-gke.1394000 版或更高版本。GKE 在运行固定版本的节点上重新创建 Pod 后,已卡在 Terminating
状态或 CreateContainerError
状态的 Pod 将正确部署。
升级 Autopilot 集群时,GKE 会升级工作器节点以在一段时间内与控制平面版本匹配。必须重启控制平面才能启用爆发,并且必须在所有节点都运行受支持的版本后重启。在扩缩、升级或维护等操作期间,控制平面大约每周自动重启一次。
如需手动触发控制平面重启,请执行以下操作:
检查是否所有节点都运行 1.30.2-gke.1349000 版或更高版本:
kubectl get nodes
输出类似于以下内容:
NAME STATUS ROLES AGE VERSION gk3-ap-cluster-1-default-pool-18092e49-mllk Ready <none> 4m26s v1.30.2-gke.1349000
输出中的所有节点都必须显示所需的版本或更高版本。
手动启动控制平面升级到集群已在使用的版本。如需查看相关说明,请参阅手动升级控制平面。
特定节点上的工作负载性能持续不可靠
在 GKE 1.24 及更高版本中,如果特定节点上的工作负载持续出现中断、崩溃或类似不可靠的行为,您可以使用以下命令封锁有问题的节点,从而将此节点告知 GKE:
kubectl drain NODE_NAME --ignore-daemonsets
将 NODE_NAME
替换为有问题的节点的名称。您可以通过运行 kubectl get nodes
找到节点名称。
GKE 会执行以下操作:
- 从节点逐出现有工作负载并停止在该节点上调度工作负载。
- 在其他节点上自动重新创建由控制器(例如 Deployment 或 StatefulSet)管理的任何被逐出的工作负载。
- 终止保留在节点上的所有工作负载,并随着时间的推移修复或重新创建节点。
- 如果您使用 Autopilot,GKE 会立即关闭并替换节点,并忽略任何已配置的 PodDisruptionBudget。
Pod 在空集群上进行调度所花的时间超过预期时间
当您将工作负载部署到没有其他工作负载的 Autopilot 集群时,会发生此事件。Autopilot 集群会从零个可用节点开始,如果集群为空,则缩减至零个节点以避免集群中有未使用的计算资源。在具有零个节点的集群中部署工作负载会触发纵向扩容事件。
如果您遇到这种情况,则 Autopilot 会按预期运行,无需执行任何操作。新节点启动后,您的工作负载将按预期部署。
检查您的 Pod 是否正在等待新节点:
描述待处理 Pod:
kubectl describe pod POD_NAME
将
POD_NAME
替换为待处理 Pod 的名称。检查输出的
Events
部分。如果 Pod 正在等待新节点,则输出类似于以下内容:Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 11s gke.io/optimize-utilization-scheduler no nodes available to schedule pods Normal TriggeredScaleUp 4s cluster-autoscaler pod triggered scale-up: [{https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-9293c6db-grp 0->1 (max: 1000)} {https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-d99371e7-grp 0->1 (max: 1000)}]
TriggeredScaleUp
事件显示您的集群正在从零个节点纵向扩容到运行已部署的工作负载所需的节点数量。
尝试从 GKE Autopilot 中的 Pod 运行 tcpdump 时与权限相关的错误
禁止访问 GKE Autopilot 集群中的底层节点。因此,需要在 Pod 中运行 tcpdump
实用程序,然后使用 kubectl cp 命令进行复制。如果您通常从 GKE Autopilot 集群的 Pod 中运行 tcpdump 实用程序,则可能会看到以下错误:
tcpdump: eth0: You don't have permission to perform this capture on that device
(socket: Operation not permitted)
这是因为默认情况下,GKE Autopilot 会将丢弃 NET_RAW
功能的安全上下文应用于所有 Pod,以缓解潜在漏洞。例如:
apiVersion: v1
kind: Pod
metadata:
labels:
app: tcpdump
name: tcpdump
spec:
containers:
- image: nginx
name: nginx
resources:
limits:
cpu: 500m
ephemeral-storage: 1Gi
memory: 2Gi
requests:
cpu: 500m
ephemeral-storage: 1Gi
memory: 2Gi
securityContext:
capabilities:
drop:
- NET_RAW
作为解决方案,如果您的工作负载需要 NET_RAW
功能,则可以重新启用它:
将
NET_RAW
功能添加到 Pod 的 YAML 规范的securityContext
部分:securityContext: capabilities: add: - NET_RAW
从 Pod 中运行
tcpdump
:tcpdump port 53 -w packetcap.pcap tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
使用
kubectl cp
命令将其复制到本地机器以供进一步分析:kubectl cp POD_NAME:/PATH_TO_FILE/FILE_NAME/PATH_TO_FILE/FILE_NAME
使用
kubectl exec
运行tcpdump
命令以执行网络数据包捕获并重定向输出:kubectl exec -it POD_NAME -- bash -c "tcpdump port 53 -w -" > packet-new.pcap