Amazon EKS のポッドステータスをトラブルシューティングする方法を教えてください。

所要時間5分
0

Amazon Elastic Compute Cloud (Amazon EC2) インスタンスまたはマネージドノードグループで実行されている Amazon Elastic Kubernetes Service (Amazon EKS) ポッドがスタックしています。ポッドを「実行中」または「終了」状態にしたいと考えています。

解決策

**重要:**次のステップは、Amazon EC2 インスタンスまたはマネージドノードグループで起動されたポッドにのみ適用されます。これらの手順は、AWS Fargate で起動されたポッドには適用されません。

ポッドのステータスを確認します

Amazon EKS のポッドステータスをトラブルシューティングするには、次の手順を実行します。

  1. Pod のステータスを取得するには、以下のコマンドを実行します。

    $ kubectl get pod
  2. ポッドのイベント履歴から情報を取得するには、次のコマンドを実行します:

    $ kubectl describe pod YOUR_POD_NAME
  3. ポッドのステータスに基づいて、次のセクションの手順を実行します。

ポッドは保留状態です

注: 次のステップのサンプルコマンドは、デフォルトの名前空間にあります。他の名前空間の場合は、コマンドに-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 を定義した場合は、以下のベストプラクティスに従ってください。

  • hostIPhostPort、およびプロトコルの組み合わせは一意でなければならないため、hostPort は必要な場合にのみ指定してください。
  • hostPort を指定する場合は、ワーカーノードの数と同じ数のポッドをスケジュールします。

注: ポッドを hostPort にバインドする場合、ポッドをスケジュールできる場所は限られています。

次の例は、保留状態のポッド frontend-port-77f67cff67-2bv7wdescribe コマンドの出力を示しています。要求されたホストポートがクラスター内のワーカーノードで使用できないため、ポッドはスケジュールされません:

$ 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)、または別のコンテナイメージリポジトリにログインします。リポジトリのリポジトリまたはイメージを、ポッド仕様で指定されているリポジトリまたはイメージ名と比較します。画像が存在しない場合や権限がない場合は、次の手順を実行してください:

  1. 指定したイメージがリポジトリで利用可能であること、およびイメージをプルできるように正しい権限が設定されていることを確認します。

  2. イメージをプルできること、および一般的なネットワークやリポジトリ権限の問題がないことを確認するには、イメージを手動でプルします。Amazon EKS ワーカーノードからイメージを取得するには、Docker を使用する必要があります:

    $ docker pull yourImageURI:yourImageTag
  3. イメージが存在することを確認するには、イメージとタグの両方が 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

その他のトラブルシューティング

それでもポッドが動かなくなった場合は、次の手順を実行してください:

  1. ワーカーノードがクラスター内にあり、準備完了状態であることを確認するには、次のコマンドを実行します:

    $ kubectl get nodes

    ノードのステータスが「NotReady」の場合は、「ノードのステータスを「NotReady」または「Unknown」ステータスから「Ready」ステータスに変更する方法」を参照してください。ノードがクラスターに参加できない場合は、「ワーカーノードを Amazon EKS クラスターに参加させるにはどうすればよいですか?」を参照してください。

  2. Kubernetes クラスターのバージョンを確認するには、次のコマンドを実行します:

    $ kubectl version --short
  3. Kubernetes ワーカーノードのバージョンを確認するには、次のコマンドを実行します:

    $ kubectl get node -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion
  4. クラスターの Kubernetes サーバーのバージョンが、許容できるバージョンスキューの範囲内でワーカーノードのバージョンと一致していることを確認します。詳細については、Kubernetes Web サイトの「バージョンスキューポリシー」を参照してください。
    重要: パッチバージョンは、クラスターとワーカーノード間で異なる場合があります。たとえば、クラスターの場合は v1.21.x、ワーカーノードの場合は v1.21.y です。クラスターとワーカーノードのバージョンに互換性がない場合は、eksctl または AWS CloudFormation を使用して新しいノードグループを作成します。または、互換性のある Kubernetes バージョンを使用して、Kubernetes: v1.21、platform: eks.1 以降などの新しいマネージドノードグループを作成します。次に、互換性のない Kubernetes バージョンを含むノードグループを削除します。

  5. Kubernetes コントロールプレーンがワーカーノードと通信できることを確認します。ファイアウォールルールを Amazon EKS セキュリティグループの要件と考慮事項の必須ルールと照合してください。次に、ノードが Ready ステータスになっていることを確認します。

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

関連するコンテンツ