本页面介绍了如何解决您在使用 Google Kubernetes Engine (GKE) 时出现的 kubectl
命令行工具问题。如需了解更多常规建议,请参阅 Kubernetes 文档中的排查 kubectl 问题。
身份验证和授权错误
如果您在使用 kubectl
命令行工具命令时遇到与身份验证和授权相关的错误,请参阅以下部分以获取建议。
错误:401(未授权)
连接到 GKE 集群时,您可能会收到 HTTP 状态代码为 401 (Unauthorized)
的身份验证和授权错误。如果您尝试通过本地环境在 GKE 集群中运行 kubectl
命令,可能会遇到此问题。如需了解详情,请参阅问题:身份验证和授权错误。
错误:身份验证范围不足
运行 gcloud container clusters get-credentials
时,您可能会收到以下错误:
ERROR: (gcloud.container.clusters.get-credentials) ResponseError: code=403, message=Request had insufficient authentication scopes.
出现此错误的原因是您正在尝试从没有 cloud-platform
范围的 Compute Engine 虚拟机访问 Kubernetes Engine API。
如需解决此错误,请授予缺少的 cloud-platform
范围。如需了解如何在 Compute Engine 虚拟机实例上更改范围,请参阅 Compute Engine 文档中的为实例创建和启用服务账号。
错误:找不到可执行的 gke-gcloud-auth-plugin
在尝试运行 kubectl
命令或与 GKE 交互的自定义客户端时,可能会出现类似以下内容的错误消息:
Unable to connect to the server: getting credentials: exec: executable gke-gcloud-auth-plugin not found
It looks like you are trying to use a client-go credential plugin that is not installed.
To learn more about this feature, consult the documentation available at:
https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins
Visit cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl#install_plugin to install gke-gcloud-auth-plugin.
Unable to connect to the server: getting credentials: exec: fork/exec /usr/lib/google-cloud-sdk/bin/gke-gcloud-auth-plugin: no such file or directory
如需解决此问题,请按照安装所需的插件中的说明安装 gke-gcloud-auth-plugin
。
错误:找不到身份验证提供方
如果 kubectl
或自定义 Kubernetes 客户端使用 Kubernetes client-go
1.26 版或更高版本构建,则会发生以下错误:
no Auth Provider found for name "gcp"
如需解决此问题,请完成以下步骤:
按照安装所需的插件中的说明安装
gke-gcloud-auth-plugin
。更新到最新版 gcloud CLI:
gcloud components update
更新
kubeconfig
文件。gcloud container clusters get-credentials CLUSTER_NAME \ --region=COMPUTE_REGION
替换以下内容:
CLUSTER_NAME
:您的集群的名称。COMPUTE_REGION
:集群的 Compute Engine 区域。 对于可用区级集群,请使用--zone=COMPUTE_ZONE
。
错误:GCP 身份验证插件已弃用,请改用 gcloud
在安装 gke-gcloud-auth-plugin
并对 GKE 集群运行 kubectl
命令后,您可能会看到以下警告消息:
WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.25+; use gcloud instead.
如果您的客户端版本低于 1.26,则会显示此消息。
如需解决此问题,请指示客户端改用 gke-gcloud-auth-plugin
身份验证插件:
在文本编辑器中打开 shell 登录脚本:
Bash
vi ~/.bashrc
Zsh
vi ~/.zshrc
如果您使用的是 PowerShell,请跳过此步骤。
设置以下环境变量:
Bash
export USE_GKE_GCLOUD_AUTH_PLUGIN=True
Zsh
export USE_GKE_GCLOUD_AUTH_PLUGIN=True
PowerShell
[Environment]::SetEnvironmentVariable('USE_GKE_GCLOUD_AUTH_PLUGIN', True, 'Machine')
在您的环境中应用该变量:
Bash
source ~/.bashrc
Zsh
source ~/.zshrc
PowerShell
退出终端并打开新的终端会话。
更新 gcloud CLI:
gcloud components update
向集群进行身份验证:
gcloud container clusters get-credentials CLUSTER_NAME \ --region=COMPUTE_REGION
请替换以下内容:
CLUSTER_NAME
:您的集群的名称。COMPUTE_REGION
:集群的 Compute Engine 区域。 对于可用区级集群,请使用--zone=COMPUTE_ZONE
。
问题:找不到 kubectl
命令
如果您收到一条消息,提示您未找到 kubectl
命令,请重新安装 kubectl
二进制文件并设置 $PATH
环境变量:
安装
kubectl
二进制文件:gcloud components update kubectl
当安装程序提示您修改
$PATH
环境变量时,请输入y
以继续。修改此变量后,您可以在使用kubectl
命令时无需键入其完整路径。或者,将以下行添加到 shell 存储环境变量的任何位置,例如
~/.bashrc
(在 macOS 中是~/.bash_profile
):export PATH=$PATH:/usr/local/share/google/google-cloud-sdk/bin/
运行以下命令以加载更新后的文件。以下示例使用
.bashrc
:source ~/.bashrc
如果您使用的是 macOS,请使用
~/.bash_profile
而不是.bashrc
。
问题:kubectl
命令返回“连接被拒绝”错误
如果 kubectl
命令返回“连接被拒绝”错误,则需要使用以下命令设置集群上下文:
gcloud container clusters get-credentials CLUSTER_NAME
将 CLUSTER_NAME
替换为您的集群名称。如果您不确定要为集群名称输入什么内容,请使用以下命令列出您的集群:
gcloud container clusters list
错误:kubectl
命令超时
如果您创建了集群并尝试针对该集群运行 kubectl
命令,但 kubectl
命令超时,您会看到类似于以下内容的错误:
Unable to connect to the server: dial tcp IP_ADDRESS: connect: connection timed out
Unable to connect to the server: dial tcp IP_ADDRESS: i/o timeout
。
这些错误表示 kubectl
无法与集群控制平面通信。
如需解决此问题,请验证并设置集群所在的上下文,并确保与集群的连接:
前往
$HOME/.kube/config
或运行命令kubectl config view
以验证配置文件是否包含集群上下文和控制平面的外部 IP 地址。设置集群凭据:
gcloud container clusters get-credentials CLUSTER_NAME \ --location=COMPUTE_LOCATION \ --project=PROJECT_ID
替换以下内容:
CLUSTER_NAME
:您的集群的名称。COMPUTE_LOCATION
:Compute Engine 位置。PROJECT_ID
:在其中创建集群的项目的 ID。
如果该集群是专用 GKE 集群,那么请确保其现有授权网络列表包含您尝试连接的计算机的传出 IP。您可以在控制台中查找现有授权网络,也可以通过运行以下命令来查找:
gcloud container clusters describe CLUSTER_NAME \ --location=COMPUTE_LOCATION \ --project=PROJECT_ID \ --format "flattened(masterAuthorizedNetworksConfig.cidrBlocks[])"
如果上述命令输出的授权网络列表中未包含机器的传出 IP,请完成以下步骤之一:
- 如果您使用的是控制台,请通过实现任一集群端点访问配置,提高集群控制平面的可达性。如需了解详情,请参阅集群端点访问权限。
- 如果从 Cloud Shell 连接,请按照使用 Cloud Shell 访问专用集群中的说明操作。
错误:kubectl
命令返回“无法协商 API 版本”
如果 kubectl
命令返回 failed to negotiate an API version
错误,则需要确保 kubectl
具有身份验证凭据:
gcloud auth application-default login
问题:kubectl
logs
、attach
、exec
或 port-forward
命令停止响应
如果 kubectl
logs
、attach
、exec
或 port-forward
命令停止响应,通常表示 API 服务器无法与节点通信。
首先,检查您的集群是否有任何节点。如果您已将集群中的节点数减少到零,则命令将无法运行。如需解决此问题,请调整集群大小以至少拥有一个节点。
如果您的集群至少有一个节点,那么请检查您是使用 SSH 还是 Konnectivity 代理隧道来实现安全通信。以下各部分介绍了针对每项服务的特定问题排查步骤:
排查 SSH 问题
如果您使用的是 SSH,GKE 会在您的 Compute Engine 项目元数据中保存一个 SSH 公钥文件。使用 Google 提供的映像的所有 Compute Engine 虚拟机会定期检查其项目的公共元数据及其实例的元数据,以使 SSH 公钥添加到虚拟机的授权用户列表中。GKE 还为您的 Compute Engine 网络添加了防火墙规则,以允许通过 SSH 实现从控制平面的 IP 地址到集群中每个节点的访问。
以下设置可能会导致 SSH 通信出现问题:
您的网络的防火墙规则不允许通过 SSH 从控制平面访问。
所有 Compute Engine 网络都使用名为
default-allow-ssh
的防火墙规则创建,该规则允许从所有 IP 地址进行 SSH 访问(需要使用有效的私钥)。GKE 还为每个公共集群插入一项 SSH 规则(格式为gke-CLUSTER_NAME-RANDOM_CHARACTERS-ssh
),该规则允许通过 SSH 实现专门从集群的控制平面到集群的节点的访问。若没有这些规则,则控制平面无法打开 SSH 隧道。
如需验证是否是此原因导致的问题,请检查您的配置是否包含这些规则。
如需解决此问题,请确定所有集群节点上的标记,然后重新添加防火墙规则,以允许从控制平面的 IP 地址访问具有该标记的虚拟机。
您的项目的
ssh-keys
的公共元数据条目已满。如果名为
ssh-keys
的项目元数据条目接近其大小上限,则 GKE 将无法添加自己的 SSH 密钥来打开 SSH 隧道。如需验证是否存在此问题,请检查
ssh-keys
列表的长度。您可以通过运行以下命令并酌情添加--project
标志来查看项目的元数据:gcloud compute project-info describe [--project=PROJECT_ID]
如需解决此问题,对不再需要的密钥,请删除一些 SSH 密钥。
您已在集群中的虚拟机上使用密钥
ssh-keys
设置元数据字段。相比项目范围的 SSH 密钥,虚拟机上的节点代理会优先使用每个实例的 SSH 密钥,因此如果您在集群的节点上专门设置了任何 SSH 密钥,则节点将不会遵循项目元数据中控制平面的 SSH 密钥。
如需验证是否存在此问题,请运行
gcloud compute instances describe VM_NAME
并在元数据中查找ssh-keys
字段。如需解决此问题,请从实例元数据中删除每个实例的 SSH 密钥。
排查 Konnectivity 代理问题
您可以通过检查以下系统 Deployment 来确定集群是否使用 Konnectivity 代理:
kubectl get deployments konnectivity-agent --namespace kube-system
以下设置可能会导致 Konnectivity 代理出现问题:
您的网络的防火墙规则不允许 Konnectivity 代理访问控制平面。
在创建集群时,Konnectivity 代理 Pod 会在端口
8132
上建立并维护与控制平面的连接。运行其中一个kubectl
命令时,API 服务器会使用此连接与集群进行通信。如果您的网络的防火墙规则包含出站流量拒绝规则,则可能会阻止代理建立连接。
如需验证问题是否由此原因引起,请检查网络的防火墙规则,看看它们是否包含出站流量拒绝规则。
如需解决此问题,请允许出站流量通过端口 8132 进入集群控制平面。(相比之下,API 服务器使用 443)。
您的集群的网络政策会阻止从
kube-system
命名空间到workload
命名空间的入站流量。集群的正确运行并不需要这些功能。如果您希望集群的网络拒绝所有外部访问,请注意这些功能将停止工作。
如需验证问题是否由此原因引起,请通过运行以下命令查找受影响命名空间中的网络政策:
kubectl get networkpolicy --namespace AFFECTED_NAMESPACE
如需解决此问题,请将以下内容添加到网络政策的
spec.ingress
字段中:- from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: konnectivity-agent
后续步骤
如果您需要其他帮助,请与 Cloud Customer Care 联系。