问题排查

下面几个部分介绍使用 GKE On-Prem 时可能遇到的问题及其解决方法。

准备工作

在开始排查问题之前,请先查看以下部分。

使用 gkectl 诊断集群问题

使用 gkectl diagnose 命令识别集群问题并与 Google 共享集群信息。请参阅诊断集群问题

以 verbose 模式运行 gkectl 命令

-v5

gkectl 错误记录到 stderr

--alsologtostderr

在管理员工作站中查找 gkectl 日志

即使未传入其调试标志,您也可以在以下管理员工作站目录中查看 gkectl 日志:

/home/ubuntu/.config/gke-on-prem/logs

在管理员集群中查找 Cluster API 日志

如果虚拟机在管理员控制层面启动后无法启动,您可以通过在管理员集群中检查 Cluster API 控制器的日志来尝试进行调试:

  1. kube-system 命名空间中找到 Cluster API 控制器 pod 的名称,其中 [ADMIN_CLUSTER_KUBECONFIG] 是管理员集群的 kubeconfig 文件的路径:

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] -n kube-system get pods | grep clusterapi-controllers
  2. 打开 pod 的日志,其中 [POD_NAME] 是 pod 的名称。您可以选择使用 grep 或类似工具来搜索错误:

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] -n kube-system logs [POD_NAME] vsphere-controller-manager

安装

使用管理员集群控制层面节点的 kubeconfig 调试 F5 BIG-IP 问题

安装完成后,GKE On-Prem 会在管理员工作站的主目录中生成一个名为 internal-cluster-kubeconfig-debug 的 kubeconfig 文件。此 kubeconfig 文件与管理员集群的 kubeconfig 完全相同,只是它直接指向管理员集群的控制层面节点(该节点上运行着管理员控制层面)。您可以使用 internal-cluster-kubeconfig-debug 文件调试 F5 BIG-IP 问题。

gkectl check-config 验证失败:找不到 F5 BIG-IP 分区

表现

验证失败,因为找不到 F5 BIG-IP 分区(即使分区存在)。

潜在原因

F5 BIG-IP API 的问题可能会导致验证失败。

解决方法

尝试再次运行 gkectl check-config

gkectl prepare --validate-attestations 失败:无法验证版本证明

表现

如果使用可选的 --validate-attestations 标志运行 gkectl prepare,则系统会返回以下错误:

could not validate build attestation for gcr.io/gke-on-prem-release/.../...: VIOLATES_POLICY
潜在原因

受影响的映像可能没有证明。

解决方法

请按照创建管理员工作站中的说明,尝试重新下载并部署管理员工作站 OVA。如果问题仍然存在,请与 Google 联系以获取帮助。

使用引导集群的日志进行调试

在安装期间,GKE On-Prem 会创建临时引导集群。成功安装后,GKE On-Prem 会删除引导集群,留下您的管理员集群和用户集群。通常情况下,您无需与此集群进行交互。

如果在安装过程中出现问题,并且您确实向 gkectl create cluster 传递了 --cleanup-external-cluster=false,则使用引导集群的日志进行调试可能会有用。您可以找到 pod,然后获取其日志:

kubectl --kubeconfig /home/ubuntu/.kube/kind-config-gkectl get pods -n kube-system
kubectl --kubeconfig /home/ubuntu/.kube/kind-config-gkectl -n kube-system get logs [POD_NAME]

适用于 Anthos 的身份验证插件

运行 gkectl create-login-config 失败

问题 1

表现

运行 gkectl create-login-config 时,您遇到以下错误:

Error getting clientconfig using [user_cluster_kubeconfig]
潜在原因

此错误表示传递到 gkectl create-login-config 的 kubeconfig 文件不适用于用户集群,或者 ClientConfig CRD 在集群创建过程中未出现。

解决方法

运行以下命令以确定 ClientConfig CRD 是否在集群中:

$ kubectl --kubeconfig
  [user_cluster_kubeconfig] get clientconfig default -n kube-public

问题 2

表现

运行 gkectl create-login-config 时,您遇到以下错误:

error merging with file [merge_file] because [merge_file] contains a
  cluster with the same name as the one read from [kubeconfig]. Please write to
  a new output file
潜在原因

每个登录配置文件都必须包含唯一的集群名称。如果您看到这个错误,则表示您正在写入登录配置数据的文件包含一个集群名称,该名称已经存在于目标文件中。

解决方法

