Amazon EKS のロードバランサーのヘルスチェックが失敗した場合の解決方法を教えてください。
ロードバランサーが Amazon Elastic Kubernetes サービス (Amazon EKS) のヘルスチェックに失敗します。
解決策
Amazon EKS のロードバランサーのヘルスチェックに関する問題をトラブルシューティングするには、以下のセクションのステップを実行します。
ポッドのステータスを確認する
ポッドが「実行中」ステータスで、ポッド内のコンテナの準備が整っているかどうかを確認します。
$ kubectl get pod -n YOUR_NAMESPACE
**注:**YOUR_NAMESPACE は、Kubernetes の名前空間に置き換えてください。
出力例:
NAME READY STATUS RESTARTS AGEpodname 1/1 Running 0 16s
ポッドのステータスにあるアプリケーションコンテナが「実行中」でない場合、ロードバランサーのヘルスチェックは応答せずに失敗します。
ポッドとサービスラベルセレクターを確認してください
ポッドラベルの場合は、以下のコマンドを実行します。
$ kubectl get pod -n YOUR_NAMESPACE --show-labels
出力例:
NAME READY STATUS RESTARTS AGE LABELSalb-instance-6cc5cd9b9-prnxw 1/1 Running 0 2d19h app=alb-instance,pod-template-hash=6cc5cd9b9
Kubernetes Service がポッドラベルを使用していることを確認するには、次のコマンドを実行して、出力がポッドラベルと一致することを確認します。
$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath='{.spec.selector}{"\n"}'
**注:**SERVICE_NAME は Kubernetes Service に、**YOUR_NAMESPACE ** は Kubernetes の名前空間に置き換えてください。
出力例:
{"app":"alb-instance"}
見つからないエンドポイントを確認する
サービスセレクターの Kubernetes コントローラーは、セレクターと一致するポッドを継続的にスキャンし、エンドポイントオブジェクトに更新をポストします。間違ったラベルを選択した場合、エンドポイントは表示されません。
以下のコマンドを実行します。
$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE
出力例:
Name: alb-instanceNamespace: default Labels: <none> Annotations: <none> Selector: app=alb-instance-1 Type: NodePort IP Family Policy: SingleStack IP Families: IPv4 IP: 10.100.44.151 IPs: 10.100.44.151 Port: http 80/TCP TargetPort: 80/TCP NodePort: http 32663/TCP Endpoints: <none> Session Affinity: None External Traffic Policy: Cluster Events: <none>
不足しているエンドポイントがないか確認します。
$ kubectl get endpoints SERVICE_NAME -n YOUR_NAMESPACE
出力例:
NAME ENDPOINTS AGEalb-instance <none> 2d20h
Application Load Balancer の問題については、サービストラフィックポリシーとクラスターセキュリティグループを確認してください。
Application Load Balancer のターゲットグループ内の異常なターゲットは、次の 2 つの理由で発生します。
- サービストラフィックポリシーの spec.externalTrafficPolicy が、[クラスタ] ではなく [ローカル] に設定されている。
- クラスター内のノードグループにはそれぞれ異なるクラスターセキュリティグループが関連付けられており、トラフィックはノードグループ間を自由に流れることができません。
トラフィックポリシーが正しく設定されていることを確認します。
$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath='{.spec.externalTrafficPolicy}{"\n"}'
出力例:
Local
設定を [クラスタ] に変更します。
$ kubectl edit svc SERVICE_NAME -n YOUR_NAMESPACE
**クラスターセキュリティグループを確認する **
次の手順を実行します。
- Amazon EC2 コンソールを開きます。
- 正常なインスタンスを選択します。
- [セキュリティ] タブを選択し、セキュリティグループの進入ルールを確認します。
- 異常のあるインスタンスを選択します。
- [セキュリティ] タブを選択し、セキュリティグループの進入ルールを確認します。
各インスタンスのセキュリティグループが異なる場合は、セキュリティグループコンソールでセキュリティ進入ルールを変更する必要があります。
[セキュリティ] タブから、セキュリティグループ ID を選択します。
進入ルールを変更するには、[インバウンドのルールを編集] を選択します。
クラスター内の他のノードグループからのトラフィックを許可するインバウンドルールを追加します。
サービスが targetPort 用に設定されていることを確認する
targetPort は、サービスがトラフィックを送信するポッドの containerPort と一致する必要があります。
targetPort が何に設定されているかを確認するには、次のコマンドを実行します。
$ kubectl get svc SERVICE_NAME -n YOUR_NAMESPACE -o=jsonpath="{.items[*]}{.metadata.name}{'\t'}{.spec.ports[].targetPort}{'\t'}{.spec.ports[].protocol}{'\n'}"
出力例:
alb-instance 8080 TCP
出力例では、targetPortターゲットポートが 8080 に設定されています。ただし、containerPort は 80 に設定されているため、targetPort も 80 に設定する必要があります。
AWS Load Balancer Controller に正しい権限があることを確認する
AWS Load Balancer Controller には、ロードバランサーからインスタンスまたはポッドへのトラフィックを許可するようにセキュリティグループを更新するための正しい権限が必要です。正しい権限がないとエラーが表示されます。
AAWS Load Balancer Controller のデプロイログにエラーがないか確認します。
$ kubectl logs deploy/aws-load-balancer-controller -n kube-system
個々のコントローラーポッドのログにエラーがないか確認します。
$ kubectl logs CONTROLLER_POD_NAME -n YOUR_NAMESPACE
**注:**CONTROLLER_POD_NAME はコントローラーポッドの名前に、YOUR_NAMESPACE は Kubernetes 名前空間に置き換えてください。
Application Load Balancer に問題がないか、進入の注釈を確認する
Application Load Balancer の問題については、Kubernetes の Inguress アノテーションを確認してください。
$ kubectl describe ing INGRESS_NAME -n YOUR_NAMESPACE
**注:****INGRESS\ _NAME ** は Kubernetes Ingress の名前に置、YOUR_NAMESPACE は Kubernetes の名前空間に置き換えてください。
出力例:
Name: alb-instance-ingressNamespace: default Address: k8s-default-albinsta-fcb010af73-2014729787.ap-southeast-2.elb.amazonaws.com Default backend: alb-instance:80 (192.168.81.137:8080) Rules: Host Path Backends ---- ---- -------- awssite.cyou / alb-instance:80 (192.168.81.137:8080) Annotations: alb.ingress.kubernetes.io/scheme: internet-facing kubernetes.io/ingress.class: alb Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfullyReconciled 25m (x7 over 2d21h) ingress Successfully reconciled
ユースケースに固有の Ingress アノテーションを見つけるには、Kubernetes ウェブサイトの「Ingress annotations」を参照してください。
ネットワークロードバランサーの問題についてKubernetes Service のアノテーションを確認する
ネットワークロードバランサーの問題について、Kubernetes Service のアノテーションを確認します。
$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE
出力例:
Name: nlb-ipNamespace: default Labels: <none> Annotations: service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-type: external Selector: app=nlb-ip Type: LoadBalancer IP Family Policy: SingleStack IP Families: IPv4 IP: 10.100.161.91 IPs: 10.100.161.91 LoadBalancer Ingress: k8s-default-nlbip-fff2442e46-ae4f8cf4a182dc4d.elb.ap-southeast-2.amazonaws.com Port: http 80/TCP TargetPort: 80/TCP NodePort: http 31806/TCP Endpoints: 192.168.93.144:80 Session Affinity: None External Traffic Policy: Cluster Events: <none>
**注:**後のステップでヘルスチェックコマンドを実行するために、APPLICATION_POD_IP の値を書き留めておきます。
ユースケースに固有の Kubernetes サービスアノテーションを見つけるには、Kubernetes ウェブサイトの「Service annotations」を参照してください。
ヘルスチェックを手動でテストする
アプリケーションポッドの IP アドレスを確認します。
$ kubectl get pod -n YOUR_NAMESPACE -o wide
テストポッドを実行して、クラスター内のヘルスチェックを手動でテストします。
$ kubectl run -n YOUR_NAMESPACE troubleshoot -it --rm --image=amazonlinux -- /bin/bash
次に、HTTP ヘルスチェックを実行します。
# curl -Iv APPLICATION_POD_IP/HEALTH_CHECK_PATH
**注:**APPLICATION\ _POD\ _IP はアプリケーションポッドの IP アドレスに置き換え、HEALTH_CHECK_PATH は Application Load Balancer のターゲットグループのヘルスチェックパスに置き換えます。
コマンド例:
# curl -Iv 192.168.81.137
出力例:
* Trying 192.168.81.137:80...* Connected to 192.168.81.137 (192.168.81.137) port 80 (#0) > HEAD / HTTP/1.1 > Host: 192.168.81.137 > User-Agent: curl/7.78.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK HTTP/1.1 200 OK < Server: nginx/1.21.3 Server: nginx/1.21.3 < Date: Tue, 26 Oct 2021 05:10:17 GMT Date: Tue, 26 Oct 2021 05:10:17 GMT < Content-Type: text/html Content-Type: text/html < Content-Length: 615 Content-Length: 615 < Last-Modified: Tue, 07 Sep 2021 15:21:03 GMT Last-Modified: Tue, 07 Sep 2021 15:21:03 GMT < Connection: keep-alive Connection: keep-alive < ETag: "6137835f-267" ETag: "6137835f-267" < Accept-Ranges: bytes Accept-Ranges: bytes < * Connection #0 to host 192.168.81.137 left intact
HTTP 応答ステータスコードを確認します。応答ステータスコードが 200 OK の場合、アプリケーションはヘルスチェックパスに正しく応答します。
HTTP 応答ステータスコードが 3xx または ** 4xx** の場合は、ヘルスチェックパスを変更してください。次のアノテーションは 200 OK で応答します。
alb.ingress.kubernetes.io/healthcheck-path: /ping
または、
Ingress リソースに次のアノテーションを使用して、ヘルスチェック成功応答のステータスコード範囲を追加します。
alb.ingress.kubernetes.io/success-codes: 200-399
TCP ヘルスチェックでは、次のコマンドを使用して netcat コマンドをインストールします。
# yum update -y && yum install -y nc
TCP ヘルスチェックをテストします。
# nc -z -v APPLICATION_POD_IP CONTAINER_PORT_NUMBER
**注:**APPLICATION\ _POD\ _IP はアプリケーションポッドの IP アドレスに、CONTAINER\ _PORT\ _NUMBER はコンテナポートに置き換えます。
コマンド例:
# nc -z -v 192.168.81.137 80
出力例:
Ncat: Version 7.50 ( https://nmap.org/ncat ) Ncat: Connected to 192.168.81.137:80.Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds.
ネットワークを確認する
ネットワークの問題については、以下を確認してください。
- EKS クラスター内の複数のノードグループが、自由に相互通信できる。
- ポッドが実行されるサブネットに関連付けられているネットワークアクセスコントロールリスト (ネットワーク ACL) は、ロードバランサーのサブネット CIDR 範囲からのトラフィックを許可します。
- ロードバランサーのサブネットに関連付けられているネットワーク ACL では、ポッドが実行されているサブネットからのエフェメラルポート範囲への戻りトラフィックを許可します。
- ルートテーブルで、VPC CIDR 範囲内からのローカルトラフィックが許可されている。
kube-proxy を再起動する
各ノードで実行される kube-proxy が正しく機能しない場合、kube-proxy はサービスとエンドポイントの iptables ルールを更新できない可能性があります。kube-proxy を再起動して適用し、iptables ルールを再確認して更新します。
kubectl rollout restart daemonset.apps/kube-proxy -n kube-system
出力例:
daemonset.apps/kube-proxy restarted
関連情報
Amazon EKS の Kubernetes のサービスコントローラーによって作成されたロードバランサーに関する問題をトラブルシューティングする方法を教えてください。
Amazon EKS で Application Load Balancer が使用するサブネットを自動的に検出する方法を教えてください。
関連するコンテンツ
- 質問済み 1年前lg...
- 質問済み 7ヶ月前lg...
- 質問済み 2ヶ月前lg...
- AWS公式更新しました 10ヶ月前
- AWS公式更新しました 9ヶ月前