跳至内容

为什么我无法在 Amazon EKS 中运行 kubectl 命令?

4 分钟阅读
0

我无法在 Amazon Elastic Kubernetes Service (Amazon EKS) 中运行 kubectl 命令,例如 kubectl exec、kubectl logs、kubectl get pods 或 kubectl get nodes。

简短描述

当您尝试运行 kubectl 命令时,可能会遇到以下问题:

  • 您无法运行 kubectl execkubectl logskubectl attachkubectl port-forward
  • kubectl 无法到达控制面板。
  • 您无法安装 kubectl
  • 您遇到授权错误。

解决方法

**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

您无法运行 kubectl exec、kubectl logs、kubectl attach 或 kubectl port-forward

要运行 kubectl execkubectl logskubectl attachkubectl 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 中启用 RotateKubeletServerCertificateServerTLSBootstrap 标志,这样 kubelet 才会自己提交和轮换服务证书。要检查 kubelet-config JSON 文件中的标志是否设置为 true,请在 Worker 节点内运行以下命令:

cat /etc/kubernetes/kubelet/kubelet-config.json

输出示例:

"serverTLSBootstrap": true
"featureGates": {
    "RotateKubeletServerCertificate": true
    }

要让 kubelet 创建并提交 CSR,您必须将 eks:node-bootstrapper 角色附加到 system:bootstrapperssystem:nodes 组。要检查 ClusterRoleClusterRoleBinding 是否具有 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:bootstrapperssystem: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 服务器端点的正确端口和主机信息时,通常会出现此错误。

要解决此问题,请完成以下步骤:

  1. 要更新 kubeconfig 文件,请运行以下 update-kubeconfig AWS CLI 命令:

    aws eks update-kubeconfig --region region-code --name my-cluster

    **注意:**将 region-code 替换为您的 AWS 区域,将 my-cluster 替换为您的集群名称。

  2. 要查看当前上下文,请运行以下命令:

    kubectl config current-context
  3. 要检查您在环境中配置的 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 命令时,您可能会遇到以下错误:

“错误: 您必须登录到服务器(未授权)”

要解决此问题,请参阅当我连接到 Amazon EKS API 服务器时,如何解决错误“您必须登录到服务器(未授权)”?

AWS 官方已更新 6 个月前