写入新的 --output 文件。注意事项:

  • 如果未提供 --output,则默认情况下,登录配置数据将写入当前目录中名为 kubectl-anthos-config.yaml 的文件中。
  • 如果 --output 已存在,则该命令会尝试将新的登录配置合并到 --output

运行 gcloud anthos auth login 失败

问题 1

表现

使用身份验证插件和所生成的登录配置 YAML 文件来运行 login 失败。

潜在原因

OIDC 配置详细信息中可能存在错误。

解决方法

向您的管理员验证 OIDC 客户端注册。

问题 2

表现

为 HTTPS 流量配置了代理后,运行 gcloud anthos auth login 命令失败,而且错误消息中显示 proxyconnect tcp。例如,您可能看到如下所示的错误消息:proxyconnect tcp: tls: first record does not look like a TLS handshake

潜在原因

https_proxyHTTPS_PROXY 环境变量配置中可能存在错误。如果环境变量中指定了 https://,则当代理配置为使用其他协议(如 SOCK5)来处理 HTTPS 连接时,GoLang HTTP 客户端库可能会失败。

解决方法

修改 https_proxyHTTPS_PROXY 环境变量以省略 https:// 前缀。在 Windows 上,修改系统环境变量。例如,将 https_proxy 环境变量的值从 https://webproxy.example.com:8000 更改为 webproxy.example.com:8000

使用 gcloud anthos auth login 生成的 kubeconfig 访问集群失败

表现

“未经授权”错误

如果使用 gcloud anthos auth login 生成的 kubeconfig 访问集群时发生“未经授权”错误,则意味着 apiserver 无法向用户授权。

潜在原因
相应的 RBAC 不存在或者错误,或者集群的 OIDC 配置存在错误。
解决方法
请尝试以下步骤来解决此问题:
  1. 从 kubeconfig 解析 id-token

    在登录命令生成的 kubeconfig 文件中,复制 id-token

    kind: Config
    …
    users:
    - name: …
      user:
        auth-provider:
          config:
            id-token: [id-token]
            …
    

    按照步骤安装 jwt-cli 并运行以下命令:

    $ jwt [id-token]
  2. 验证 OIDC 配置

    用于创建集群的 config.yaml 中填有 oidc 部分,此部分含有在 apiserver 中设置 --oidc-group-claim--oidc-username-claim 标志时使用的 groupusername 字段。当 apiserver 收到令牌时,会查找 group-claim 和 username-claim,并验证相应的群组或用户是否拥有正确的权限。

    验证在 config.yamloidc 部分为 groupuser 设置的声明是否存在于 id-token 中。

  3. 检查已应用的 RBAC。

    针对上一步由 username-claim 指定的用户或者 group-claim 下面列出的某个群组,验证是否存在具有正确权限的 RBAC。RBAC 中用户或群组的名称应该带有前缀 usernameprefixgroupprefix,此前缀是在 config.yamloidc 部分提供的。

    请注意,如果 usernameprefix 留空,并且 usernameemail 以外的值,则前缀将默认为 issuerurl#。如需停用用户名前缀,则 usernameprefix 应该设置为 -

    如需详细了解用户和群组前缀,请参阅填充 OIDC 规范

    请注意,Kubernetes API 服务器目前将反斜杠视为转义字符。因此,如果用户或群组的名称包含 \\,则 API 服务器会在解析 id_token 时将其作为单个 \ 进行读取。因此,应用到此用户或群组的 RBAC 只能包含一个反斜杠,否则您可能会看到 Unauthorized 错误。

    示例:

    config.yaml:

    oidc:
        issuerurl:
        …
        username: "unique_name"
        usernameprefix: "-"
        group: "group"
        groupprefix: "oidc:"
        ...
    

    id_token:

    {
      ...
      "email": "cluster-developer@example.com",
      "unique_name": "EXAMPLE\\cluster-developer",
      "group": [
        "Domain Users",
        "EXAMPLE\\developers"
    ],
      ...
    }
    

    以下 RBAC 将授予此用户集群管理员权限(请注意名称字段中应包含单斜杠,而不是双斜杠):

    Group RBAC:

    apiVersion:
    kind:
    metadata:
       name: example-binding
    subjects:
    -  kind: Group
       name: "oidc:EXAMPLE\developers"
       apiGroup: rbac.authorization.k8s.io
       roleRef:
         kind: ClusterRole
         name: pod-reader
         apiGroup: rbac.authorization.k8s.io
    

    User RBAC:

    apiVersion:
    kind:
    metadata:
       name: example-binding
    subjects:
    -  kind: User
                   name: "EXAMPLE\cluster-developer"
                   apiGroup: rbac.authorization.k8s.io
               roleRef:
               kind: ClusterRole
                   name: pod-reader
                   apiGroup: rbac.authorization.k8s.io
  4. 请检查 API 服务器日志

    如果 kube apiserver 中配置的 OIDC 插件未正确启动,则当 API 服务器收到 id-token 时,会返回“未经授权”错误。如需检查 API 服务器中的 OIDC 插件是否存在任何问题,请运行以下命令:

    $ kubectl
          --kubeconfig=[user_cluster_kubeconfig] logs statefulset/kube-apiserver -n
          [user_cluster_name]
