Amazon EKSでロードバランサーの失敗した健康チェックを解決するにはどうすればよいですか?
ロードバランサーが Amazon Elastic Kubernetes サービス (Amazon EKS) の健康チェックに失敗し続ける。
簡単な説明
Amazon EKS のロードバランサーに関する健康チェックの問題をトラブルシューティングするには、以下のセクションの処置を完了します:
- ポットのステータスをチェックしてください
- ポットとサービスラベルセレクターを確認してください
- 不明なエンドポイントがないか確認してください
- アプリケーションロードバランサー のサービストラフィックポリシーとクラスターセキュリティグループを確認してください
- EKS が targetPort 用に設定されていることを確認してください。
- AWS ロードバランサーコントローラーに正しい権限があることを確認してください。
- アプリケーションロードバランサーに関する問題がないか、Ingress アノテーションをチェックしてください。
- Kubernetes Service アノテーションでネットワークロードバランサーに関する問題を確認してください
- 健康チェックを手動で確かめてください
- ネットワークを確認してください
- kube-proxy を再起動します。
解決方法
ポットのステータスをチェックしてください
ポットが Running ステータスで、ポット 内のコンテナが準備完了であることを確認してください。
$ kubectl get pod -n YOUR_NAMESPACE
注: YOUR_NAMESPACE を自分の名前空間に置き換えてください。
出力例:
NAME READY STATUS RESTARTS AGE podname 1/1 Running 0 16s
**注:**ポット 内のアプリケーションコンテナが実行されていない場合、ロードバランサーの健康チェックは応答されず、失敗します。
ポットとサービスラベルセレクターを確認してください
ポットラベルの場合は、以下のコマンドを実行してください:
$ kubectl get pod -n YOUR_NAMESPACE --show-labels
出力例:
NAME READY STATUS RESTARTS AGE LABELS alb-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 サービスに置き換え、 YOUR_NAMESPACE を Kubernetes 名前空間に置き換えてください。
出力例:
{"app":"alb-instance"}
不明なエンドポイントがないか確認してください
サービスセレクターの Kubernetes コントローラーは、そのセレクターに一致する ポットを継続的にスキャンし、エンドポイントオブジェクトに更新をポストします。間違ったラベルを選択した場合、エンドポイントは表示されません。
次のコマンドを実行してください。
$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE
出力例:
Name: alb-instance Namespace: 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 AGE alb-instance <none> 2d20h
サービストラフィックポリシーとクラスターセキュリティグループで、アプリケーションロードバランサーの問題がないか確認します。
アプリケーションロードバランサーのターゲットグループ内の異常なターゲットは、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
クラスターセキュリティグループを確認する
1. Amazon EC2 コンソールを開きます。
2. 正常なインスタンスを選択します。
3. [Security] タブを選択し、セキュリティグループの進入ルールを確認します。
4. 異常のあるインスタンスを選択します。
5. [Security] タブを選択し、セキュリティグループの進入ルールを確認します。
各インスタンスのセキュリティグループが異なる場合は、セキュリティグループコンソールでセキュリティイングレスルールを変更する必要があります。
1. [Security] タブで、セキュリティグループ ID を選択します。
2. イングレスルールを変更するには、 [インバウンドルールの編集] ボタンを選択します。
3. インバウンドルールを追加して、クラスター内の他のノードグループからのトラフィックを許可します。
サービスが 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 ロードバランサーコントローラーに正しい権限があることを確認してください。
AWS Load Balancer Controller には、ロードバランサーからインスタンスまたはポッドへのトラフィックを許可するために、セキュリティグループを更新するための適切なアクセス権限が必要です。コントローラに適切な許可がない場合、エラーが表示されます。
AWS ロードバランサーコントローラーのデプロイログにエラーがないか確認してください。
$ kubectl logs deploy/aws-load-balancer-controller -n kube-system
個々のコントローラー ポットログにエラーがないか確認してください:
$ kubectl logs CONTROLLER_POD_NAME -n YOUR_NAMESPACE
**注:**CONTROLLER_POD_NAME はコントローラーのポッド名に、 YOUR_NAMESPACE は Kubernetes 名前空間に置き換えます
アプリケーションロードバランサーに関する問題がないか、Ingress アノテーションをチェックしてください。
アプリケーションロードバランサーに関する問題については、Kubernetes ingress アノテーションを確認してください:
$ kubectl describe ing INGRESS_NAME -n YOUR_NAMESPACE
**注:**INGRESS_NAME は Kubernetes Ingress の名前に置き換え、 YOUR_NAMESPACE は Kubernetes 名前空間に置き換えます。
出力例:
Name: alb-instance-ingress Namespace: 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 アノテーションを見つけるには、 Ingress アノテーション (Kubernetes Web サイトから) を参照してください。
Kubernetes Service アノテーションでネットワークロードバランサーに関する問題を確認してください
ネットワークロードバランサーに関する問題については、Kubernetes Service アノテーションを確認してください:
$ kubectl describe svc SERVICE_NAME -n YOUR_NAMESPACE
出力例:
Name: nlb-ip Namespace: 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 Service アノテーションを見つけるには、Kubernetes Web サイトの「サービスアノテーション」を参照してください。
健康チェックを手動で確かめてください
アプリケーション ポット の IP アドレスを確認してください:
$ kubectl get pod -n YOUR_NAMESPACE -o wide
テスト ポットを実行して、HTTP 健康チェックについてクラスター内の健康チェックを手動でテストしてください。
$ 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 を ALB ターゲットグループのヘルスチェックパスに置き換えます。
コマンドの例:
# 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 が正しく動作しない場合、サービスとエンドポイントの iptables ルールを更新できない可能性があります。kube-proxy を再起動して iptables ルールの再チェックと更新を強制してください。
kubectl rollout restart daemonset.apps/kube-proxy -n kube-system
出力例:
daemonset.apps/kube-proxy restarted
関連情報
どうやってAmazon EKS のサービスロードバランサーをトラブルシューティングするんですか。
ロードバランサーまたは入力コントローラーにより自動サブネット検出をするとき、Amazon EKS クラスター内の Amazon VPC サブネットにタグを付ける方法を教えてください。
関連するコンテンツ
- 質問済み 7ヶ月前lg...
- 質問済み 2ヶ月前lg...
- 質問済み 1年前lg...
- 質問済み 5ヶ月前lg...
- AWS公式更新しました 2ヶ月前
- AWS公式更新しました 1年前
- AWS公式更新しました 2年前
- AWS公式更新しました 1年前