下面几个部分介绍使用 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 控制器的日志来尝试进行调试:
在
kube-system
命名空间中找到 Cluster API 控制器 pod 的名称,其中 [ADMIN_CLUSTER_KUBECONFIG] 是管理员集群的 kubeconfig 文件的路径:kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] -n kube-system get pods | grep clusterapi-controllers
打开 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_proxy
或HTTPS_PROXY
环境变量配置中可能存在错误。如果环境变量中指定了https://
,则当代理配置为使用其他协议(如 SOCK5)来处理 HTTPS 连接时,GoLang HTTP 客户端库可能会失败。- 解决方法
修改
https_proxy
和HTTPS_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 配置存在错误。
- 解决方法
- 请尝试以下步骤来解决此问题:
从 kubeconfig 解析
id-token
。在登录命令生成的 kubeconfig 文件中,复制
id-token
:kind: Config … users: - name: … user: auth-provider: config: id-token: [id-token] …
按照步骤安装 jwt-cli 并运行以下命令:
$ jwt [id-token]
验证 OIDC 配置
用于创建集群的
config.yaml
中填有oidc
部分,此部分含有在 apiserver 中设置--oidc-group-claim
和--oidc-username-claim
标志时使用的group
和username
字段。当 apiserver 收到令牌时,会查找 group-claim 和 username-claim,并验证相应的群组或用户是否拥有正确的权限。验证在
config.yaml
的oidc
部分为group
和user
设置的声明是否存在于id-token
中。检查已应用的 RBAC。
针对上一步由 username-claim 指定的用户或者 group-claim 下面列出的某个群组,验证是否存在具有正确权限的 RBAC。RBAC 中用户或群组的名称应该带有前缀
usernameprefix
或groupprefix
,此前缀是在config.yaml
的oidc
部分提供的。请注意,如果
usernameprefix
留空,并且username
是email
以外的值,则前缀将默认为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
请检查 API 服务器日志
如果 kube apiserver 中配置的 OIDC 插件未正确启动,则当 API 服务器收到
id-token
时,会返回“未经授权”错误。如需检查 API 服务器中的 OIDC 插件是否存在任何问题,请运行以下命令:$ kubectl --kubeconfig=[admin_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 身份提供方。
- 解决方法
请尝试以下步骤来解决此问题:
-
将
useHTTPProxy
设置为true
如果无法通过公共互联网访问 IDP,则需要启用 OIDC HTTP 代理以通过 Google Cloud 控制台登录。在
config.yaml
的oidc
部分中,应将usehttpproxy
设置为true
。如果您已经创建了集群并希望启用代理,则可以直接修改 ClientConfig CRD。运行$ kubectl edit clientconfig default -n kube-public
并将useHTTPProxy
更改为true
。 useHTTPProxy
已设置为true
如果已启用 HTTP 代理,但您仍然看到此错误,则可能是代理启动时出现问题。如需获取代理的日志,请运行
$ kubectl logs deployment/clientconfig-operator -n kube-system
。请注意,即使您的 IDP 有一个知名的 CA,也必须提供config.yaml
的oidc
部分中的capath
字段才能启动 HTTP 代理。IDP 提示同意
如果授权服务器提示同意,而您未添加 extraparam
prompt=consent
,则您可能会看到此错误。运行$ kubectl edit clientconfig default -n kube-public
,将prompt=consent
添加到extraparams
,然后再次尝试登录。RBAC 配置错误
如果您尚未验证,请尝试使用适用于 Anthos 的身份验证插件进行身份验证。如果您在使用该插件登录时也看到授权错误,请按照问题排查步骤来解决插件问题,然后再次尝试通过 Google Cloud 控制台登录。
尝试退出,然后重新登录
在某些情况下,如果存储服务的某些设置更改,您可能需要明确退出。转到集群详情页面,点击退出,然后尝试重新登录。
管理员工作站
下载 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。
解决方法
如果虚拟磁盘挂接到了错误的虚拟机,您可能需要手动将其分离:
- 排空节点。请参阅安全排空节点。您可能需要在
kubectl drain
命令中添加--ignore-daemonsets
和--delete-local-data
标志。 - 关闭虚拟机电源。
- 在 vCenter 中修改虚拟机的硬件配置以移除卷。
- 开启虚拟机
- 取消封锁节点。
卷丢失
表现
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 资源:
- 通过运行
kubectl delete pvc [PVC_NAME].
删除引用了 PV 的 PVC - 通过运行
kubectl delete pod [POD_NAME].
删除引用了 PVC 的 pod - 重复第 2 步。(是的,请参阅 Kubernetes 问题 74374。)
升级
关于升级过程中的停机时间
资源 说明 管理员集群 当管理员集群关闭时,用户集群上的用户集群控制层面和工作负载会继续运行,除非它们受到导致停机的故障的影响
用户集群控制层面 通常情况下,用户集群控制层面应该不会出现较长的停机时间。但是,与 Kubernetes API 服务器的长时间运行的连接可能会中断,需要重新建立连接。在这些情况下,API 调用方应该重试,直到建立连接。在最糟糕的情况下,升级期间的停机时间可能长达一分钟。
用户集群节点 如果升级需要更改用户集群节点,GKE On-Prem 会以滚动方式重新创建节点,并重新安排在这些节点上运行的 pod。您可以通过配置适当的 PodDisruptionBudget 和反亲和性规则来防止对工作负载产生影响。
调整用户集群的大小
无法调整用户集群的大小
- 表现
对用户集群执行的调整大小操作失败。
- 潜在原因
有几个因素可能会导致调整大小操作失败。
- 解决方法
如果调整大小失败,请按以下步骤操作:
检查集群的 MachineDeployment 状态,看看是否有任何事件或错误消息:
kubectl describe machinedeployments [MACHINE_DEPLOYMENT_NAME]
检查新创建的 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 证书,则此证书可能会随时间而更改。如果证书已更改,您需要让正在运行的集群知晓新证书:
检索新的 vCenter 证书并保存到文件中:
true | openssl s_client -connect [VCENTER_IP_ADDRESS]:443 -showcerts 2>/dev/null | sed -ne '/-BEGIN/,/-END/p' > vcenter.pem
现在,对于每个集群,请删除包含每个集群的 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 -
删除每个集群的 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 许可已过期,您可能会遇到意外故障。
-