表现

Unable to connect to the server: Get {DISCOVERY_ENDPOINT}: x509: certificate signed by unknown authority(无法连接到服务器:获得 {DISCOVERY_ENDPOINT}:x509:证书由未知授权机构签名)

潜在原因

kubeconfig 中的刷新令牌已过期。

解决方法

再次运行 login 命令。

Google Cloud 控制台登录

以下是使用 Google Cloud 控制台尝试登录时可能发生的常见错误:

登录重定向到页面时显示“未找到网址”错误

表现

Google Cloud 控制台无法访问 GKE On-Prem 身份提供方。

潜在原因

Google Cloud 控制台无法访问 GKE On-Prem 身份提供方。

解决方法

请尝试以下步骤来解决此问题:

  1. useHTTPProxy 设置为 true

    如果无法通过公共互联网访问 IDP,则需要启用 OIDC HTTP 代理以通过 Google Cloud 控制台登录。在 config.yamloidc 部分中,应将 usehttpproxy 设置为 true。如果您已经创建了集群并希望启用代理,则可以直接修改 ClientConfig CRD。运行 $ kubectl edit clientconfig default -n kube-public 并将 useHTTPProxy 更改为 true

  2. useHTTPProxy 已设置为 true

    如果已启用 HTTP 代理,但您仍然看到此错误,则可能是代理启动时出现问题。如需获取代理的日志,请运行 $ kubectl logs deployment/clientconfig-operator -n kube-system。请注意,即使您的 IDP 有一个知名的 CA,也必须提供 config.yamloidc 部分中的 capath 字段才能启动 HTTP 代理。

  3. IDP 提示同意

    如果授权服务器提示同意,而您未添加 extraparam prompt=consent,则您可能会看到此错误。运行 $ kubectl edit clientconfig default -n kube-public,将 prompt=consent 添加到 extraparams,然后再次尝试登录。

  4. RBAC 配置错误

    如果您尚未验证,请尝试使用适用于 Anthos 的身份验证插件进行身份验证。如果您在使用该插件登录时也看到授权错误,请按照问题排查步骤来解决插件问题,然后再次尝试通过 Google Cloud 控制台登录。

  5. 尝试退出,然后重新登录

    在某些情况下,如果存储服务的某些设置更改,您可能需要明确退出。转到集群详情页面,点击退出,然后尝试重新登录。

管理员工作站

下载 OVA 时出现 AccessDeniedException

表现

尝试下载管理员工作站 OVA 和签名会返回以下错误:

AccessDeniedException: 403 whitelisted-service-account@project.iam.gserviceaccount.com does not have storage.objects.list access to gke-on-prem-release
潜在原因

已列入许可名单的服务帐号未激活。

解决方法

确保您已激活已列入许可名单的服务帐号。如果问题仍然存在,请与 Google 联系以获取帮助。

openssl 无法验证管理员工作站 OVA

表现

对管理员工作站 OVA 文件运行 openssl dgst 不会返回 Verified OK

潜在原因

OVA 文件存在问题,导致无法成功验证。

解决方法

按照下载管理员工作站 OVA 中的说明,尝试重新下载并部署管理员工作站 OVA。如果问题仍然存在,请与 Google 联系以获取帮助。

Connect

无法注册用户集群

如果您在注册用户集群时遇到问题,请与 Google 联系以获取帮助。

在 Alpha 版中创建的集群已取消注册

请参阅 Connect 文档中的注册用户集群

您也可以选择删除重新创建集群。

存储

无法挂接卷

表现

gkectl diagnose cluster 的输出如下所示:

Checking cluster object...PASS
Checking machine objects...PASS
Checking control plane pods...PASS
Checking gke-connect pods...PASS
Checking kube-system pods...PASS
Checking gke-system pods...PASS
Checking storage...FAIL
    PersistentVolume pvc-776459c3-d350-11e9-9db8-e297f465bc84: virtual disk "[datastore_nfs] kubevols/kubernetes-dynamic-pvc-776459c3-d350-11e9-9db8-e297f465bc84.vmdk" IS attached to machine "gsl-test-user-9b46dbf9b-9wdj7" but IS NOT listed in the Node.Status
