排查节点注册问题


本文档介绍了如何解决向 Google Kubernetes Engine (GKE) Standard 集群添加节点时遇到的问题。发生这些问题的一些场景包括集群创建和节点池创建,以及扩容事件期间。

如需解决 GKE Autopilot 集群的问题,请参阅排查 Autopilot 集群问题

如果您需要其他帮助,请与 Cloud Customer Care 联系。

节点注册简介

节点是 GKE 代表您创建的 Compute Engine 虚拟机实例。在新节点添加到 GKE 集群后,必须向集群的控制平面进行注册。此过程称为节点注册或节点引导,在创建节点时发生。

何时发生节点注册

每当创建节点时都会发生节点注册,包括以下场景:

节点注册过程遵循以下步骤:

  1. 为节点池设置的节点数复制到代管式实例组 (MIG)。
  2. MIG 创建所需数量的虚拟机实例。
  3. 对于创建的每个虚拟机实例:

    1. 虚拟机实例启动。
    2. 虚拟机实例配置和安装必要的软件包,以作为 Kubernetes 节点运行。
    3. 现已在虚拟机实例上运行的 kubelet 与控制平面的 API 服务器进行通信,以注册为节点。

节点注册错误消息

当 GKE 尝试向集群添加节点时,如果节点注册失败,Google Cloud 控制台中会显示以下错误:

  All cluster resources were brought up, but: only 0 nodes out of * have
  registered; this is likely due to the Nodes failing to start correctly; try
  re-creating the cluster or contact support if that doesn't work.

此错误消息表示节点未成功向集群注册。以下部分介绍了此错误的一些可能原因。

成功注册节点的前提条件

向 GKE 集群成功注册节点取决于如下因素:

  • 网络连接。
  • 资源可用性。
  • 服务账号权限。

实例创建的前提条件

当 GKE 为集群创建节点时,第一步是创建新的 Compute Engine 虚拟机实例。

实例创建可能会因以下原因之一而失败:

实例创建失败意味着,在 GKE 尝试创建实例以注册为 GKE 节点的时间范围内,由于从未创建实例,因此缺少实例创建日志。如需检查是否缺少日志,请参阅查找节点注册失败的实例中的说明。

服务账号权限

GKE 节点具有与其关联的 IAM 服务账号。默认情况下,此服务账号是 Compute Engine 默认服务账号。我们建议您使用具有所需的最低权限的自定义 IAM 服务账号强化集群的安全性。

此服务账号需要拥有正确的权限,虚拟机实例才能初始化为 GKE 节点。如果您删除服务账号、停用服务账号或没有为其提供正确的权限,则节点注册可能会失败。

与 Google API 和服务的网络连接的前提条件

虚拟机实例会下载软件包以准备作为 GKE 节点运行,连接超时可能意味着您的集群未满足连接到 Google API 和服务(例如 storage.googleapis.com)所需的网络要求。如果实例无法连接到这些服务,则无法下载 Kubernetes 发行版并完成节点注册过程。

根据您的网络连接,允许此连接可能意味着配置专用 Google 访问通道,或者在允许此连接的集群 Virtual Private Cloud (VPC) 网络中设置防火墙规则路由

与控制平面的网络连接的前提条件

控制平面与节点之间的连接对于节点注册和常规功能至关重要。这种通信是默认允许的。 确保在设置 VPC 防火墙规则后,节点与控制平面之间仍可进行通信。

如需了解详情,请参阅允许控制平面连接

使用节点注册检查工具排查节点注册问题

对于在 GKE 1.24.0-gke.100 版或更高版本上创建的节点池,名为节点注册检查工具的实用程序会在新创建的实例上运行,并检查该实例是否已成功完成节点注册步骤。

当节点注册失败时,该实用程序会生成摘要报告,您可以在其中根据实例是在该过程的哪个环节失败来查看未满足的前提条件。

请按照以下部分中的说明查找节点注册失败的实例,并使用节点注册检查工具摘要了解失败的原因。

如果您无法在节点池中使用节点注册检查工具,请参阅在不使用节点注册检查工具的情况下排查节点注册问题

查找节点注册失败的实例

当一个或多个实例向 GKE 集群的控制平面注册为节点失败时,您可以从 Google Cloud 控制台的集群详情页面中显示的错误消息查看失败的实例数。如果多个实例同时注册失败,则根本原因可能相同。因此,您可以使用其中一个失败的实例来调查所有实例失败的原因。

