Amazon EKS クラスターで Liveness Probe と Readiness Probe の問題をトラブルシューティングするにはどうすればよいですか?

所要時間4分
0

Amazon Elastic Kubernetes Service (Amazon EKS) クラスターの Liveness Probe と Readiness Probe に関連する問題をトラブルシューティングしたいと考えています。

簡単な説明

ワーカーノードで実行されている kubelet は、Probe を使用してポッドのステータスを定期的にチェックします。Kubernetes は現在、Probe の 3 つの状態 (成功、失敗、不明) をサポートしています。kubelet は、次の条件下でポッドが成功または正常であるとみなします。

  • コンテナ内で実行されているアプリケーションの準備が整っている。
  • アプリケーションはトラフィックを受け入れており、ポッドマニフェストで定義されている Probe に応答している。

Probe が応答しない場合、kubelet はアプリケーションポッドに障害が発生したか、または異常があるとみなします。その後、kubelet はこのポッドを異常とマークし、SIGTERM をポッドに送信します。デプロイで定義されているライフサイクルポリシーと restartPolicy に基づいて次のいずれかが発生します。

  • ポッドが直ちに終了する。
  • ポッドがトラフィックの受け入れを停止すると正常にシャットダウンする。

例:

spec:
 containers:
 - name: "example-container"
  image: "example-image"
  lifecycle:
   preStop:
    exec:
     command: ["sh", "-c", "sleep 10"]

この例では、example-pod 内で実行される example-container が Probe に応答しないことで異常になった場合、ポッドは 10 秒以内にトラフィックの受け入れを停止します。その後、kubelet はポッドを正常にシャットダウンします。30 秒経ってもポッドが終了しない場合、kubelet はポッドを強制的に削除します。kubelet がデプロイマニフェストで定義されている Probe を使用してポッドのステータスを判断できない場合、kubelet はアプリケーションポッドを不明とみなします。この場合、kubelet は追加のチェックを実行してポッドのステータスを判断します。

Kubernetes は、Liveness Probe、Readiness Probe、Startup Probe の Probe チェックを提供します。

  • kubelet は Liveness Probe を使用して、ポッド内で実行されているアプリケーションの状態を把握します。
  • kubelet は Readiness Probe を使用して、アプリケーションが着信トラフィックの処理を開始する準備ができたことを把握します。
  • kubelet は、ポッド内の起動の遅いアプリケーションのために Startup Probe を使用します。Startup Probe を設定すると、起動が成功したとみなされるまで、Liveness Probe と Readiness Probe はポッドをチェックしません。

ポッドマニフェストでこれらの Probe のいずれも定義されていない場合、kubelet はポッドを無期限に成功または正常とマークします。ポッドの状態をチェックするために、次のいずれかの Probe を設定できます。

  • HTTP Probe
  • Command Probe
  • TCP ソケット Probe
  • gRPC Probe

解決方法

クライアントタイムアウトによるアプリケーションヘルスチェック失敗エラー

Liveness Probe または Readiness Probe が失敗すると、次のエラーメッセージが表示されます。

Liveness probe failed: Get "http://podIP:8080/health ": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

Readiness probe failed: Get "http://podIP:8080/health ": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

これらのエラーをトラブルシューティングするには、次を実行します。

アプリケーションポッドのために Liveness Probe と Readiness Probe が正しく設定されているかどうかを確認します。

Amazon Virtual Private Cloud (Amazon VPC) CNI バージョン 1.11.0 以降を使用している場合は、aws-node DaemonSet[POD_SECURITY_GROUP_ENFORCING_MODE][standard] (標準) に設定されていることを確認してください。この設定が間違っている場合は、次のコマンドを実行します。

kubectl set env daemonset aws-node -n kube-system POD_SECURITY_GROUP_ENFORCING_MODE=standard

次の条件に当てはまる場合は、initcontainers の下のコンテナである amazon-k8s-cni-init について、[DISABLE_TCP_EARLY_DEMUX] を必ず [true] に設定してください。

  • バージョン 1.11.0 よりも前の Amazon VPC CNI バージョンを使用している。
  • ポッドにはセキュリティグループが設定されている。
  • ENABLE_POD_ENI が [true] に設定されている。
kubectl patch daemonset aws-node -n kube-system \
-p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'

Amazon VPC CNI 障害エラー

aws-node DaemonSet は次のエラーで失敗する可能性があります。

Liveness probe failed: OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: read init-p: connection reset by peer: unknown
Warning  Unhealthy  11m (x3 over 12m)    kubelet            Liveness probe failed:
Normal   Killing    11m                  kubelet            Container aws-node failed liveness probe, will be restarted