1 storage errors

一个或多个 pod 卡在 ContainerCreating 状态,并出现如下警告:

Events:
  Type     Reason              Age               From                     Message
  ----     ------              ----              ----                     -------
  Warning  FailedAttachVolume  6s (x6 over 31s)  attachdetach-controller  AttachVolume.Attach failed for volume "pvc-776459c3-d350-11e9-9db8-e297f465bc84" : Failed to add disk 'scsi0:6'.

潜在原因

如果将虚拟磁盘挂接到错误的虚拟机,则可能是由于 Kubernetes 1.12 中的问题 #32727

解决方法

如果虚拟磁盘挂接到了错误的虚拟机,您可能需要手动将其分离:

  1. 排空节点。请参阅安全排空节点。您可能需要在 kubectl drain 命令中添加 --ignore-daemonsets--delete-local-data 标志。
  2. 关闭虚拟机电源
  3. 在 vCenter 中修改虚拟机的硬件配置以移除卷。
  4. 开启虚拟机
  5. 取消封锁节点

卷丢失

表现

gkectl diagnose cluster 的输出如下所示:

Checking cluster object...PASS
Checking machine objects...PASS
Checking control plane pods...PASS
Checking gke-connect pods...PASS
Checking kube-system pods...PASS
Checking gke-system pods...PASS
Checking storage...FAIL
    PersistentVolume pvc-52161704-d350-11e9-9db8-e297f465bc84: virtual disk "[datastore_nfs] kubevols/kubernetes-dynamic-pvc-52161704-d350-11e9-9db8-e297f465bc84.vmdk" IS NOT found
1 storage errors

一个或多个 pod 卡在 ContainerCreating 状态,并出现如下警告:

Events:
  Type     Reason              Age                   From                                    Message
  ----     ------              ----                  ----                                    -------
  Warning  FailedAttachVolume  71s (x28 over 42m)    attachdetach-controller                 AttachVolume.Attach failed for volume "pvc-52161704-d350-11e9-9db8-e297f465bc84" : File []/vmfs/volumes/43416d29-03095e58/kubevols/
  kubernetes-dynamic-pvc-52161704-d350-11e9-9db8-e297f465bc84.vmdk was not found

潜在原因

如果您看到与 VMDK 文件相关的“未找到”错误,则可能是因为永久删除了虚拟磁盘。如果运维人员手动删除虚拟磁盘或其挂接的虚拟机,则可能会发生这种情况。为避免出现这种情况,请按照调整用户集群的大小升级集群中的说明管理您的虚拟机

解决方法

如果虚拟磁盘已永久删除,您可能需要手动清理相关 Kubernetes 资源:

  1. 通过运行 kubectl delete pvc [PVC_NAME]. 删除引用了 PV 的 PVC
  2. 通过运行 kubectl delete pod [POD_NAME]. 删除引用了 PVC 的 pod
  3. 重复第 2 步。(是的,请参阅 Kubernetes 问题 74374。)

升级

关于升级过程中的停机时间

资源 说明
管理员集群

当管理员集群关闭时,用户集群上的用户集群控制层面和工作负载会继续运行,除非它们受到导致停机的故障的影响

用户集群控制层面

通常情况下,用户集群控制层面应该不会出现较长的停机时间。但是,与 Kubernetes API 服务器的长时间运行的连接可能会中断,需要重新建立连接。在这些情况下,API 调用方应该重试,直到建立连接。在最糟糕的情况下,升级期间的停机时间可能长达一分钟。

用户集群节点

如果升级需要更改用户集群节点,GKE On-Prem 会以滚动方式重新创建节点,并重新安排在这些节点上运行的 pod。您可以通过配置适当的 PodDisruptionBudget反亲和性规则来防止对工作负载产生影响。

调整用户集群的大小

无法调整用户集群的大小

表现

对用户集群执行的调整大小操作失败。

潜在原因

有几个因素可能会导致调整大小操作失败。

解决方法

如果调整大小失败,请按以下步骤操作:

  1. 检查集群的 MachineDeployment 状态,看看是否有任何事件或错误消息:

    kubectl describe machinedeployments [MACHINE_DEPLOYMENT_NAME]
  2. 检查新创建的 Machine 上是否存在错误:

    kubectl describe machine [MACHINE_NAME]

错误:“无法分配任何地址”

表现

