スキップしてコンテンツを表示

Amazon EKS で kubectl コマンドを実行できない理由を知りたいです。

所要時間4分
0

Amazon Elastic Kubernetes Service (Amazon EKS) で kubectl exec、kubectl logs、kubectl get pods、kubectl get nodes などの kubectl コマンドを実行できません。

簡単な説明

kubectl コマンドを実行しようとすると、次の問題が発生する可能性があります。

  • kubectl execkubectl logskubectl attach、または kubectl 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 との信頼済み接続を確立する必要があります。認証に失敗すると、次の例のようなエラーが発生します。

「Error from server: error dialing backend: remote error: tls: internal error」

ネットワーク接続の問題が発生していないか確認する

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 の状態が Approved, Issued ではなく、Pending または Approved になっているかどうかを確認します。

kubelet がサービスを行う証明書を送信し、自身でローテーションできるようにするには、RotateKubeletServerCertificate および ServerTLSBootstrap フラグを有効にする必要があります。kubelet-config JSON ファイル内のフラグが true に設定されているかどうかを確認するには、ワーカーノード内から次のコマンドを実行します。

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

出力例

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

kubelet が CSR を作成して送信するには、eks:node-bootstrapper ロールを system:bootstrappers および system:nodes グループにアタッチする必要があります。ClusterRole および ClusterRoleBindingeks: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-rolesystem:bootstrappers および system:nodes グループにアタッチする必要があります。次の形式で、instance-roleaws-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 ロールを使用する場合は、リクエスタは system:node:EC2PrivateDNSName ではなく、kubernetes-admin になっている可能性があります。Amazon EKS は、system:node:EC2PrivateDNSName 以外からのリクエストを拒否します。ワーカーノードのロールを aws-auth でカスタムユーザー名にマッピングした場合は、ワーカーノードのロールが 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 フラグを使用します。詳細な分析を行うためにワーカーノードログを収集するには、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] couldn't get current server API group list: Get "APISERVERENDPOINT": dial tcp 11.11.111.111:443: i/o timeout」

この問題を解決するには、クラスターのエンドポイントアクセスパブリックアクセスに変更します。プライベートクラスターが必要な場合は、クラスターの VPC 内に Amazon Elastic Compute Cloud (Amazon EC2) 踏み台ホストを作成します。次に、その踏み台ホストを使用してクラスターにアクセスします。踏み台ホストのセキュリティグループをクラスターのセキュリティグループに追加する必要があります。

ホストとポートの設定を確認する

The connection to the server localhost:8080 was refused というエラーメッセージが表示される場合は、ホストとポートの設定を確認します。このエラーは通常、kubectl が kubeconfig ファイル内の Amazon EKS APIサーバーエンドポイントの正しいポートとホスト情報を見つけられない場合に発生します。

この問題を解決するには、次の手順を実行します。

  1. kubeconfig ファイルを更新するには、次の AWS CLI コマンド update-kubeconfig を実行します。

    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

詳細については、「Amazon EKS でクラスターを作成した後に、他の IAM ユーザーやロールにクラスターへのアクセスを付与する方法を教えてください」を参照してください。

コントロールプレーンとワーカーノードのセキュリティグループのルールを確認する

コントロールプレーンとノードにおいて、セキュリティグループのルールが API サーバーへのアクセスをブロックしている場合、次のエラーが発生します。

「The connection to the server APISERVERENDPOINT was refused - did you specify the right host or port?」

この問題を解決するには、コントロールプレーンとノードのセキュリティグループに必要なインバウンドルールとアウトバウンドルールがあることを確認してください。API サーバーのセキュリティグループは、API サーバークライアントからのインバウンドアクセスをポート 443 で許可する必要があります。

kubectl をインストールできない

クラスターとのマイナーバージョン差が 1 以内である kubectl バージョンを使用する必要があります。たとえば、v1.31 クライアントはコントロールプレーンバージョン v1.30、v1.31、v1.32 と通信できます。問題を回避するには、互換性のある最新バージョンの kubectl をインストールしてください。

kubectl のインストール時に、次のいずれかのエラーが発生することがあります。

「error: exec plugin: invalid apiVersion "client.authentication.k8s.io/v1alpha1"

または、

「Unable to connect to the server: getting credentials: decoding stdout: no kind "ExecCredential" is registered for version "client.authentication.k8s.io/v1alpha1" in scheme "pkg/client/auth/exec/exec.go:62"」

上記のエラーは通常、過去のバージョンの AWS CLI を使用して update-kubeconfig コマンドを実行した場合に発生します。この問題を解決するには、AWS CLI を更新してください。詳細については、GitHub のウェブサイトで「Kubernetes クライアント API バージョン v1alpha1 の廃止」を参照してください。

kubectl コマンドの実行時に認証エラーが発生する

kubectl コマンドの実行時に、次のエラーが発生することがあります。

「error: You must be logged in to the server (Unauthorized)」

この問題の解決方法については、「Amazon EKS API サーバーへの接続時に、You must be logged in to the server (Unauthorized) というエラーが発生する場合の解決方法を教えてください」を参照してください。

AWS公式更新しました 8ヶ月前
コメントはありません

関連するコンテンツ