为什么我无法在 Amazon EKS 中运行 kubectl 命令?
我无法在 Amazon Elastic Kubernetes Service (Amazon EKS) 中运行 kubectl 命令,例如 kubectl exec、kubectl logs、kubectl get pods 或 kubectl get nodes。
简短描述
当您尝试运行 kubectl 命令时,可能会遇到以下问题:
- 您无法运行 kubectl exec、kubectl logs、kubectl attach 或 kubectl port-forward。
- kubectl 无法到达控制面板。
- 您无法安装 kubectl。
- 您遇到授权错误。
解决方法
**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
您无法运行 kubectl exec、kubectl logs、kubectl attach 或 kubectl port-forward
要运行 kubectl exec、kubectl logs、kubectl attach 或 kubectl port-forward 命令,Amazon EKS API 必须与 kubelet 建立可信连接。如果身份验证失败,则会收到与以下示例类似的错误:
“来自服务器的错误:拨号后端时出错:远程错误:tls:内部错误”
检查是否存在网络连接问题
确保 API 服务器可以在端口 1025 上与 Worker 节点通信。Worker 节点安全组必须允许端口 10250 上来自群集安全组的入站流量。集群安全组必须允许端口 443 上来自 Worker 节点安全组的入站流量。确保您的安全组遵守 Amazon EKS 要求。
检查是否存在 CSR 问题
如果控制面板不批准 kubelet 提交的证书签名请求 (CSR),则 kubelet 将无法运行。
要识别存在问题的 CSR,请运行以下命令:
kubectl get certificatesigningrequest
要检查 CSR 请求的状态,请运行以下命令:
kubectl describe certificatesigningrequest csr-name -n namespace
**注意:**将 csr-name 替换为 CSR 名称,将 namespace 替换为命名空间名称。
在输出中,检查 CSR 是否处于 Pending(待处理)或 Approved(已批准)状态,而不是 Approved, Issued(已批准,已发布)状态。
您必须在 kubelet 中启用 RotateKubeletServerCertificate 和 ServerTLSBootstrap 标志,这样 kubelet 才会自己提交和轮换服务证书。要检查 kubelet-config JSON 文件中的标志是否设置为 true,请在 Worker 节点内运行以下命令:
cat /etc/kubernetes/kubelet/kubelet-config.json
输出示例:
"serverTLSBootstrap": true "featureGates": { "RotateKubeletServerCertificate": true }
要让 kubelet 创建并提交 CSR,您必须将 eks:node-bootstrapper 角色附加到 system:bootstrappers 和 system:nodes 组。要检查 ClusterRole 和 ClusterRoleBinding 是否具有 eks:node:boostrapper 角色,请运行以下命令:
kubectl describe clusterrole eks:node-bootstrapper kubectl describe clusterrolebinding eks:node-bootstrapper
输出示例:
kubectl describe clusterrole eks:node-bootstrapper Name: eks:node-bootstrapper Labels: eks.amazonaws.com/component=node Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- certificatesigningrequests.certificates.k8s.io/selfnodeserver [] [] [create] $ kubectl describe clusterrolebinding eks:node-bootstrapper Name: eks:node-bootstrapper Labels: eks.amazonaws.com/component=node Annotations: <none> Role: Kind: ClusterRole Name: eks:node-bootstrapper Subjects: Kind Name Namespace ---- ---- --------- Group system:bootstrappers Group system:nodes
如果缺少 eks:node-bootstrapper 角色,请使用以下配置创建 YAML 文件:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: eks:node-bootstrapper labels: eks.amazonaws.com/component: node rules: - apiGroups: ["certificates.k8s.io"] resources: ["certificatesigningrequests/selfnodeserver"] verbs: ["create"]
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: eks:node-bootstrapper labels: eks.amazonaws.com/component: node roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: eks:node-bootstrapper subjects: - kind: Group name: system:bootstrappers - kind: Group name: system:nodes
然后,运行以下命令来更新 Amazon EKS 集群:
kubectl apply -f file-name command
**注意:**将 file-name 替换为您的 YAML 文件名。
如果您使用 ConfigMap 身份验证方法,则还必须将在 aws-auth 文件中配置的 instance-role 附加到 system:bootstrappers 和 system:nodes 组中。按照以下格式将 instance-role 添加到 aws-auth:
kubectl get cm aws-auth -n kube-system -o yaml apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes rolearn: arn:aws:iam::12345678912:role/kubectl-cluster-nodegroup-custo-NodeInstanceRole-1KFZHWE6FCBDS username: system:node:{{EC2PrivateDNSName}}
**注意:**如果您将 Amazon EKS API 配置为集群身份验证模式,请检查您的配置。确保 Worker 节点 AWS Identity and Access Management (IAM) 角色映射到 system:node:{{EC2PrivateDNSName}} 用户名。此配置可确保 Amazon EKS 识别 CSR 请求者并自动批准 CSR。Amazon EKS 仅自动批准来自 system:node:{{EC2PrivateDNSName}} 的 CSR。
要检查请求者的详细信息,请运行以下命令:
kubectl describe csr csr-name
**注意:**将 csr-name 替换为您的 CSR 名称。
输出示例:
Name: csr-tpb4m Labels: <none> Annotations: <none> CreationTimestamp: Tue, 12 Dec 2023 11:18:30 +0530 Requesting User: system:node:ip-000-00-00-000.ec2.internal Signer: kubernetes.io/kubelet-serving Status: Approved,Issued Subject: Common Name: system:node:ip-172-31-73-240.ec2.internal Serial Number: Organization: system:nodes Subject Alternative Names: DNS Names: ip-172-31-73-240.ec2.internal IP Addresses: 172.31.73.240 Events: <none>
确保 CSR 请求者采用 system:node:ip-abc-xx-x-xabc.ec2.internal 格式。如果您使用为 Worker 节点创建集群的同一 IAM 角色,则请求者可能是 kubernetes-admin 而不是 system:node:EC2PrivateDNSName。Amazon EKS 拒绝不来自 system:node:EC2PrivateDNSName 的请求。如果您已在 aws-auth 中将 Worker 节点角色映射到自定义用户名,请确保已将 Worker 节点角色正确映射到 system:node:EC2PrivateDNSName。
检查 kubelet 日志
要检查 kubelet 的状态,请运行以下命令:
systemctl status kubelet
如果输出显示 kubelet 状态为 Stopped(已停止),则运行以下命令来重启 kubelet:
sudo systemctl restart kubelet
要检查 kubelet 日志中是否存在 cert 关键字,请运行以下命令:
journalctl -u kubelet | grep cert
错误示例:
kubelet[8070]: I1021 18:49:21.594143 8070 log.go:184] http: TLS handshake error from 192.168.130.116:38710: no serving certificate available for the kubelet
如果您在命令输出中没有看到 cert 错误,则可以提交新的 CSR。如需更详细的日志,请使用 --v=4 标志。要收集 Worker 节点日志以进行详细分析,请使用 GitHub 网站上的 log-collector-script。
检查控制面板日志
先决条件:允许 Amazon EKS 集群向 Amazon CloudWatch Logs Insights 发送控制面板日志。
要进一步了解 CSR 问题,请运行以下命令以使用 CloudWatch Logs Insights 检查控制面板日志:
fields @timestamp, @message, @logStream, @log | filter message like 'csr-name' | sort @timestamp desc | limit 10000
**注意:**将 csr-name 替换为存在问题的 CSR 的名称。
Kubectl 无法访问控制面板
检查对 Amazon EKS 端点的访问权限
如果您为集群的 Kubernetes API 服务器端点启用了私有访问权限,则只能从以下来源访问 API 服务器:
- 您的虚拟专用网络 (VPC)
- 连接的网络
如果您从不属于 VPC 或互联网络中的客户端运行 kubectl,则无法访问集群的 API 服务器。您会收到类似于以下示例的错误:
“E1009 12:33:44.852680 106 memcache.go:265] 无法获取当前服务器 API 组列表: 获取‘APISERVERENDPOINT’:拨打 tcp 11.11.111.111:443:I/O 超时”
要解决此问题,请将集群端点访问权限更改为 Public access(公开访问)。如果您必须拥有私有集群,请在集群的 VPC 中创建 Amazon Elastic Compute Cloud (Amazon EC2) 堡垒主机。然后,使用堡垒主机访问集群。您必须将堡垒主机的安全组添加到集群的安全组中。
检查您的主机和端口配置
如果您收到错误消息 The connection to the server localhost:8080 was refused(与服务器 localhost: 8080 的连接被拒绝),请检查您的主机和端口配置。当 kubectl 在 kubeconfig 文件中找不到 Amazon EKS API 服务器端点的正确端口和主机信息时,通常会出现此错误。
要解决此问题,请完成以下步骤:
-
要更新 kubeconfig 文件,请运行以下 update-kubeconfig AWS CLI 命令:
aws eks update-kubeconfig --region region-code --name my-cluster**注意:**将 region-code 替换为您的 AWS 区域,将 my-cluster 替换为您的集群名称。
-
要查看当前上下文,请运行以下命令:
kubectl config current-context -
要检查您在环境中配置的 IAM 用户或角色,请运行以下 get-caller-identity 命令:
aws sts get-caller-identity
要对 IAM 问题进行故障排除,请参阅在 Amazon EKS 中创建集群后,如何向其他 IAM 用户和角色提供集群访问权限?
检查控制面板和 Worker 节点安全组规则
如果您的控制面板和节点安全组规则阻止访问 API 服务器,则会收到以下错误:
“与服务器 APISERVERENDPOINT 的连接被拒绝。您是否指定了正确的主机或端口?”
要解决此问题,请确保控制面板和节点安全组具有所需的入站和出站规则。API 服务器安全组必须允许通过端口 443 从 API 服务器客户端进行入站访问。
您无法安装 kubectl
您使用的 kubectl 版本必须与集群的版本相差不超过一个次要版本号。例如,v1.31 客户端可以与控制面板版本 v1.30、v1.31 和 v1.32 进行通信。为避免出现问题,请安装最新兼容版本的 kubectl。
安装 kubectl 时,您可能会收到以下错误之一:
“错误:执行插件:apiVersion‘client.authentication.k8s.io/v1alpha1’无效”
-或-
“无法连接到服务器:正在获取凭证:正在解码 stdout:架构‘pkg/client/auth/exec/exec.go:62’中没有为版本‘client.authentication.k8s.io/v1alpha1’注册任何一种‘ExecCredential’”
当您使用早期版本的 AWS CLI 运行 update-kubeconfig 命令时,通常会出现上述错误。要解决此问题,请按照更新 AWS CLI 进行操作。有关详细信息,请参阅 GitHub 网站上的 Deprecate Kubernetes client API version v1alpha1。
运行 kubectl 命令时遇到授权错误
当运行 kubectl 命令时,您可能会遇到以下错误:
“错误: 您必须登录到服务器(未授权)”
- 语言
- 中文 (简体)

相关内容
AWS 官方已更新 5 个月前