调整用户集群的大小后,kubectl describe machine [MACHINE_NAME] 会显示以下错误:

Events:
   Type     Reason  Age                From                    Message
   ----     ------  ----               ----                    -------
   Warning  Failed  9s (x13 over 56s)  machineipam-controller  ipam: no addresses can be allocated
   
潜在原因

可用于用户集群的 IP 地址不足。

解决方法

为集群分配更多 IP 地址。然后,删除受影响的 Machine:

kubectl delete machine [MACHINE_NAME]

如果集群已正确配置,则会使用 IP 地址创建替换 Machine。

已分配足够数量的 IP 地址,但 Machine 无法向集群注册

表现

网络分配了足够的地址,但 Machine 仍然无法向用户集群注册。

可能的原因

可能存在 IP 冲突。该 IP 可能被其他 Machine 或您的负载平衡器占用。

解决方法

确认受影响的 Machine 的 IP 地址未被占用。如果存在冲突,则需要解决您的环境中的冲突。

vSphere

使用 govc 进行调试

如果您遇到 vSphere 特有的问题,则可以使用 govc 进行问题排查。例如,您可以轻松确认 vCenter 用户帐号的权限和访问权限,并收集 vSphere 日志。

更改 vCenter 证书

如果您在评估或默认设置模式下运行 vCenter 服务器,并且该服务器具有生成的 TLS 证书,则此证书可能会随时间而更改。如果证书已更改,您需要让正在运行的集群知晓新证书:

  1. 检索新的 vCenter 证书并保存到文件中:

    true | openssl s_client -connect [VCENTER_IP_ADDRESS]:443 -showcerts 2>/dev/null | sed -ne '/-BEGIN/,/-END/p' > vcenter.pem
  2. 现在,对于每个集群,请删除包含每个集群的 vSphere 和 vCenter 证书的 ConfigMap,并使用新的证书创建新的 ConfigMap。例如:

    kubectl --kubeconfig kubeconfig delete configmap vsphere-ca-certificate -n kube-system
    kubectl --kubeconfig kubeconfig delete configmap vsphere-ca-certificate -n user-cluster1
    kubectl --kubeconfig kubeconfig create configmap -n user-cluster1 --dry-run vsphere-ca-certificate --from-file=ca.crt=vcenter.pem  -o yaml  | kubectl --kubeconfig kubeconfig apply -f -
    kubectl --kubeconfig kubeconfig create configmap -n kube-system --dry-run vsphere-ca-certificate --from-file=ca.crt=vcenter.pem  -o yaml  | kubectl --kubeconfig kubeconfig apply -f -
  3. 删除每个集群的 clusterapi-controller pod。当 pod 重启时,它会开始使用新证书。例如:

    kubectl --kubeconfig kubeconfig -n kube-system get pods
    kubectl --kubeconfig kubeconfig -n kube-system delete pod clusterapi-controllers-...

其他

Terraform vSphere 提供方会话数限制

GKE On-Prem 使用 Terraform 的 vSphere 提供方在您的 vSphere 环境中启动虚拟机。提供方的会话数上限为 1000。当前实现不会在使用后关闭活动会话。如果您运行的会话过多,则可能会遇到 503 错误。

会话会在 300 秒后自动关闭。

表现

如果您运行的会话过多,则可能会遇到以下错误:

Error connecting to CIS REST endpoint: Login failed: body:
  {"type":"com.vmware.vapi.std.errors.service_unavailable","value":
  {"messages":[{"args":["1000","1000"],"default_message":"Sessions count is
  limited to 1000. Existing sessions are 1000.",
  "id":"com.vmware.vapi.endpoint.failedToLoginMaxSessionCountReached"}]}},
  status: 503 Service Unavailable
潜在原因

您的环境中运行的 Terraform 提供方会话过多。

解决方法

目前,此功能按预期运行。会话会在 300 秒后自动关闭。如需了解详情,请参阅 GitHub 问题 #618

为 Docker 使用代理:oauth2: cannot fetch token

表现

使用代理时,您遇到以下错误:

oauth2: cannot fetch token: Post https://oauth2.googleapis.com/token: proxyconnect tcp: tls: oversized record received with length 20527
潜在原因

您提供的可能是 HTTPS 代理,而不是 HTTP。

解决方法

在 Docker 配置中,将代理地址更改为 http:// 而不是 https://

验证许可是否有效

请务必验证您的许可是否有效,特别是在使用试用许可的情况下。如果您的 F5、ESXi 主机或 vCenter 许可已过期,您可能会遇到意外故障。