跳至內容

為什麼我無法在 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 attachmentkubectl port-forward
  • kubectl 無法到達控制平面。
  • 您無法安裝 kubectl
  • 您遇到授權錯誤。

解決方法

**注意:**如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤訊息,請參閱對 AWS CLI 錯誤進行疑難排解。此外,請確定您使用的是最新的 AWS CLI 版本

您無法執行 kubectl exec、kubectl logs、kubectl attachment 或 kubectl port-forward

若要執行 kubectl execkubectl logskubectl attachmentkubectl port-forward 命令,Amazon EKS API 必須與 kubelet 建立可信任連線。如果驗證失敗,您將收到類似以下範例的錯誤:

「伺服器錯誤:撥號後端錯誤:遠端錯誤:tls:內部錯誤」

檢查網路連線問題

確定 API 伺服器可以透過 1025 連接埠與工作節點通訊。工作節點安全群組必須允許來自 10250 連接埠上叢集安全群組的傳入流量。叢集安全群組必須允許來自 443 連接埠上工作節點安全群組的傳入流量。請確定您的安全群組符合 Amazon EKS 要求

檢查 CSR 問題

如果控制面板未核准 kubelet 提交的憑證簽署請求 (CSR),kubelet 就無法運作。

若要識別有問題的 CSR,請執行下列命令:

kubectl get certificatesigningrequest

若要檢查 CSR 請求的狀態,請執行下列命令:

kubectl describe certificatesigningrequest csr-name -n namespace

**注意:**將 csr-name 替換為 CSR 名稱,將 namespace 替換為命名空間名稱。

在輸出中,檢查 CSR 是否處於擱置中已核准狀態,而不是已核准並已發行狀態。

您必須在 kubelet 中啟動 RotateKubeletServerCertificateServerTLSBootstrap 旗標,以便 kubelet 為自己提交和輪換服務憑證。若要檢查 kubelet-config JSON 檔案中的旗標是否設為 true,請在工作節點內執行下列命令:

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 設定為叢集驗證模式,請檢查您的組態。確定工作節點 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 格式。如果您為工作節點使用與建立叢集相同的 IAM 角色,那麼請求者可能會是 kubernetes-admin 而不是 system:node:EC2PrivateDNSName。Amazon EKS 會拒絕不是來自 system:node:EC2PrivateDNSName 的請求。如果您將工作節點角色對應到 aws-auth 中的自訂使用者名稱,請確定您已正確地將工作節點角色對應到 system:node:EC2PrivateDNSName

檢查 kubelet 日誌

若要檢查 kubelet 的狀態,請執行下列命令:

systemctl status kubelet

如果輸出顯示 kubelet 狀態為停止,請執行下列命令以重新啟動 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 旗標。若要收集工作節點日誌進行詳細分析,請使用 GitHub 網站上的 log-collector-script

檢查控制平面日誌

先決條件:允許 Amazon EKS 叢集將控制平面日誌傳送至 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 逾時」

若要解決此問題,請將叢集端點存取權變更公有存取權。如果您必須擁有私有叢集,請在叢集的 VPC 中建立 Amazon Elastic Compute Cloud (Amazon EC2) 堡壘主機。然後,使用堡壘主機來存取叢集。您必須將堡壘主機的安全群組新增至叢集的安全群組。

檢查您的主機和連接埠組態

如果您收到與伺服器 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 使用者和角色提供叢集存取權?

檢查控制平面和工作節點安全群組規則

如果您的控制平面和節點安全群組規則禁止對 API 伺服器的存取,那麼您會收到以下錯誤訊息:

「與伺服器 APISERVERENDPOINT 的連線遭拒 - 您是否指定了正確的主機或連接埠?」

若要解決此問題,請確定控制平面和節點安全群組具有必要的傳入和傳出規則。API 伺服器安全群組必須允許來自連接埠 443 上 API 伺服器用戶端的傳入存取。

您無法安裝 kubectl

您必須使用與叢集相差不超過一個次要版本的 kubectl 版本。例如,v1.31 用戶端可以與控制平面版本 v1.30、v1.31 和 v1.32 進行通訊。為避免發生問題,請安裝最新相容版本的 kubectl

安裝 kubectl 時,您可能會收到下列其中一個錯誤:

「錯誤:執行外掛程式:無效的apiVersion "client.authentication.k8s.io/v1alpha1"

- 或 -

「無法連接到伺服器:取得憑證:解碼標準輸出:在配置 "pkg/client/auth/exec/exec.go:62" 中,版本 "client.authentication.k8s.io/v1alpha1" 未註冊任何 "ExecCredential" 類型」

當您使用早期版本的 AWS CLI 執行 update-kubeconfig 命令時,通常會發生上述錯誤。若要解決此問題,請依照更新 AWS CLI 的步驟操作。如需詳細資訊,請參閱 GitHub 網站上的淘汰 Kubernetes 用戶端 API 版本 v1alpha1

執行 kubectl 命令時遇到授權錯誤

執行 kubectl 命令時,您可能會遇到下列錯誤:

「錯誤: 您必須登入伺服器 (未經授權)」

若要解決此問題,請參閱如何解決當我連線至 Amazon EKS API 伺服器時,出現的「您必須登入伺服器 (未經授權)」錯誤?

AWS 官方已更新 9 個月前