Readiness probe failed: OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: process_linux.go:99: starting setns process caused: fork/exec /proc/self/exe: resource temporarily unavailable: unknown
Warning  Unhealthy  11m (x9 over 13m)    kubelet            Readiness probe failed:

これらのエラーは、aws-node DaemonSet で [timeoutSeconds] の値を 60 秒に増やすことで解決できます。

VPC CNI のフィールドの現在の値を表示するには、次のコマンドを実行します。

$kubectl get daemonset aws-node -n kube-system -o yaml

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

"livenessProbe":
          exec:
            command:
            - /app/grpc-health-probe
            -addr=:50051
            -connect-timeout=5s
            -rpc-timeout=5s
          failureThreshold: 3
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 60

アプリケーション接続エラー

カスタムアプリケーションポッドで describe コマンドを実行する場合、ポッドが Liveness Probe と Readiness Probe のチェックに失敗すると、次のエラーが表示されます。

2m 25s Warning  Unhealthy  Liveness probe failed: Get "http://podIP:8081/health ": dial tcp 192.168.187.28: 8081: connect: connection refused

2m 25s Warning  Unhealthy   Readiness probe failed: Get "http:// podIP:8081/health": dial tcp 192.168.187.28:8081: connect: connection refused

Warning  Unhealthy  39s (x4 over 2m19s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 500

Warning  Unhealthy  29s (x5 over 2m19s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 500

このエラーをトラブルシューティングするには、次を実行します。

1.    ポッドマニフェストで定義されているヘルスチェックパスをワーカーノードから手動で curl します。

[ec2-user@ip-10-0-0-11 ~]$ curl -ikv podIP:8081/health

2.    Liveness Probe または Readiness Probe に失敗したアプリケーションポッドに Exec を実行します。その後、ポッドマニフェストで定義されているヘルスチェックパスを curl します。

local@bastion-host ~ % kubectl exec <pod-name> -- curl  -ikv "http://localhost:8081/_cluster/health?"

3.    ポッドが実行されているワーカーノードの kubelet ログにエラーがないかどうかを確認します。

[ec2-user@ip-10-0-0-11 ~]$ journalctl -u kubelet //optionally 'grep' with pod name

4.    ポッドで describe pod コマンドを実行し、ポッドで実行されているコンテナの現在のステータスを確認します。また、ポッドのログも確認します。

$ kubectl describe pod <pod name> -n <namespace>

$ kubectl logs <pod name>

5.    それでもエラーに関する情報が得られない場合は、ワーカーノードで実行されている基盤となる kubelet の詳細度を上げることを検討してください。

$ sudo systemctl status kubelet
$ vi /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf 
   [Service]
   Environment='KUBELET_ARGS=--node-ip=192.168.31.211 --pod-infra-container-image=602401143452.dkr.ecr.us-east-2.amazonaws.com/eks/pause:3.5 --v=2'

設定ファイルで、--v=2--v=9 に変更し、ファイルを保存します。

変更を有効にするには、kubelet を再起動します。

$ sudo systemctl daemon-reload && sudo systemctl restart kubelet && sudo systemctl enable kubelet

kubelet の詳細度を確認するには、次のコマンドを実行します。

$ systemctl status kubelet -l

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

CGroup: /system.slice/kubelet.service 
       └─5909 /usr/bin/kubelet --cloud-provider aws --config /etc/kubernetes/kubelet/kubelet-config.json --kubeconfig /var/lib/kubelet/kubeconfig --container-runtime docker --network-plugin cni --node-ip=10.0.0.11 --pod-infra-container-image=602401143452.dkr.ecr.us-east-1.amazonaws.com/eks/pause:3.1-eksbuild.1 --v=9

Liveness または Readiness のチェックで障害が発生したポッドを再起動します。その後、前述の変更が行われた Amazon EKS ワーカーノードでこのポッドがデプロイされていることを確認します。次のコマンドを実行すると、kubelet のログを確認できます。

$ journalctl -u kubelet //optionally 'grep' with pod name

6.    踏み台ホストで同じコンテナイメージを実行し、マニフェストの Probe で定義されているヘルスチェックパスを curl できるかどうかを確認します。また、コンテナのログも確認します。

7.    HTTP Probe の場合は、カスタム HTTP ヘッダーが正しく設定されているかどうかを確認します。kubelet は curl と同等の golang のコードを使用してポッドを HTTP テストします。

例:

"livenessProbe":
   httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

8.    exec Probe を使用している場合は、ポッドが正しく設定されているかどうかを確認します。次の例では、ポッドは 30 秒間通過し、その後失敗します。

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

AWS公式
AWS公式更新しました 2年前
コメントはありません

関連するコンテンツ