诊断集群问题

本文档介绍如何使用 gkectl diagnose 诊断集群中的问题。

概览

gkectl 工具有两个用于排查集群问题的命令:gkectl diagnose clustergkectl diagnose snapshot。这两个命令适用于管理员集群和用户集群。

gkectl diagnose cluster

对集群执行健康检查并报告错误。对以下组件运行健康检查:

  • VCenter
    • 凭据
    • DRS
    • 反亲和性群组
    • 网络
    • 版本
    • 数据中心
    • 数据存储区
    • 资源池
    • 文件夹
    • 网络
  • 负载平衡器(F5、Seesaw、手动)
  • 用户集群和节点池
  • 集群对象
  • 机器对象和相应的集群节点
  • kube-system 和 gke-system 命名空间中的 Pod
  • 用户控制层面(如果目标集群是用户集群)
  • 集群中的 vSphere 永久卷
  • 用户和管理员集群的 vCPU(虚拟 CPU)和内存争用信号
  • 用户和管理员集群 ESXi 预配置主机 CPU 使用率和内存用量警报
  • 时段 (TOD)
  • 启用了 Dataplane V2 的集群的节点网络政策

gkectl diagnose snapshot

将集群的状态、配置和日志压缩成 tarball 文件。具体而言,该命令的默认配置会捕获有关集群的以下信息:

  • Kubernetes 版本

  • kubenetes 资源在 kube-system 和 gke-system 命名空间中的状态:集群、机器、节点、服务、端点、ConfigMap、ReplicaSet、CronJob、Pod 以及这些 Pod 的所有者,包括 Deployment、DaemonSet 和 StatefulSet

  • 如果目标集群是用户集群(用户集群的控制层面在管理员集群中运行),则为用户控制层面的状态

  • 有关每个节点配置的详细信息,包括 IP 地址、iptables 规则、装载点、文件系统、网络连接,以及正在运行的进程

  • 管理员集群的控制层面节点的容器日志(当 Kubernetes API 服务器不可用时)

  • vSphere 信息,包括虚拟机对象及其基于资源池的事件。与虚拟机关联的数据中心、集群、网络和 Datastore 对象

  • F5 BIG-IP 负载平衡器信息,包括虚拟服务器、虚拟地址、池、节点和监控器

  • 来自 gkectl diagnose snapshot 命令的日志

  • 快照中所有文件的 HTML 索引文件

  • (可选)用于安装和升级集群的集群配置文件

在创建 tarball 之前,将移除凭据(包括 vSphere 和 F5 凭据)。

诊断集群

您可以运行 gke diagnose cluster 来查找集群的常见问题。

gkectl diagnose cluster --kubeconfig ADMIN_CLUSTER_KUBECONFIG --config ADMIN_CLUSTER_CONFIG

输出示例:

Failed to access the api server via LB VIP "...": ...
Try to use the admin master IP instead of problematic VIP...
Reading config with version "[CONFIG_VERSION]"
Finding the admin master VM...
Fetching the VMs in the resource pool "[RESOURCE_POOL_NAME]"...
Found the "[ADMIN_MASTER_VM_NAME]" is the admin master VM.
Diagnosing admin|user cluster "[TARGET_CLUSTER_NAME]"...
...

诊断管理员集群

您可以通过传递名称或仅传递 kubeconfig 来诊断管理员集群。

使用管理员集群 kubeconfig

传入管理员集群的 kubeconfig 会导致 gkectl 自动选择管理员集群:

gkectl diagnose cluster --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG]

使用管理员集群名称

要获取管理员集群的名称,请运行以下命令:

kubectl get cluster --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG]

然后,将管理员集群名称传入到 gkectl diagnose cluster

gkectl diagnose cluster --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--cluster-name=[ADMIN_CLUSTER_NAME]

如果您的管理员集群正常运行,gkectl diagnose cluster 将返回类似于以下内容的输出:

Preparing for the diagnose tool...
Diagnosing the cluster......DONE

- Validation Category: Admin Cluster Connectivity
Checking VMs TOD (availability)...SUCCESS

- Validation Category: Admin Cluster F5 BIG-IP
Checking f5 (credentials, partition)...SUCCESS

