Amazon EKS のポッドステータスをトラブルシューティングする方法を教えてください。
Amazon Elastic Compute Cloud (Amazon EC2) インスタンスまたはマネージドノードグループで実行されている Amazon Elastic Kubernetes Service (Amazon EKS) ポッドがスタックしています。ポッドを「実行中」または「終了」状態にしたいと考えています。
解決策
**重要:**次のステップは、Amazon EC2 インスタンスまたはマネージドノードグループで起動されたポッドにのみ適用されます。これらの手順は、AWS Fargate で起動されたポッドには適用されません。
ポッドのステータスを確認します
Amazon EKS のポッドステータスをトラブルシューティングするには、次の手順を実行します。
-
Pod のステータスを取得するには、以下のコマンドを実行します。
$ kubectl get pod
-
ポッドのイベント履歴から情報を取得するには、次のコマンドを実行します:
$ kubectl describe pod YOUR_POD_NAME
-
ポッドのステータスに基づいて、次のセクションの手順を実行します。
ポッドは保留状態です
注: 次のステップのサンプルコマンドは、デフォルトの名前空間にあります。他の名前空間の場合は、コマンドに-n YOURNAMESPACE を追加してください。
リソースが不足していたり、hostPortを定義したことが原因で、ポッドが保留状態のままになることがあります。詳細については、Kubernetes ウェブサイトの「ポッドフェーズ」を参照してください。
ワーカーノードのリソースが不十分な場合は、不要なポッドを削除してください。ワーカーノードにさらにリソースを追加することもできます。クラスターに十分なリソースがない場合は、Kubernetes Cluster Autoscaler を使用してワーカーノードグループを自動的にスケーリングします。
CPU 不足の例:
$ kubectl describe pod frontend-cpu Name: frontend-cpu ... Status: Pending ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 22s (x14 over 13m) default-scheduler 0/3 nodes are available: 3 Insufficient cpu.
メモリ不足の例:
$ kubectl describe pod frontend-memory Name: frontend-memory ... Status: Pending ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 80s (x14 over 15m) default-scheduler 0/3 nodes are available: 3 Insufficient memory.
ポッドに hostPort を定義した場合は、以下のベストプラクティスに従ってください。
- hostIP、hostPort、およびプロトコルの組み合わせは一意でなければならないため、hostPort は必要な場合にのみ指定してください。
- hostPort を指定する場合は、ワーカーノードの数と同じ数のポッドをスケジュールします。
注: ポッドを hostPort にバインドする場合、ポッドをスケジュールできる場所は限られています。
次の例は、保留状態のポッド frontend-port-77f67cff67-2bv7w の describe コマンドの出力を示しています。要求されたホストポートがクラスター内のワーカーノードで使用できないため、ポッドはスケジュールされません:
$ kubectl describe pod frontend-port-77f67cff67-2bv7w Name: frontend-port-77f67cff67-2bv7w ... Status: Pending IP: IPs: <none> Controlled By: ReplicaSet/frontend-port-77f67cff67 Containers: app: Image: nginx Port: 80/TCP Host Port: 80/TCP ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 11s (x7 over 6m22s) default-scheduler 0/3 nodes are available: 3 node(s) didn't have free ports for the requested pod ports.
ポッドでは許可されないテイントがノードにあるためにポッドをスケジュールできない場合、出力例は次のようになります。
$ kubectl describe pod nginx Name: nginx ... Status: Pending ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 8s (x10 over 9m22s) default-scheduler 0/3 nodes are available: 3 node(s) had taint {key1: value1}, that the pod didn't tolerate.
ノードのテイントを確認するには、次のコマンドを実行します。
$ kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
ノードのテイントを維持するには、PodSpec でポッドの許容値を指定します。詳細については、Kubernetes ウェブサイトの「コンセプト」を参照してください。または、テイント値の末尾に**-** を追加してノードテイントを削除します。
$ kubectl taint nodes NODE_Name key1=value1:NoSchedule-
ポッドがまだ「保留中」状態の場合は、「その他のトラブルシューティング」セクションの手順を実行してください。
コンテナは待機状態です
Docker イメージが正しくないか、リポジトリ名が正しくないため、コンテナが待機状態になっている可能性があります。または、イメージが存在しないか、権限がないために、ポッドが待機状態になっている可能性があります。
イメージとリポジトリ名が正しいことを確認するには、Docker Hub、Amazon Elastic Container Registry (Amazon ECR)、または別のコンテナイメージリポジトリにログインします。リポジトリのリポジトリまたはイメージを、ポッド仕様で指定されているリポジトリまたはイメージ名と比較します。画像が存在しない場合や権限がない場合は、次の手順を実行してください:
-
指定したイメージがリポジトリで利用可能であること、およびイメージをプルできるように正しい権限が設定されていることを確認します。
-
イメージをプルできること、および一般的なネットワークやリポジトリ権限の問題がないことを確認するには、イメージを手動でプルします。Amazon EKS ワーカーノードからイメージを取得するには、Docker を使用する必要があります:
$ docker pull yourImageURI:yourImageTag
-
イメージが存在することを確認するには、イメージとタグの両方が Docker Hub または Amazon ECR にあることを確認します。
注: Amazon ECR を使用している場合は、リポジトリポリシーで NodeInstanceRole のイメージプルが許可されていることを確認してください。または、AmazonEC2ContainerRegistryReadOnly ロールがポリシーにアタッチされていることを確認してください。
次の例は、イメージプルエラーのためにポッドが 保留 状態で、コンテナが 待機 状態になっていることを示しています:
$ kubectl describe po web-test Name: web-test ... Status: Pending IP: 192.168.1.143 Containers: web-test: Container ID: Image: somerandomnonexistentimage Image ID: Port: 80/TCP Host Port: 0/TCP State: Waiting Reason: ErrImagePull ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 66s default-scheduler Successfully assigned default/web-test to ip-192-168-6-51.us-east-2.compute.internal Normal Pulling 14s (x3 over 65s) kubelet, ip-192-168-6-51.us-east-2.compute.internal Pulling image "somerandomnonexistentimage" Warning Failed 14s (x3 over 55s) kubelet, ip-192-168-6-51.us-east-2.compute.internal Failed to pull image "somerandomnonexistentimage": rpc error: code = Unknown desc = Error response from daemon: pull access denied for somerandomnonexistentimage, repository does not exist or may require 'docker login' Warning Failed 14s (x3 over 55s) kubelet, ip-192-168-6-51.us-east-2.compute.internal Error: ErrImagePull
コンテナがまだ待機状態の場合は、「その他のトラブルシューティング」セクションの手順を実行してください。
ポッドは CrashLoopBackOff 状態です
「コンテナのバックオフ再起動に失敗しました」という出力メッセージが表示された場合は、Kubernetes がコンテナを起動した直後にコンテナが終了した可能性があります。
現在のポッドのログでエラーを探すには、以下のコマンドを実行します:
$ kubectl logs YOUR_POD_NAME
クラッシュした以前のポッドのログでエラーを探すには、次のコマンドを実行します:
$ kubectl logs --previous YOUR-POD_NAME
マルチコンテナポッドの場合は、最後にコンテナ名を追加します。例:
$ kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]
ライブネスプローブが「成功」ステータスを返さない場合は、ライブネスプローブがアプリケーション用に正しく設定されていることを確認してください。詳細については、Kubernetes Web サイトの「プローブの設定」を参照してください。
次の例は、アプリケーションが起動後に終了するため、ポッドが CrashLoopBackOff 状態になっていることを示しています:
$ kubectl describe pod crash-app-b9cf4587-66ftw Name: crash-app-b9cf4587-66ftw ... Containers: alpine: Container ID: containerd://a36709d9520db92d7f6d9ee02ab80125a384fee178f003ee0b0fcfec303c2e58 Image: alpine Image ID: docker.io/library/alpine@sha256:e1c082e3d3c45cccac829840a25941e679c25d438cc8412c2fa221cf1a824e6a Port: <none> Host Port: <none> State: Waiting Reason: CrashLoopBackOff Last State: Terminated Reason: Completed Exit Code: 0 Started: Tue, 12 Oct 2021 12:26:21 +1100 Finished: Tue, 12 Oct 2021 12:26:21 +1100 Ready: False Restart Count: 4 ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Started 97s (x4 over 2m25s) kubelet Started container alpine Normal Pulled 97s kubelet Successfully pulled image "alpine" in 1.872870869s Warning BackOff 69s (x7 over 2m21s) kubelet Back-off restarting failed container Normal Pulling 55s (x5 over 2m30s) kubelet Pulling image "alpine" Normal Pulled 53s kubelet Successfully pulled image "alpine" in 1.858871422s
ポッドで失敗するライブネスプローブの例を以下に示します:
$ kubectl describe pod nginx Name: nginx ... Containers: nginx: Container ID: containerd://950740197c425fa281c205a527a11867301b8ec7a0f2a12f5f49d8687a0ee911 Image: nginx Image ID: docker.io/library/nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506 Port: 80/TCP Host Port: 0/TCP State: Waiting Reason: CrashLoopBackOff Last State: Terminated Reason: Completed Exit Code: 0 Started: Tue, 12 Oct 2021 13:10:06 +1100 Finished: Tue, 12 Oct 2021 13:10:13 +1100 Ready: False Restart Count: 5 Liveness: http-get http://:8080/ delay=3s timeout=1s period=2s #success=1 #failure=3 ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Pulled 2m25s kubelet Successfully pulled image "nginx" in 1.876232575s Warning Unhealthy 2m17s (x9 over 2m41s) kubelet Liveness probe failed: Get "http://192.168.79.220:8080/": dial tcp 192.168.79.220:8080: connect: connection refused Normal Killing 2m17s (x3 over 2m37s) kubelet Container nginx failed liveness probe, will be restarted Normal Pulling 2m17s (x4 over 2m46s) kubelet Pulling image "nginx"
ポッドがまだ CrashLoopBackOff 状態にある場合は、「その他のトラブルシューティング」セクションの手順を実行してください。
ポッドは終了状態です
ポッドが終了状態のままになっている場合は、そのポッドが実行されているノードとファイナライザーの状態を確認してください。ファイナライザーは、ポッドが終了に移行する前に終了処理を実行する関数です。詳細については、Kubernetes ウェブサイトの「ファイナライザー」を参照してください。終了しているポッドのファイナライザーを確認するには、以下のコマンドを実行します:
$ kubectl get po nginx -o yaml apiVersion: v1 kind: Pod metadata: ... finalizers: - sample/do-something ...
前の例では、ファイナライザーの sample/do-something が削除された後にのみ Pod が 終了 に移行します。通常、カスタムコントローラーはファイナライザーを処理してから削除します。その後、ポッドは「終了」状態に移行します。
この問題を解決するには、カスタムコントローラーのポッドが正しく動作しているかどうかを確認してください。コントローラーのポッドに関する問題を解決し、カスタムコントローラーにファイナライザープロセスを完了させます。その後、ポッドは自動的に「終了」状態に移行します。または、次のコマンドを実行してファイナライザーを直接削除します:
$ kubectl edit po nginx
その他のトラブルシューティング
それでもポッドが動かなくなった場合は、次の手順を実行してください:
-
ワーカーノードがクラスター内にあり、準備完了状態であることを確認するには、次のコマンドを実行します:
$ kubectl get nodes
ノードのステータスが「NotReady」の場合は、「ノードのステータスを「NotReady」または「Unknown」ステータスから「Ready」ステータスに変更する方法」を参照してください。ノードがクラスターに参加できない場合は、「ワーカーノードを Amazon EKS クラスターに参加させるにはどうすればよいですか?」を参照してください。
-
Kubernetes クラスターのバージョンを確認するには、次のコマンドを実行します:
$ kubectl version --short
-
Kubernetes ワーカーノードのバージョンを確認するには、次のコマンドを実行します:
$ kubectl get node -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion
-
クラスターの Kubernetes サーバーのバージョンが、許容できるバージョンスキューの範囲内でワーカーノードのバージョンと一致していることを確認します。詳細については、Kubernetes Web サイトの「バージョンスキューポリシー」を参照してください。
重要: パッチバージョンは、クラスターとワーカーノード間で異なる場合があります。たとえば、クラスターの場合は v1.21.x、ワーカーノードの場合は v1.21.y です。クラスターとワーカーノードのバージョンに互換性がない場合は、eksctl または AWS CloudFormation を使用して新しいノードグループを作成します。または、互換性のある Kubernetes バージョンを使用して、Kubernetes: v1.21、platform: eks.1 以降などの新しいマネージドノードグループを作成します。次に、互換性のない Kubernetes バージョンを含むノードグループを削除します。 -
Kubernetes コントロールプレーンがワーカーノードと通信できることを確認します。ファイアウォールルールを Amazon EKS セキュリティグループの要件と考慮事項の必須ルールと照合してください。次に、ノードが Ready ステータスになっていることを確認します。
関連するコンテンツ
- 質問済み 4年前lg...
- AWS公式更新しました 2年前
- AWS公式更新しました 2年前
- AWS公式更新しました 1年前