Amazon EKS で kubectl コマンドを実行できない理由を知りたいです。
Amazon Elastic Kubernetes Service (Amazon EKS) で kubectl exec、kubectl logs、kubectl get pods、kubectl get nodes などの kubectl コマンドを実行できません。
簡単な説明
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 との信頼済み接続を確立する必要があります。認証に失敗すると、次の例のようなエラーが発生します。
「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 および 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 をクラスター認証モードとして設定した場合は、設定を確認してください。ワーカーノードの 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サーバーエンドポイントの正しいポートとホスト情報を見つけられない場合に発生します。
この問題を解決するには、次の手順を実行します。
-
kubeconfig ファイルを更新するには、次の AWS CLI コマンド update-kubeconfig を実行します。
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
詳細については、「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) というエラーが発生する場合の解決方法を教えてください」を参照してください。
- トピック
- Containers
- 言語
- 日本語
