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

最終更新日: 2020 年 2 月 13 日

Amazon Elastic Compute Cloud (Amazon EC2) インスタンスまたはマネージドノードグループで実行されている Amazon Elastic Kubernetes Service (Amazon EKS) ポッドがスタックしています。実行状態のポッドを取得する方法を教えてください。

解決方法

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

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

1.    ポッドのイベント履歴から情報を取得するには、次のコマンドを実行します。

$ kubectl describe pod YOUR_POD_NAME

注: 以下の手順で説明するコマンドの例は、デフォルトの名前空間にあります。他の名前空間については、コマンドに -n YOURNAMESPACE を付けます。

2.    ポッドが Pending 状態ポッドが Waiting 状態、または ポッドが CrashLoopBackOff 状態 といったポッドのステータスに基づいて、以下のいずれかのセクションの手順を実行します。

ポッドが Pending 状態にある場合

Pending 状態のポッドは、ノードにスケジュールできません。

使用可能なワーカーノードに十分なリソースがないか、ポッドで専有 hostPort を定義したため、ポッドが Pending 状態になる可能性があります。

使用可能なワーカーノードに十分なリソースがない場合は、不要なポッドを削除するか、ワーカーノードを追加します。たとえば、ワーカーノードの CPU とメモリが不足する可能性があります。これが繰り返し発生する問題である場合、Kubernetes Cluster Autoscaler を使用して、クラスター内のリソースが不足しているときにワーカーノードグループを自動的にスケーリングできます。

ポッドの hostPort を定義している場合は、以下の点を考慮します。

(A) ポッドを hostPort にバインドするときに、ポッドをスケジュールできる場所の数は限られています。
(B) hostIPhostPortprotocol の組み合わせは一意でなければならないため、必要でない限り、hostPort を指定しないでください。
(C) hostPort を指定する必要がある場合は、ワーカーノードと同じ数のポッドをスケジュールします。

次の例は、Pending 状態にある my-nginx-12345abc6d-7e8fgdescribe コマンドの出力を示しています。リソースの制約のため、ポッドがスケジュールされていません。

$ kubectl describe pod my-nginx-86459cfc9f-2j5bq

Name:               my-nginx-12345abc6d-7e8fg
Namespace:          default
Priority:           0
PriorityClassName:  
Node:               
Labels:             pod-template-hash=86459cfc9f
                    run=my-nginx
Annotations:        kubernetes.io/psp: eks.privileged
Status:             Pending
...
Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  7s (x6 over 5m58s)  default-scheduler  0/2 nodes are available: 1 Insufficient pods, 1 node(s) had taints that the pod didn't tolerate.

前の手順を試してもポッドがまだ Pending 状態にある場合は、追加のトラブルシューティングセクションの手順を実行してください。

ポッドが Waiting 状態にある場合

Waiting 状態のポッドはワーカーノード (Amazon EC2 インスタンスなど) でスケジュールされていますが、そのノードでは実行できません。

Docker イメージまたはリポジトリ名が正しくない、アクセス許可がない、またはイメージが存在しないため、ポッドが Waiting 状態になる可能性があります。

Docker イメージまたはリポジトリ名が正しくない場合は、次の手順を実行してください。

1.    Docker Hub、Amazon Elastic Container Registry (Amazon ECR)、または別のコンテナイメージリポジトリにログインして、イメージ名とリポジトリ名が正しいことを確認します。

2.    リポジトリからのリポジトリまたはイメージを、ポッド仕様で指定されたリポジトリ名またはイメージ名と比較します。

イメージが存在しない場合、またはアクセス許可が不足している場合は、以下の手順を実行します。

1.    指定されたイメージがリポジトリで使用可能であり、イメージをプルできるように正しいアクセス許可が設定されていることを確認します。

2.    イメージのプルが可能であることを確認し、一般的なネットワークとリポジトリのアクセス許可の問題を防ぐには、Docker を使用して Amazon EKS ワーカーノードから手動でイメージをプルします。

$ docker pull yourImageURI:yourImageTag

3.    イメージが存在することを確認するには、Docker Hub または Amazon ECR にイメージとタグの両方が存在することを確認します。

注: Amazon ECR を使用している場合、リポジトリポリシーで NodeInstanceRole のイメージプルが許可されていることを確認します。または、AmazonEC2ContainerRegistryReadOnly ロールがポリシーにアタッチされていることを確認します。

次の例は、イメージプルエラーのため、ポッドが Pending 状態、そしてコンテナが Waiting 状態にあることを示しています。

$ kubectl describe po web-test

