このトピックでは、LoadBalancer Service の問題を診断およびトラブルシューティングする方法について説明します。
背景情報
Service タイプをType=LoadBalancer に設定すると、ACK Cloud Controller Manager (CCM) コンポーネントは、Service 用に Alibaba Cloud Classic Load Balancer (CLB) インスタンスを自動的に作成または設定します。これには、CLB インスタンス、リスナー、バックエンドサーバーグループなどのリソースが含まれます。CLB の自動更新ポリシーの詳細については、「Service の Server Load Balancer 設定に関する注意事項」をご参照ください。
診断プロセス
CCM コンポーネントのバージョンが V1.9.3.276-g372aa98-aliyun 以降であることを確認してください。CCM コンポーネントのアップグレード方法の詳細については、「CCM コンポーネントのアップグレード」をご参照ください。CCM のリリースノートについては、「Cloud Controller Manager」をご参照ください。
次のコマンドを実行して、CLB インスタンスに関連付けられている Service を特定します。
kubectl get svc -A |grep -i LoadBalancer|grep {XXX.XXX.XXX.XXX} # XXX.XXX.XXX.XXX はロードバランサーの IP アドレスです。次のコマンドを実行して、Service にエラーイベントがあるかどうかを確認します。
kubectl -n {your-namespace} describe svc {your-svc-name}エラーイベントが存在する場合は、「Service のエラーイベントと解決策」をご参照ください。
エラーイベントが存在しない場合は、「トラブルシューティング方法」をご参照ください。
Service のエラーイベントと解決策
次の表に、さまざまなエラーメッセージの解決策を示します。
エラーメッセージ | 説明と解決策 |
| CLB インスタンスのバックエンドサーバー数がクォータ制限に達しました。 解決策: 次のいずれかの方法でクォータの使用量を最適化します。
|
| 共有 CLB インスタンスは ENI をサポートしていません。 解決策: CLB バックエンドが ENI を使用する場合は、パフォーマンス専有型 CLB インスタンスを選択する必要があります。Service に 重要 アノテーションが CCM バージョンと互換性があることを確認してください。アノテーションと CCM バージョンのマッピングの詳細については、「アノテーションを使用した Classic Load Balancer (CLB) インスタンスの設定」をご参照ください。 |
| CLB インスタンスにバックエンドサーバーがありません。Service が Pod に関連付けられているか、Pod が期待どおりに実行されているかを確認してください。 解決策:
|
| CLB インスタンスは Service に基づいて関連付けることができません。 解決策: Server Load Balancer コンソールにログインします。Service が存在するリージョンで、Service の
|
| アカウントに支払い遅延があります。 |
| アカウントの残高が不足しています。 |
| CLB OpenAPI がスロットリングされています。 解決策:
|
| vServer グループに関連付けられているリスナーは削除できません。 解決策:
|
| このエラーは、クラスターと同じ VPC にない内部向け CLB インスタンスを再利用した場合に発生します。 解決策: CLB インスタンスとクラスターが同じ VPC にあることを確認してください。 |
| vSwitch の利用可能な IP アドレスの数が不足しています。 解決策: |
| ENI モードは 解決策: Service YAML ファイルの |
| 以前のバージョンの CCM は、デフォルトで共有 CLB インスタンスを作成します。ただし、共有 CLB インスタンスは廃止されました。 解決策: CCM コンポーネントをアップグレードします。 |
| CLB インスタンスのリソースグループは、インスタンスの作成後に変更することはできません。 解決策: Service から |
| VPC で指定された ENI IP アドレスが見つかりません。 解決策: Service で |
| CLB インスタンスの課金方法を従量課金からスペック保証型に変更することはできません。 解決策:
|
| このエラーは、CCM によって作成された CLB インスタンスが再利用されるときに発生します。 解決策:
|
| CLB インスタンスのタイプは、インスタンスの作成後に変更することはできません。このエラーは、Service の作成後に CLB タイプを変更した場合に発生します。 解決策: Service を削除して再作成します。 |
| Service はすでに CLB インスタンスにアタッチされており、別のインスタンスにアタッチすることはできません。 解決策: |
トラブルシューティング方法
Service エラーではない問題については、次の表の説明に従ってトラブルシューティングを行ってください。
問題のカテゴリ | 症状 | ソリューション |
CLB アクセスの問題 | CLB バックエンド間の負荷分散が不均一 | |
アプリケーションの更新中に CLB インスタンスにアクセスすると 503 エラーが発生する | ||
クラスター内から CLB インスタンスにアクセスできない | ||
クラスター外から CLB インスタンスにアクセスできない | ||
HTTPS ポートにアクセスすると「 | ||
CLB の設定クラス | Service アノテーションが有効にならない | |
CLB 設定が変更される | ||
既存の CLB インスタンスの再利用が有効にならない | ||
既存の CLB インスタンスを再利用する際にリスナーが設定されない | ||
CLB バックエンドの不整合 | ||
CLB 削除の問題 | CLB インスタンスが削除される | |
Service の削除後に CLB インスタンスが削除されない |
CLB バックエンド間の負荷分散が不均一
原因
CLB インスタンスのスケジューリングアルゴリズムが正しく設定されていません。
症状
CLB インスタンスのバックエンドサーバー間で負荷が不均一に分散されます。
解決策
Local モード (
externalTrafficPolicy: Local) の Service の場合、CLB スケジューリングアルゴリズムを重み付きラウンドロビンに設定します。これを行うには、Service にservice.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler:"wrr"アノテーションを追加します。アプリケーションが持続的接続を使用している場合、各接続で複数のリクエストが送信されるため、負荷が不均衡になる可能性があります。この場合、Service に
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler:"wlc"アノテーションを追加して、CLB スケジューリングアルゴリズムを重み付き最小接続に設定します。
アプリケーションの更新中に CLB インスタンスにアクセスすると 503 エラーが発生する
原因
CLB リスナーに接続ドレインが設定されていないか、Pod に正常な終了が設定されていません。
症状
アプリケーションの更新中に CLB インスタンスにアクセスすると、503 エラーが返されます。
解決策
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-connection-drainなどのアノテーションを使用して、CLB リスナーの接続ドレインを設定します。アノテーションの詳細については、「一般的なリスナー操作」をご参照ください。コンテナーネットワークモードに基づいて、Pod の
preStopとreadinessProbeを設定します。readinessProbeは readiness プローブです。Pod は、readiness プローブに合格した後にのみ Endpoint に追加されます。ACK は Endpoint の変更を検出した後、ノードを CLB インスタンスのバックエンドにアタッチします。readinessProbeのプローブ周波数、遅延、および異常しきい値を適切に設定する必要があります。一部のアプリケーションは起動に時間がかかります。タイムアウト期間が短すぎると、Pod が繰り返し再起動する可能性があります。preStop期間を、アプリケーションが残りのすべてのリクエストを処理するのに必要な時間に設定します。terminationGracePeriodSeconds期間を、preStop期間より少なくとも 30 秒長い値に設定します。
Pod 設定例:
apiVersion: v1 kind: Pod metadata: name: nginx namespace: default spec: containers: - name: nginx image: nginx # Liveness プローブ livenessProbe: failureThreshold: 3 initialDelaySeconds: 30 periodSeconds: 30 successThreshold: 1 tcpSocket: port: 5084 timeoutSeconds: 1 # Readiness プローブ readinessProbe: failureThreshold: 3 initialDelaySeconds: 30 periodSeconds: 30 successThreshold: 1 tcpSocket: port: 5084 timeoutSeconds: 1 # 正常な終了 lifecycle: preStop: exec: command: - sleep - 30 terminationGracePeriodSeconds: 60
クラスター内から CLB インスタンスにアクセスできない
原因
Service に externalTrafficPolicy: Local 設定が構成されています。この設定を使用すると、kube-proxy はローカルエンドポイントにのみトラフィックを転送します。Service のバックエンド Pod がないノードからリクエストが送信された場合、リクエストは失敗します。CLB アドレスはクラスター外からのアクセスを目的としていますが、クラスター内からのリクエストは、このポリシーに基づいて kube-proxy によってルーティングされます。
リクエストを受信したノードに Service のバックエンド Service Pod が存在しない場合、ネットワーク接続障害が発生します。ノードにバックエンド Service Pod が存在する場合、アクセスは成功します。この問題の詳細については、「kube-proxy adds external-lb address to node-local iptables rule」をご参照ください。
症状
クラスター内から CLB インスタンスにアクセスできません。
解決策
Kubernetes クラスター内から、ClusterIP または Service 名を使用して Service にアクセスします。
Ingress の Service 名は
nginx-ingress-lb.kube-systemです。LoadBalancer Service の externalTrafficPolicy の値を Cluster に変更します。ただし、これによりアプリケーションでソース IP アドレスが失われます。次のコマンドは、Ingress Service を変更する方法を示しています。
説明Ingress CLB インスタンスを使用する場合、Pod は Ingress Pod が存在するノード上でのみ、Ingress または CLB インスタンスを介して公開されている Service にアクセスできます。
kubectl edit svc nginx-ingress-lb -n kube-systemクラスターが ENI または ENI ごとに複数の IP アドレスを持つ Terway を使用している場合は、LoadBalancer Service の externalTrafficPolicy の値を Cluster に変更し、ENI パススルーのアノテーション (例:
annotation: service.beta.kubernetes.io/backend-type: "eni") を追加できます。次のコードに例を示します。このメソッドはソース IP アドレスを保持し、問題なくクラスター内から Service にアクセスできるようにします。詳細については、「アノテーションを使用した Classic Load Balancer (CLB) インスタンスの設定」をご参照ください。apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/backend-type: eni labels: app: nginx-ingress-lb name: nginx-ingress-lb namespace: kube-system spec: externalTrafficPolicy: Cluster
クラスター外から CLB インスタンスにアクセスできない
原因
CLB インスタンスにアクセス制御リスト (ACL) が設定されているか、CLB インスタンスが期待どおりに実行されていません。
症状
クラスター外から CLB インスタンスにアクセスできません。
解決策
次のコマンドを実行して Service イベント情報を表示し、エラーイベントを解決します。詳細については、「Service のエラーイベントと解決策」をご参照ください。
kubectl -n {your-namespace} describe svc {your-svc-name}CLB インスタンスに ACL が設定されているかどうかを確認します。
ACL が設定されている場合は、ACL がクライアント IP アドレスからのアクセスを許可しているかどうかを確認します。CLB ACL 設定の詳細については、「Resource Access Management」をご参照ください。
CLB vServer グループが空かどうかを確認します。
vServer グループが空の場合は、アプリケーション Pod が Service に関連付けられているか、アプリケーション Pod が期待どおりに実行されているかを確認します。関連付けられた Pod が異常な場合は、Pod の問題を特定して解決します。詳細については、「Pod の問題のトラブルシューティング」をご参照ください。
CLB リスナーのヘルスチェックが正常かどうかを確認します。
CLB ヘルスチェックが異常な場合は、アプリケーション Pod が期待どおりに実行されているかどうかを確認します。CLB ヘルスチェックの問題の詳細については、「CLB ヘルスチェックのよくある質問」をご参照ください。
バックエンド HTTPS Service に接続できない
原因
CLB インスタンスで証明書を設定すると、CLB インスタンスで復号が実行されます。その結果、バックエンド Pod に送信されるリクエストは HTTP リクエストになります。
症状
バックエンド HTTPS Service に接続できません。
解決策
Service の HTTPS ポートに対応する targetPort を HTTP ポートに設定します。たとえば、Nginx が HTTPS ポート 443 を使用する場合、対応する targetPort を 80 に変更する必要があります。
設定例:
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port: "https:443"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-cert-id: "${YOUR_CERT_ID}"
name: nginx
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
- port: 443
protocol: TCP
targetPort: 80
selector:
run: nginx
type: LoadBalancer