- Validation Category: Admin Cluster VCenter
Checking Credentials...SUCCESS
Checking DRS enabled...SUCCESS
Checking Hosts for AntiAffinityGroups...SUCCESS
Checking Version...SUCCESS
Checking Datacenter...SUCCESS
Checking Datastore...SUCCESS
Checking Resource pool...SUCCESS
Checking Folder...SUCCESS
Checking Network...SUCCESS

- Validation Category: Admin Cluster
Checking cluster object...SUCCESS
Checking machine deployment...SUCCESS
Checking machineset...SUCCESS
Checking machine objects...SUCCESS
Checking kube-system pods...SUCCESS
Checking anthos-identity-service pods...SUCCESS
Checking storage...SUCCESS
Checking resource...SUCCESS
Checking virtual machine resource contention...SUCCESS
Checking host resource contention...SUCCESS
All validation results were SUCCESS.
Cluster is healthy!

诊断用户集群

要诊断集群,请先获取用户集群的名称:

kubectl get cluster --kubeconfig=[USER_CLUSTER_KUBECONFIG]

接着传入管理员集群的 Kubeconfig 和用户集群的名称:

gkectl diagnose cluster --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
  --cluster-name=[USER_CLUSTER_NAME]

如果您的用户集群正常运行,gkectl diagnose cluster 将返回类似于以下内容的输出:

Preparing for the diagnose tool...
Diagnosing the cluster......DONE

Diagnose result is saved successfully in 

- Validation Category: User Cluster Connectivity
Checking Node Network Policy...SUCCESS
Checking VMs TOD (availability)...SUCCESS

- Validation Category: User Cluster F5 BIG-IP
Checking f5 (credentials, partition)...SUCCESS

- Validation Category: User Cluster VCenter
Checking Credentials...SUCCESS
Checking DRS enabled...SUCCESS
Checking Hosts for AntiAffinityGroups...SUCCESS
Checking VSphere CSI Driver...SUCCESS
Checking Version...SUCCESS
Checking Datacenter...SUCCESS
Checking Datastore...SUCCESS
Checking Resource pool...SUCCESS
Checking Folder...SUCCESS
Checking Network...SUCCESS

- Validation Category: User Cluster
Checking user cluster and node pools...SUCCESS
Checking cluster object...SUCCESS
Checking machine deployment...SUCCESS
Checking machineset...SUCCESS
Checking machine objects...SUCCESS
Checking control plane pods...SUCCESS
Checking kube-system pods...SUCCESS
Checking gke-system pods...SUCCESS
Checking gke-connect pods...SUCCESS
Checking anthos-identity-service pods...SUCCESS
Checking storage...SUCCESS
Checking resource...SUCCESS
Checking virtual machine resource contention...SUCCESS
Checking host resource contention...SUCCESS
All validation results were SUCCESS.
Cluster is healthy!

排查诊断出的集群问题

运行 gke diagnose cluster 命令时,如果您遇到以下问题,请考虑以下解决方法。

.
问题可能的原因解决方法
管理员集群或用户集群无法连接到 Kubernetes API 服务器。 检查虚拟机运行状况 OOB(开箱)内存延迟图表,理想情况下内存延迟时间应接近零。内存争用也会增加 CPU 争用,CPU 就绪情况图表可能会出现峰值,因为会执行交换。 增大物理内存。如需了解其他选项,请参阅 VMware 问题排查建议
创建 Nodepool 时超时。 VMDK 的读/写延迟时间较长。检查虚拟机运行状况 OOB 以了解是否存在虚拟磁盘读写延迟。根据 VMware 报道,总延迟时间超过 20 毫秒表示存在问题。 请参阅磁盘性能问题的 VMware 解决方案

捕获集群状态

如果 gkectl diagnose cluster 发现错误,您应该捕获集群的状态并将信息提供给 Google。您可以使用 gkectl diagnose snapshot 命令执行此操作。

gkectl diagnose snapshot 有一个可选标志 --config。除了收集有关集群的信息之外,此标志还收集用于创建或升级集群的 Anthos Clusters on VMware 配置文件。

捕获管理员集群状态

要捕获管理员集群的状态,请运行以下命令,其中 --config 是可选的:

gkectl diagnose snapshot --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] [--config]

输出包括文件列表和 tarball 文件的名称:

