本页面介绍了如何解决与安装或升级 Google Distributed Cloud 集群相关的问题。
安装问题
以下部分可能会帮助您排查与安装 Google Distributed Cloud 相关的问题。
暂时性错误消息
Google Distributed Cloud 的安装过程是一个持续的协调循环。因此,在安装时,您可能会在日志中看到暂时性错误消息。
只要安装成功,您就可以放心地忽略这些错误。下面列出了典型的暂时性错误日志消息:
  Internal error occurred: failed calling webhook "webhook.cert-manager.io": Post
  https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s:
  dial tcp IP_ADDRESS:443: connect: connection refused
  Internal error occurred: failed calling webhook "vcluster.kb.io": Post
  https://webhook-service.kube-system.svc:443/validate-baremetal-cluster-gke-io-v1-cluster?timeout=30s:
  dial tcp IP_ADDRESS:443: connect: connection refused
  Failed to register cluster with GKE Hub; gcloud output: error running command
  'gcloud container fleet memberships register CLUSTER_NAME  --verbosity=error --quiet':
  error: exit status 1, stderr: 'ERROR: (gcloud.container.hub.memberships.register)
  Failed to check if the user is a cluster-admin: Unable to connect to the server: EOF
  Get
  https://127.0.0.1:34483/apis/infrastructure.baremetal.cluster.gke.io/v1/namespaces/cluster-
  cluster1/baremetalmachines: dial tcp 127.0.0.1:34483: connect: connection refused"
  Create Kind Cluster "msg"="apply run failed" "error"="unable to recognize \"/tmp/kout088683152\": no matches for kind \"NetworkLogging\" in version \"networking.gke.io/v1alpha1\""
  Create Kind Cluster "msg"="apply run failed" "error"="unable to recognize \"/tmp/kout869681888\": no matches for kind \"Provider\" in version \"clusterctl.cluster.x-k8s.io/v1alpha3\""
如果您的 Google Cloud 服务账号密钥已过期,您会看到来自 bmctl 的以下错误消息:
Error validating cluster config: 3 errors occurred:
        * GKEConnect check failed: Get https://gkehub.googleapis.com/v1beta1/projects/project/locations/global/memberships/admin: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}
        * ClusterOperations check failed: Post https://cloudresourcemanager.googleapis.com/v1/projects/project:testIamPermissions?alt=json&prettyPrint=false: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}
        * GCR pull permission for bucket: artifacts.anthos-baremetal-release.appspot.com failed: Get https://storage.googleapis.com/storage/v1/b/artifacts.anthos-baremetal-release.appspot.com/iam/testPermissions?alt=json&permissions=storage.objects.get&permissions=storage.objects.list&prettyPrint=false: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Invalid JWT Signature."}
您将需要生成一个新的服务账号密钥。
使用引导集群调试问题
Google Distributed Cloud 在创建自行管理(管理员、混合或独立)集群时,会部署 Kubernetes in Docker (kind) 集群,用于暂时托管创建集群所需的 Kubernetes 控制器。此暂时性集群称为引导集群。用户集群由其管理员或混合集群创建和升级,无需使用引导集群。
如果 kind 集群在您尝试安装时已经存在于您的部署中,Google Distributed Cloud 会删除现有的 kind 集群。只有在安装或升级成功后,系统才会执行删除操作。如需在成功后保留现有的 kind 集群,请使用 bmctl 的 --keep-bootstrap-cluster 标志。
Google Distributed Cloud 在 WORKSPACE_DIR/.kindkubeconfig 下为引导集群创建配置文件。您只能在集群创建和升级期间连接到引导集群。
引导集群需要访问 Docker 代码库以拉取映像。除非您使用私有注册表,否则注册表默认为 Artifact Registry。在集群创建期间,bmctl 会创建以下文件:
- bmctl-workspace/config.json:包含 Google Cloud 服务账号凭据,用于访问注册表。凭据是从集群配置文件中的- gcrKeyPath字段获取的。
- bmctl-workspace/config.toml:包含 kind 集群中的 containerd 配置。
检查引导集群日志
如需调试引导集群,您可以执行以下步骤:
- 在集群创建和升级期间连接到引导集群。
- 获取引导集群的日志。
您可以在用于运行 bmctl 的机器的以下文件夹中找到日志:
- bmctl-workspace/CLUSTER_NAME/log/create-cluster-TIMESTAMP/bootstrap-cluster/
- bmctl-workspace/CLUSTER_NAME/log/upgrade-cluster-TIMESTAMP/bootstrap-cluster/
将 CLUSTER_NAME 和 TIMESTAMP 替换为您的集群名称和相应系统的时间。
如需直接获取引导集群的日志,您可以在集群创建和升级期间运行以下命令:
docker exec -it bmctl-control-plane bash
该命令会在引导集群中运行的 bmctl 控制层面容器内打开一个终端。
如需检查 kubelet和 containerd 日志,请使用以下命令并查找输出中的错误或警告:
journalctl -u kubelet
journalctl -u containerd
启用 containerd 调试日志记录
如果标准 containerd 日志无法提供足够的信息来排查问题,您可以提高日志记录级别。在诊断复杂问题(例如注册表镜像问题或 ImagePullBackOff 错误)时,通常需要提高日志记录级别。
如需提高日志记录级别,请执行以下操作:
- 启用调试日志记录: - 使用您偏好的文本编辑器打开 containerd 配置文件 ( - /etc/containerd/config.toml)。
- 在该文件中,找到 - [debug]部分,并将- level的值从- ""更改为- "debug"。
- 保存文件并退出文本编辑器。 
- 验证您是否已成功更新配置文件: - cat /etc/containerd/config.toml | grep debug- 输出应如下所示: - [debug] level = "debug" shim_debug = false
- 如需应用日志记录级别的更改,请重启 containerd: - sudo systemctl restart containerd
 