Name:               web-test
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               ip-192-168-6-51.us-east-2.compute.internal/192.168.6.51
Start Time:         Wed, 22 Jan 2020 08:18:16 +0200
Labels:             app=web-test
Annotations:        kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"web-test"},"name":"web-test","namespace":"default"},"spec":{...
                    kubernetes.io/psp: eks.privileged
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

前の手順を試してもポッドがまだ Waiting 状態にある場合は、追加のトラブルシューティングセクションの手順を実行してください。

ポッドが CrashLoopBackOff 状態にある場合

CrashLoopBackOff でスタックしているポッドは、繰り返し起動、クラッシュ、再起動、再度クラッシュします。

「Back-Off restarting failed container」という出力メッセージを受け取った場合、Kubernetes がコンテナを起動した直後にコンテナが終了した可能性があります。

現在のポッドのログでエラーを探すには、次のコマンドを実行します。

$ kubectl logs YOUR_POD_NAME

クラッシュした以前のポッドのログでエラーを探すには、次のコマンドを実行します。

$ kubectl logs --previous YOUR-POD_NAME

注: マルチコンテナポッドの場合、最後にコンテナ名を追加できます。例:

$ kubectl logs POD_NAME CONTAINER_NAME

Liveness プローブが成功ステータスを返さない場合、Liveness プローブがアプリケーションに対して正しく設定されていることを確認します。詳細については、「プローブの設定」を参照してください。

次の例は、アプリケーションが起動後に終了したため、CrashLoopBackOff の状態にあるポッドを示しています。

$ kubectl describe po crash-app-6847947bf8-28rq6

Name:               crash-app-6847947bf8-28rq6
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               ip-192-168-6-51.us-east-2.compute.internal/192.168.6.51
Start Time:         Wed, 22 Jan 2020 08:42:20 +0200
Labels:             pod-template-hash=6847947bf8
                    run=crash-app
Annotations:        kubernetes.io/psp: eks.privileged
Status:             Running
IP:                 192.168.29.73
Controlled By:      ReplicaSet/crash-app-6847947bf8
Containers:
  main:
    Container ID:  docker://6aecdce22adf08de2dbcd48f5d3d8d4f00f8e86bddca03384e482e71b3c20442
    Image:         alpine
    Image ID:      docker-pullable://alpine@sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
    Port:          80/TCP
    Host Port:     0/TCP
    Command:
      /bin/sleep
      1
    State:          Waiting
      Reason:       CrashLoopBackOff
...
Events:
  Type     Reason     Age                From                                                 Message
  ----     ------     ----               ----                                                 -------
  Normal   Scheduled  47s                default-scheduler                                    Successfully assigned default/crash-app-6847947bf8-28rq6 to ip-192-168-6-51.us-east-2.compute.internal
  Normal   Pulling    28s (x3 over 46s)  kubelet, ip-192-168-6-51.us-east-2.compute.internal  Pulling image "alpine"
  Normal   Pulled     28s (x3 over 46s)  kubelet, ip-192-168-6-51.us-east-2.compute.internal  Successfully pulled image "alpine"
  Normal   Created    28s (x3 over 45s)  kubelet, ip-192-168-6-51.us-east-2.compute.internal  Created container main
  Normal   Started    28s (x3 over 45s)  kubelet, ip-192-168-6-51.us-east-2.compute.internal  Started container main
  Warning  BackOff    12s (x4 over 42s)  kubelet, ip-192-168-6-51.us-east-2.compute.internal  Back-off restarting failed container

上記の手順を試してもポッドがまだ CrashLoopBackOff 状態にある場合は、追加のトラブルシューティングセクションの手順を完了します。

追加のトラブルシューティング

前のセクションの手順を完了してもまだポッドがスタックしている場合は、以下の手順を試してください。

1.    ワーカーノードがクラスターに存在し、ステータスが (ポッドをスケジュールできる) Ready になっていることを確認するには、次のコマンドを実行します。

$ kubectl get nodes

出力は次のようになります。

NAME                                          STATUS   ROLES    AGE   VERSION
ip-192-168-6-51.us-east-2.compute.internal    Ready    <none>   25d   v1.14.6-eks-5047ed
ip-192-168-86-33.us-east-2.compute.internal   Ready    <none>   25d   v1.14.6-eks-5047ed

ノードがクラスター内にない場合、ワーカーノードを追加します

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

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

$ kubectl version --short

出力は次のようになります。

Client Version: v1.14.6-eks-5047ed
Server Version: v1.14.9-eks-c0eccc

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

$ kubectl get node -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion

出力は次のようになります。

NAME                                          VERSION
ip-192-168-6-51.us-east-2.compute.internal    v1.14.6-eks-5047ed
ip-192-168-86-33.us-east-2.compute.internal   v1.14.6-eks-5047ed

4.    手順 2 と 3 の出力に基づいて、クラスターの Kubernetes サーバーのバージョンが、許容されるバージョンスキュー内のワーカーノードのバージョンと一致することを確認します。

重要: パッチのバージョンは異なる場合があります (たとえば、クラスターの v1.14.x とワーカーノードの v1.14.y)。

クラスターとワーカーノードのバージョンに互換性がない場合は、eksctl (eksctl タブを参照) または AWS CloudFormation (セルフマネージドノードタブを参照) で 新しいノードグループを作成します。

-- または --

互換性のある Kubernetes バージョンを使用して、新しいマネージドノードグループ (Kubernetes:v1.14、プラットフォーム:eks.3 以降) を作成します。次に、互換性のない Kubernetes バージョンのノードグループを削除します。

5.    Kubernetes コントロールプレーンがワーカーノードと通信できることを確認するには、ファイアウォールルールを Amazon EKS セキュリティグループに関する考慮事項の推奨ルールと照らし合わせて、ノードが Ready ステータスにあることを確認します。


この記事はお役に立ちましたか?

改善できることはありますか?


さらにサポートが必要な場合