但是,由于实例未注册为 GKE 节点,因此您必须按照以下说明查找注册失败的底层 Compute Engine 虚拟机的名称。

  1. 在 Google Cloud 控制台中,进入日志浏览器页面:

    进入日志浏览器

  2. 使用以下日志过滤条件查找虚拟机实例创建日志:

    resource.type="gce_instance"
    logName="projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Factivity"
    protoPayload.requestMetadata.callerSuppliedUserAgent="GCE Managed Instance Group for GKE"
    protoPayload.response.status="RUNNING"
    

    PROJECT_ID 替换为您的集群的项目 ID。

  3. 使用日志过滤条件下方的直方图,将时间范围缩小到应创建节点的时间。

  4. 点击查询结果下显示的一个日志,然后点击展开嵌套字段以显示详情。

  5. 找到 protoPayload.resourceName 字段。此处列出的路径的最后一部分是实例名称。实例名称遵循以集群名称和节点池名称开头的格式,例如:

    gke-cluster-1-default-pool-b0ac62d3-9g1vgke-cluster-1default-pool 节点池的实例。

  6. 在 Google Cloud 控制台中,进入 Compute Engine 虚拟机实例页面:

    进入“虚拟机实例”

    使用过滤条件查找虚拟机实例的名称。点击可了解详情。

使用节点注册检查工具排查实例问题

找到注册失败的实例的名称后,您可以使用节点注册检查程序调查失败的原因。

在虚拟机实例的详细信息标签页的日志部分中,点击串行端口 1(控制台)

对于在 GKE 1.24.0-gke.100 版或更高版本上创建的节点池,新创建的实例的输出包含以下内容,表明节点注册检查工具已启动:

** Starting Node Registration Checker **
** Loading variables from kube-env **
** Sleeping for 7m to allow registration to complete  **

如果节点注册成功,则输出包含以下消息:

** Node ready and registered. **
** Completed running Node Registration Checker **

如果您没有看到这些消息,则表示节点注册失败,并且节点注册检查工具会生成报告,总结注册失败的原因。查找以下附加消息以查看摘要:

** Here is a summary of the checks performed: **

在此消息下方,查找如下所示的表:

------------------------------
Service    DNS      Reachable
------------------------------
LOGGING    true     true
GCR        true     true
GCS        true     true
Master     N/A      false
------------------------------

如果 LOGGINGGCRGCS 列为无法访问,请针对节点注册检查服务账号权限针对节点注册检查与 Google API 和服务的网络连接

如果 Master 列为无法访问,请针对节点注册检查与控制平面的网络连接的前提条件

在解决阻止成功注册节点的所有问题后,请参阅修复根本原因后完成节点注册

如果上述步骤未说明节点注册失败的原因,请参阅收集信息以进一步调查

在不使用节点注册检查工具的情况下排查节点注册问题

如果节点注册在 1.24.0-gke.100 之前的 GKE 版本上创建的节点池中失败,您只能手动排查节点注册问题。如果节点池是在 GKE 1.24.0-gke.100 版或更高版本上创建的,请按照使用节点注册检查工具排查节点注册问题中的说明操作。

在解决导致节点注册失败的所有问题后,请按照以下说明在修复根本原因后完成节点注册

如果本页面上的调查步骤都未说明节点注册失败的原因,请参阅收集信息以进一步调查

针对节点注册检查服务账号权限

您的节点使用的服务账号必须具有节点注册的必备权限。请按照以下说明检查您是否满足这些前提条件:

  1. 查找节点注册失败的实例

  2. 在虚拟机实例的详细信息标签页的 API 和身份管理部分中,找到服务账号字段中的服务账号名称。如果节点使用 Compute Engine 默认服务账号,则该名称遵循 PROJECT_NUMBER-compute@developer.gserviceaccount.com 格式。此服务账号必须具有所需的最低权限

  3. 检查串行控制台输出中是否表明注册成功。在虚拟机实例的详细信息标签页的日志部分中,点击串行端口 1(控制台)

    如果实例使用了具有正确权限的服务账号,则输出包含以下内容:

    • Started Download and install k8s binaries and configurations
    • Started Docker Application Container Engine.
    • Started Configure kubernetes node.
    • Reached target Kubernetes.

    这些消息位于此输出中的不同位置。可能还有时间戳或其他工件中断这些消息,例如:Starting [0;1;39mConfigure kubernetes node。如果您看到上述所有消息,则表明已满足服务账号前提条件。

    如果您没有看到这些消息,则表示分配给虚拟机实例的服务账号可能被删除、停用或没有正确的权限

针对节点注册检查与 Google API 和服务的网络连接

使用 SSH 访问权限检查连接

如果您在项目中拥有对虚拟机实例的 SSH 访问权限,则还可以检查虚拟机实例是否与 Google API 和服务建立网络连接。

  1. 查找节点注册失败的实例

  2. 在虚拟机实例的详细信息标签页中,点击 SSH

  3. 在连接到虚拟机实例对应的命令行后,请运行以下命令以检查是否与 Google API 和服务连接:

    curl -m 5 -v https://storage.googleapis.com/generate_204
    

    如果连接成功,则输出类似于以下内容:

    *   Trying 142.250.148.128:443...
    * Connected to storage.googleapis.com (142.250.148.128) port 443 (#0)
    
    ...
    
    < HTTP/1.1 204 No Content
    < Content-Length: 0
    < Cross-Origin-Resource-Policy: cross-origin
    < Date: Wed, 04 Jan 2023 00:58:41 GMT
    <
    * Connection #0 to host storage.googleapis.com left intact
    

    如果连接不成功,则输出类似于以下内容:

    *   Trying 142.250.148.128:443...
    * Connection timed out after 5000 milliseconds
    * Closing connection 0
    curl: (28) Connection timed out after 5000 milliseconds```
    

    如果连接超时且返回的 IP 地址在 199.36.153.0/24 IP 地址范围内,请检查您的集群是否满足连接到 Google API 和服务的网络要求。如果连接超时且返回的 IP 地址不在所述的 IP 地址范围内,请检查防火墙规则是否阻止了集群的 VPC 网络中的传出流量或配置错误的路由

    保持与虚拟机实例的 SSH 连接处于打开状态,然后继续执行下一部分的操作。

在没有 SSH 访问权限的情况下使用 Connectivity Tests 检查连接

如果您没有对虚拟机实例的 SSH 访问权限,请使用 Connectivity Tests 检查虚拟机实例是否与 Google API 和服务建立连接。

  1. 查找节点注册失败的实例

  2. 创建并运行 Connectivity Tests,将虚拟机实例作为来源,将 storage.googleapis.com TCP/443 作为目的地

    使用测试结果来检查集群的网络配置。

针对节点注册检查与控制平面的网络连接

如果您在项目中拥有对虚拟机实例的 SSH 访问权限,则可以检查虚拟机实例是否与集群的控制平面建立网络连接。

  1. 查找节点注册失败的实例

  2. 在虚拟机实例的详细信息标签页中,点击 SSH

  3. 在连接到虚拟机实例对应的命令行后,请将集群的控制平面端点保存为环境变量:

    source <(sudo grep KUBERNETES_MASTER_NAME /home/kubernetes/kube-env)
    
  4. 向控制平面端点发送 GET 请求:

    curl -k -m 5  https://${KUBERNETES_MASTER_NAME}/version
    

    如果输出类似于以下内容,则虚拟机实例可以与控制平面建立连接:

    {
    "major": "1",
    "minor": "24",
    "gitVersion": "v1.24.7-gke.900",
    "gitCommit": "e35c4457f66187eff006dda6d2c0fe12144ef2ec",
    "gitTreeState": "clean",
    "buildDate": "2022-10-26T09:25:34Z",
    "goVersion": "go1.18.7b7",
    "compiler": "gc",
    "platform": "linux/amd64"
    }
    

    如果输出类似于以下内容,则虚拟机实例无法与控制平面建立连接:

    curl: (28) Connection timed out after 5000 milliseconds
    

如果虚拟机实例无法与控制平面建立连接,请参阅 GKE 网络最佳实践中有关允许控制平面连接的部分。

修复根本原因后完成节点注册

在解决阻止节点注册的问题后,如何继续操作取决于失败的上下文:

  • 如果节点注册在创建集群时失败,请删除集群并重试。
  • 如果节点注册在使用集群自动扩缩器进行扩容期间失败,请等待虚拟机实例再次尝试注册。
  • 如果节点注册在创建节点池时失败:
    • 如果虚拟机实例已创建,请等待虚拟机实例再次尝试注册。
    • 如果虚拟机实例未创建,请删除节点池,然后重试。
  • 如果节点注册在调整集群大小时失败,请重新运行相应命令以增加集群大小
  • 如果节点注册在操作范围之外(例如在修复操作期间)失败,请等待虚拟机实例再次尝试注册。

收集信息以进一步调查

如果您无法解决节点注册问题,您可以收集更多信息,以帮助 Cloud Customer Care 按照以下说明进行调查。以下步骤需要您在项目中拥有对虚拟机实例的 SSH 访问权限,并使用 COS 映像中包含的 sosreport 实用程序。

  1. 查找节点注册失败的实例

  2. 使用 sosreport 收集调试信息

    或者,如果您的节点未下载 sosreport 实用程序并且无法安装,请运行以下命令来手动收集调试信息:

    sudo journalctl -u cloud-init-local
    sudo journalctl -u cloud-init
    sudo journalctl -u cloud-final
    sudo journalctl -u cloud-config
    systemctl status kubelet
    journalctl -u kubelet
    systemctl status kube-node-installation.service
    systemctl status kube-node-configuration.service
    journalctl -u kube-node-installation.service --no-pager
    journalctl -u kube-node-configuration.service --no-pager
    journalctl -u kubelet.service --no-pager
    
  3. 将此信息打包为 zip 文件,并在向 Cloud Customer Care 提交支持请求时添加此信息。

后续步骤

如果您需要其他帮助,请与 Cloud Customer Care 联系。