Taking snapshot of admin cluster "[ADMIN_CLUSTER_NAME]"...
   Using default snapshot configuration...
   Setting up "[ADMIN_CLUSTER_NAME]" ssh key file...DONE
   Taking snapshots...
       commands/kubectl_get_pods_-o_yaml_--kubeconfig_...env.default.kubeconfig_--namespace_kube-system
       commands/kubectl_get_deployments_-o_yaml_--kubeconfig_...env.default.kubeconfig_--namespace_kube-system
       commands/kubectl_get_daemonsets_-o_yaml_--kubeconfig_...env.default.kubeconfig_--namespace_kube-system
       ...
       nodes/[ADMIN_CLUSTER_NODE]/commands/journalctl_-u_kubelet
       nodes/[ADMIN_CLUSTER_NODE]/files/var/log/startup.log
       ...
   Snapshot succeeded. Output saved in [TARBALL_FILE_NAME].tar.gz.

要将 tarball 文件解压到目录中,请运行以下命令:

tar -zxf [TARBALL_FILE_NAME] --directory [EXTRACTION_DIRECTORY_NAME]

要查看快照生成的文件列表,请运行以下命令:

cd [EXTRACTION_DIRECTORY_NAME]/[EXTRACTED_SNAPSHOT_DIRECTORY]
ls kubectlCommands
ls nodes/[NODE_NAME]/commands
ls nodes/[NODE_NAME]/files

要查看特定操作的详细信息,请打开其中一个文件。

指定管理员集群的 SSH 密钥

获取管理员集群的快照时,gkectl 会自动查找管理员集群的私有 SSH 密钥。您还可以使用 --admin-ssh-key-path 参数显式指定密钥。

按照使用 SSH 连接到集群节点中的说明下载 SSH 密钥。

然后在 gkectl diagnose snapshot 命令中,将 --admin-ssh-key-path 设置为已解码的密钥文件路径:

gkectl diagnose snapshot --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--admin-ssh-key-path=[PATH_TO_DECODED_KEY]

捕获用户集群状态

要捕获用户集群的状态,请运行以下命令:

gkectl diagnose snapshot --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--cluster-name=[USER_CLUSTER_NAME]

输出包括文件列表和 tarball 文件的名称:

Taking snapshot of user cluster "[USER_CLUSTER_NAME]"...
Using default snapshot configuration...
Setting up "[USER_CLUSTER_NAME]" ssh key file...DONE
    commands/kubectl_get_pods_-o_yaml_--kubeconfig_...env.default.kubeconfig_--namespace_user
    commands/kubectl_get_deployments_-o_yaml_--kubeconfig_...env.default.kubeconfig_--namespace_user
    commands/kubectl_get_daemonsets_-o_yaml_--kubeconfig_...env.default.kubeconfig_--namespace_user
    ...
    commands/kubectl_get_pods_-o_yaml_--kubeconfig_.tmp.user-kubeconfig-851213064_--namespace_kube-system
    commands/kubectl_get_deployments_-o_yaml_--kubeconfig_.tmp.user-kubeconfig-851213064_--namespace_kube-system
    commands/kubectl_get_daemonsets_-o_yaml_--kubeconfig_.tmp.user-kubeconfig-851213064_--namespace_kube-system
    ...
    nodes/[USER_CLUSTER_NODE]/commands/journalctl_-u_kubelet
    nodes/[USER_CLUSTER_NODE]/files/var/log/startup.log
    ...
Snapshot succeeded. Output saved in [FILENAME].tar.gz.

快照场景

gkectl diagnose snapshot 命令支持四种场景。要指定场景,请使用 --scenario 标志。以下列表显示了可能的值:

  • system:(默认)收集系统命名空间 kube-systemgke-system 的快照。

  • system-with-logs:收集包含日志的 system 快照。

  • all:收集所有命名空间的快照。

  • all-with-logs:收集包含日志的 all 快照。

管理员集群或用户集群可以使用四种场景中的每一个,因此有八种可能的排列。以下示例展示了一些可能性。

要使用 system 场景创建管理员集群的快照,请执行以下操作:

gkectl diagnose snapshot \
--kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--scenario=system

要使用 system-with-logs 场景创建用户集群的快照,请执行以下操作:

