Amazon EKS のロードバランサーのヘルスチェックが失敗した場合の解決方法を教えてください。

所要時間5分
0

ロードバランサーが 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

**クラスターセキュリティグループを確認する **

次の手順を実行します。

  1. Amazon EC2 コンソールを開きます。
  2. 正常なインスタンスを選択します。
  3. [セキュリティ] タブを選択し、セキュリティグループの進入ルールを確認します。
  4. 異常のあるインスタンスを選択します。
  5. [セキュリティ] タブを選択し、セキュリティグループの進入ルールを確認します。
    各インスタンスのセキュリティグループが異なる場合は、セキュリティグループコンソールでセキュリティ進入ルールを変更する必要があります。
    [セキュリティ] タブから、セキュリティグループ 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 の Amazon EC2 ノードグループの AWS Load Balancer Controller から Application Load Balancer を設定するにはどうすればよいですか?

Amazon EKS の Kubernetes のサービスコントローラーによって作成されたロードバランサーに関する問題をトラブルシューティングする方法を教えてください。

Amazon EKS で Application Load Balancer が使用するサブネットを自動的に検出する方法を教えてください。

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

関連するコンテンツ