- 如需生成新的日志条目,请尝试拉取不存在或未被任何节点或集群使用的映像。例如: - # This command fails because the image doesn't exist crictl pull us-west1-docker.pkg.dev/gdc-project/samples/non-existent-image:latest- 这会强制 containerd 执行操作并生成详细日志。 
- 等待映像被拉取或拉取失败,然后将 containerd 日志收集到名为 - containerd_log.txt的文件中:- journalctl -u containerd --no-pager --since TIME_PERIOD > containerd_log.txt- 将 - TIME_PERIOD替换为指定日志开始时间的值。请用英文双引号将包含空格的任何值括起来。 例如- "2 hours ago"。
- 完成问题排查后,将日志级别恢复为默认级别。如果让调试日志记录保持启用状态,可能会导致系统日志泛滥、影响性能,并可能泄露敏感信息。 - 打开 - /etc/containerd/config.toml文件,并将- level的值更改回默认的日志记录级别- ""。
- 验证您是否已成功更新配置: - cat /etc/containerd/config.toml | grep level- 输出应如下所示: - level = ""
- 如需应用更改,请重启 containerd: - sudo systemctl restart containerd- 您的系统现已恢复为标准日志记录配置。 
 
集群升级问题
升级 Google Distributed Cloud 集群时,您可以监控进度并检查集群和节点的状态。
- 如果您在升级期间遇到问题,请尝试确定发生故障的阶段。如需详细了解集群在升级过程中会发生什么,请参阅集群升级的生命周期和阶段。
- 如需详细了解问题在集群升级期间的影响,请参阅了解 Google Distributed Cloud 故障的影响。
以下指南可帮助您确定升级是继续正常进行还是出现问题。
监控升级进度
使用 kubectl describe cluster 命令查看集群在升级过程中的状态:
kubectl describe cluster CLUSTER_NAME \
    --namespace CLUSTER_NAMESPACE \
    --kubeconfig ADMIN_KUBECONFIG
替换以下值:
- CLUSTER_NAME:您的集群的名称。
- CLUSTER_NAMESPACE:集群的命名空间。
- ADMIN_KUBECONFIG:管理员 kubeconfig 文件。- 默认情况下,管理员集群、混合集群和独立集群使用就地升级。如果您将 --use-bootstrap=true标志与bmctl upgrade命令结合使用,升级操作将使用引导集群。如需在使用引导集群时监控升级进度,请指定引导集群 kubeconfig 文件.kindkubeconfig的路径。此文件位于工作区目录中。
 
- 默认情况下,管理员集群、混合集群和独立集群使用就地升级。如果您将 
查看输出的 Status 部分,该部分显示集群升级状态的汇总。如果集群报告错误,请使用以下部分进行问题排查。
检查节点是否已准备就绪
在升级过程中,使用 kubectl get nodes 命令查看集群中节点的状态:
kubectl get nodes --kubeconfig KUBECONFIG
如需检查节点是否成功完成升级,请查看命令响应中的 VERSION 和 AGE 列。VERSION 是集群的 Kubernetes 版本。如需查看给定 Google Distributed Cloud 版本的 Kubernetes 版本,请参阅版本控制。
如果节点显示 NOT READY,请尝试连接节点并检查 kubelet 状态:
systemctl status kubelet
您还可以查看 kubelet 日志:
journalctl -u kubelet
查看 kubelet 状态的输出和日志消息(指示节点出现问题的原因)。
检查哪个节点正在升级
如需检查集群中哪个节点正在升级,请使用 kubectl get baremetalmachines 命令:
kubectl get baremetalmachines --namespace CLUSTER_NAMESPACE \
    --kubeconfig ADMIN_KUBECONFIG
替换以下值:
- CLUSTER_NAMESPACE:集群的命名空间。
- ADMIN_KUBECONFIG:管理员 kubeconfig 文件。- 如果引导集群用于管理员、混合或独立升级,请指定引导集群 kubeconfig 文件 (bmctl-workspace/.kindkubeconfig)。
 