gkectl diagnose snapshot \
--kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--cluster-name=[USER_CLUSTER_NAME] \
--scenario=system-with-logs

要使用 all 场景创建用户集群的快照,请执行以下操作:

gkectl diagnose snapshot \
--kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--cluster-name=[USER_CLUSTER_NAME] \
--scenario=all

要使用 all-with-logs 场景创建管理员集群的快照,请执行以下操作:

gkectl diagnose snapshot \
--kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--scenario=all-with-logs

使用 --log-since 来限制快照

system-with-logsall-with-logs 场景中,您可以使用 --log-since 标志将日志收集限制为最近的时间段。例如,您可以仅收集过去两天或过去三小时的日志。默认情况下,diagnose snapshot 会收集所有日志。

要限制日志收集的时间段,请执行以下操作:

gkectl diagnose snapshot --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--cluster-name=[CLUSTER_NAME] \
--scenario=system-with-logs \
--log-since=[DURATION]

[DURATION] 替换为时间值,如 120m48h

注意:

  • kubectljournalctl 日志支持 --log-since 标志。
  • 自定义快照配置中不允许使用 --log-since 等命令标志。

对快照执行试运行

您可以使用 --dry-run 标志来显示要执行的操作和快照配置。

要在管理员集群上执行试运行,请输入以下命令:

gkectl diagnose snapshot --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--cluster-name=[ADMIN_CLUSTER_NAME] \
--dry-run

要在用户集群上执行试运行,请输入以下命令:

gkectl diagnose snapshot --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--cluster-name=[USER_CLUSTER_NAME] \
--dry-run

使用快照配置

如果这四种场景都不能满足您的需求,您可以使用 --snapshot-config 标志传入快照配置文件来创建自定义快照:

gkectl diagnose snapshot --kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--cluster-name=[USER_CLUSTER_NAME] \
--snapshot-config=[SNAPSHOT_CONFIG_FILE]

生成快照配置

您可以通过传入 --scenario--dry-run 标志为给定场景生成快照配置。例如,要查看用户集群的默认场景 (system) 的快照配置,请输入以下命令:

gkectl diagnose snapshot \
--kubeconfig=[ADMIN_CLUSTER_KUBECONFIG] \
--cluster-name=[USER_CLUSTER_NAME] \
--scenario=system
--dry-run

输出类似于以下内容:

numOfParallelThreads: 10
excludeWords:
- password
kubectlCommands:
- commands:
  - kubectl get clusters -o wide
  - kubectl get machines -o wide
  - kubectl get clusters -o yaml
  - kubectl get machines -o yaml
  - kubectl describe clusters
  - kubectl describe machines
  namespaces:
  - default
- commands:
  - kubectl version
  - kubectl cluster-info
  - kubectl get nodes -o wide
  - kubectl get nodes -o yaml
  - kubectl describe nodes
  namespaces: []
- commands:
  - kubectl get pods -o wide
  - kubectl get deployments -o wide
  - kubectl get daemonsets -o wide
  - kubectl get statefulsets -o wide
  - kubectl get replicasets -o wide
  - kubectl get services -o wide
  - kubectl get jobs -o wide
  - kubectl get cronjobs -o wide
  - kubectl get endpoints -o wide
  - kubectl get configmaps -o wide
  - kubectl get pods -o yaml
  - kubectl get deployments -o yaml
  - kubectl get daemonsets -o yaml
  - kubectl get statefulsets -o yaml
  - kubectl get replicasets -o yaml
  - kubectl get services -o yaml
  - kubectl get jobs -o yaml
  - kubectl get cronjobs -o yaml
  - kubectl get endpoints -o yaml
  - kubectl get configmaps -o yaml
  - kubectl describe pods
  - kubectl describe deployments
  - kubectl describe daemonsets
  - kubectl describe statefulsets
  - kubectl describe replicasets
  - kubectl describe services
  - kubectl describe jobs
  - kubectl describe cronjobs
  - kubectl describe endpoints
  - kubectl describe configmaps
  namespaces:
  - kube-system
  - gke-system
  - gke-connect.*
prometheusRequests: []
nodeCommands:
- nodes: []
  commands:
  - uptime
  - df --all --inodes
  - ip addr
  - sudo iptables-save --counters
  - mount
  - ip route list table all
  - top -bn1
  - sudo docker ps -a
  - ps -edF
  - ps -eo pid,tid,ppid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm,args,cgroup
  - sudo conntrack --count
nodeFiles:
- nodes: []
  files:
  - /proc/sys/fs/file-nr
  - /proc/sys/net/nf_conntrack_max
seesawCommands: []
seesawFiles: []
nodeCollectors:
- nodes: []
f5:
  enabled: true
vCenter:
  enabled: true
  • numOfParallelThreads:用于截取快照的并行线程数。

  • excludeWords:要从快照中排除的字词列表(不区分大小写)。系统会从快照结果中移除包含这些字词的行。无论您是否指定“password”,都始终会将其排除。

  • kubectlCommands:要运行的 kubectl 命令列表。系统会保存结果。这些命令将针对相应的命名空间运行。对于 kubectl logs 命令,系统会自动添加相应命名空间中的所有 Pod 和容器。支持使用正则表达式指定命名空间。如果未指定命名空间,则假定为 default 命名空间。

  • nodeCommands:要在相应节点上运行的命令列表。系统会保存结果。未指定节点时,将考虑目标集群中的所有节点。

  • nodeFiles:要从相应节点收集的文件列表。系统会保存这些文件。未指定节点时,将考虑目标集群中的所有节点。

  • seesawCommands:要运行以收集 Seesaw 负载平衡器信息的命令列表。如果集群使用 Seesaw 负载平衡器,则会保存结果。

  • seesawFiles:要为 Seesaw 负载平衡器收集的文件列表。

  • nodeCollectors:为 Cilium 节点运行以收集 eBPF 信息的收集器。

  • f5:此标志用于启用收集与 F5 BIG-IP 负载平衡器相关的信息。

  • vCenter:此标志用于启用收集与 vCenter 相关的信息。

  • prometheusRequests:Prometheus 请求列表。系统会保存结果。

将快照上传到 Google Cloud Storage 存储桶

为了更轻松地保存、分析和存储,您可以将特定用户集群的所有快照上传到 Google Cloud Storage 存储桶。如果您需要 Google Cloud 支持团队的帮助,此功能尤为有用。

在运行该命令之前,请确保已满足这些设置要求。

  • 连接项目中启用 storage.googleapis.com。虽然您可以使用其他项目,但建议您使用连接项目。
gcloud services enable --project=FLEET_HOST_PROJECT_ID \
storage.googleapis.com
  • roles/storage.admin 授予其父项目的服务账号,并使用 --service-account-key-file 参数传入服务账号 json 密钥文件。您可以使用任何服务账号,但建议使用连接注册服务账号。如需了解详情,请参阅服务账号
gcloud projects add-iam-policy-binding FLEET_HOST_PROJECT_ID \
    --member "serviceAccount:CONNECT_REGISTER_SERVICE_ACCOUNT" \
    --role "roles/storage.admin"

满足这些要求后,您现在可以使用以下命令上传快照:

gkectl diagnose snapshot --kubeconfig=ADMIN_CLUSTER_KUBECONFIG \
--cluster-name CLUSTER_NAME \
--upload-to BUCKET_NAME  \
--service-account-key-file SERVICE_ACCOUNT_KEY_FILE

SERVICE_ACCOUNT_KEY_FILE 替换为服务账号密钥文件名。

输出示例:

Using "system" snapshot configuration...
Taking snapshot of user cluster CLUSTER_NAME...
Setting up CLUSTER_NAME ssh key...DONE
Using the gke-connect register service account key...
Setting up Google Cloud Storage bucket for uploading the snapshot...DONE
Taking snapshots in 10 thread(s)...
   ...
Snapshot succeeded.
Snapshots saved in "SNAPSHOT_FILE_PATH".
Uploading snapshot to Google Cloud Storage......  DONE
Uploaded the snapshot successfully to gs://BUCKET_NAME/CLUSTER_NAME/SNAPSHOT_FILE_NAME.

已知问题

版本 1.1.2-gke.0:路径解析为多个数据中心

请参阅 Anthos Clusters on VMware 版本说明

版本 1.1.x:未将卷挂接到机器

请参阅 Anthos Clusters on VMware 版本说明