- 如果引导集群用于管理员、混合或独立升级,请指定引导集群 kubeconfig 文件 (
以下示例输出显示正在升级的节点的 ABM VERSION 与 DESIRED ABM VERSION 不同:
NAME         CLUSTER    READY   INSTANCEID               MACHINE      ABM VERSION   DESIRED ABM VERSION
10.200.0.2   cluster1   true    baremetal://10.200.0.2   10.200.0.2   1.13.0        1.14.0
10.200.0.3   cluster1   true    baremetal://10.200.0.3   10.200.0.3   1.13.0        1.13.0
检查哪些节点正在排空
在升级过程中,节点会排空 Pod,并且调度会停用,直到节点成功升级。如需查看哪些节点正在排空,请使用 kubectl get nodes 命令:
kubectl get nodes --kubeconfig USER_CLUSTER_KUBECONFIG | grep "SchedulingDisabled"
将 USER_CLUSTER_KUBECONFIG 替换为用户集群 kubeconfig 文件的路径。
使用 grep 过滤 STATUS 列,以仅显示报告 SchedulingDisabled 的节点。此状态表示节点正在排空。
您还可以检查管理员集群中的节点状态:
kubectl get baremetalmachines -n CLUSTER_NAMESPACE \
  --kubeconfig ADMIN_KUBECONFIG
替换以下值:
- CLUSTER_NAMESPACE:集群的命名空间。
- ADMIN_KUBECONFIG:管理员 kubeconfig 文件。- 如果引导集群用于管理员、混合或独立升级,请指定引导集群 kubeconfig 文件 (bmctl-workspace/.kindkubeconfig)。
 
- 如果引导集群用于管理员、混合或独立升级,请指定引导集群 kubeconfig 文件 (
排空的节点显示 MAINTENANCE 列下的状态。
检查节点长时间处于排空状态的原因
通过上一部分中的其中一种方法,使用 kubectl get nodes 命令识别正在排空的节点。使用 kubectl get
pods 命令并依据此节点名称进行过滤以查看其他详细信息:
kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAME
将 NODE_NAME 替换为正在排空的节点的名称。输出会返回卡住或排空速度缓慢的 Pod 列表。如果节点上的排空过程时间超过 20 分钟,则即使 Pod 卡住,升级也会继续进行。
从 1.29 版开始,节点排空流程使用 Eviction API,该 API 遵循 PodDisruptionBudgets (PDB)。
以下 PDB 设置可能会导致节点排空问题:
- 由多个 PDB 管理的 Pod 
- PDB 静态配置,如下所示: - maxUnavailable==- 0
- minUnavailable>= 总副本数
 - 很难从 PDB 资源确定总副本数,因为它是在更高级别的资源(例如 - Deployment、- ReplicaSet或- StatefulSet)中定义的。PDB 仅根据其配置中的选择器与 Pod 匹配。诊断静态 PDB 配置是否导致问题的一种好方法是,先查看- pdb.Status.ExpectPods<=- pdb.Status.DesiredHealthy是否成立,然后查看是否有上述静态配置允许这种情况发生。
运行时违规(例如 PDB 资源的计算 DisruptionsAllowed 值为 0)也可能会阻止节点排空。如果您配置的 PodDisruptionBudget 对象无法允许任何额外的中断,则节点升级可能会在反复尝试后仍无法升级到控制平面版本。为防止此故障,我们建议您扩容 Deployment 或 HorizontalPodAutoscaler,以允许节点排空,同时仍遵循 PodDisruptionBudget 配置。
如需查看不允许出现任何中断的所有 PodDisruptionBudget 对象,请使用以下命令:
kubectl get poddisruptionbudget --all-namespaces \
    -o jsonpath='{range .items[?(@.status.disruptionsAllowed==0)]}{.metadata.name}/{.metadata.namespace}{"\n"}{end}'
检查 Pod 运行状况不佳的原因
如果 Pod 包含 upgrade-first-node 或 upgrade-node 控制平面 IP 地址,升级可能会失败。此行为通常是因为静态 Pod 运行状况不佳。
- 使用 - crictl ps -a命令检查静态 Pod,并查找任何崩溃的 Kubernetes 或- etcdPod。如果您的 Pod 发生故障,请查看 Pod 的日志,了解 Pod 崩溃的原因。- 崩溃循环行为的一些可能原因包括: - 装载到静态 Pod 的文件的权限或所有者不正确。
- 与虚拟 IP 地址的连接不起作用。
- 与 etcd有关的问题。
 
- 如果 - crictl ps命令不起作用或未返回任何内容,请检查- kubelet和 containerd 状态。使用- systemctl status SERVICE和- journalctl -u SERVICE命令查看日志。
后续步骤
如果您需要其他帮助,请与 Cloud Customer Care 联系。 您还可以参阅获取支持,详细了解支持资源,包括以下内容: