スキップしてコンテンツを表示

AWS Load Balancer Controller を使用してロードバランサーを作成する際に発生する問題のトラブルシューティング方法を教えてください。

所要時間4分
0

AWS Load Balancer Controller を使用してロードバランサーを作成しようとしたときに発生する問題をトラブルシューティングしたいです。

簡単な説明

AWS Load Balancer Controller は Amazon Elastic Kubernetes Service (Amazon EKS) クラスターの Elastic Load Balancing を管理します。

コントローラーは以下のリソースを提供します。

  • Kubernetes イングレスを作成する場合は Application Load Balancer。
  • LoadBalancer タイプの Kubernetes サービスを作成する場合は Network Load Balancer。
    注: AWS Load Balancer Controller バージョン 2.3.0 以降では、インスタンスまたは IP ターゲットタイプのいずれかで Network Load Balancer を作成できます。

解決策

AWS Load Balancer Controller をインストールして使用するための前提条件を満たしていることを確認する

最初に実行するアクションのリストについては、「前提条件」を参照してください。

次のコマンドを実行して、AWS Load Balancer Controller が正常にデプロイされたことを確認します。

kubectl get deployment -n kube-system aws-load-balancer-controller

**注:**バージョン 2.4.4 以降を使用するのがベストプラクティスです。

出力例:

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
aws-load-balancer-controller   2/2     2            2           84s

Application Load Balancer を使用している場合は、異なるアベイラビリティーゾーンに少なくとも 2 つのサブネットがあることを確認してください。Network Load Balancer には少なくとも 1 つのサブネットが必要です。サブネットには少なくとも 8 つの使用可能な IP アドレスが必要です。詳細については、「VPC を作成する」を参照してください。

シナリオによっては、次のタグを使用する必要があります。

  • キー: 「kubernetes.io/cluster/cluster-name」
  • 値: 「shared」または「owned」

Application Load Balancer

次のシナリオでは、1 つのセキュリティグループにタグを付ける必要があります。

  • ワーカーノードにアタッチされた複数のセキュリティグループを使用する。
  • AWS Load Balancer Controller バージョン v2.1.1 以前を使用する。

Network Load Balancer

AWS Load Balancer Controller バージョン v2.1.1 以前を使用する場合は、サブネットにタグを追加する必要があります。

サービスまたは Ingress アノテーションでサブネット ID を指定しなかった場合は、サブネット自動検出に必要なタグがサブネットに付与されていることを確認してください。詳細については、GitHub のウェブサイト「Subnet auto discovery」を参照してください。

プライベートサブネットには、次のタグを使用します。

  • キー: 「kubernetes.io/role/internal-elb」
  • 値: 「1」

パブリックサブネットでは、次のタグを使用します。

  • キー: 「kubernetes.io/role/elb」
  • 値: 「1」

Ingress オブジェクトまたは Service オブジェクトのアノテーションを確認する

Service オブジェクトまたは Ingress オブジェクトのアノテーションが正しいことを確認してください。

**注:**次のコマンドでは、SERVICE-NAMEINGRESS-NAMENAMESPACE をご利用の値に置き換えます。

Service オブジェクトを表示するには、次のコマンドを実行します。

kubectl describe service SERVICE-NAME -n NAMESPACE

Ingress オブジェクトを表示するには、次のコマンドを実行します。

kubectl describe ingress INGRESS-NAME -n NAMESPACE

Service オブジェクトを編集するには、次のコマンドを実行します。

kubectl edit service SERVICE-NAME -n NAMESPACE

Ingress オブジェクトを編集するには、次のコマンドを実行します。

kubectl edit ingress INGRESS-NAME -n NAMESPACE

他のアノテーションはデフォルト値を使用します。AWS Load Balancer Controller が Application Load Balancer 用にサポートするアノテーションのリストについては、GitHub のウェブサイト「Ingress annotations」を参照してください。Network Load Balancer でサポートされているアノテーションのリストについては、GitHub のウェブサイト「Service annotations」を参照してください。

Application Load Balancer

Kubernetes バージョン 1.18 以前では、Ingress クラスは入力コントローラー名を参照する kubernetes.io/ingress.class アノテーションを使用していました。それ以降のすべての Kubernetes バージョンの Ingress クラスは、Ingress クラスリソースを参照する IngressClassName アノテーションを使用します。

詳細については、GitHub のウェブサイト「Deprecated kubernetes.io/ingress.class annotation」を参照してください。

Network Load Balancer

次のアノテーションを使用します。

  • IP ターゲットを使用する場合、**service.beta.kubernetes.io/aws-load-balancer-type: 「external」**と **service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: 「ip」**を使用します。
  • インスタンスターゲットを使用する場合、**service.beta.kubernetes.io/aws-load-balancer-type: 「external」**と **service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: 「instance」**を使用します。

Amazon EKS で Ingress または Service タイプのロードバランサーを作成する際に発生する問題のトラブルシューティング

AccessDenied」エラーが表示される

次のエラーメッセージが表示されます。

"Failed deploy model due to AccessDenied"

このエラーは、リソースを作成するための elasticloadbalancing:AddTags アクセス許可が変更されたために発生します。この問題を解決するには、最新の AWS Identity and Access Management (IAM) ポリシーを ** AWSLoadBalancerController** ロールにアタッチします。最新のポリシーを入手するには、GitHub のウェブサイト「IAM policy JSON」を参照してください。

詳細については、「eksctl を使用して IAM ロールを作成する」を参照してください。

ロードバランサーがアベイラビリティーゾーンでサポートされていない

制約のあるアベイラビリティーゾーンにサブネットを指定すると、次のエラーメッセージが表示されることがあります。

"Load balancers with type 'network' are not supported in availability-zone-name"

この問題を解決するには、制約のない別のアベイラビリティーゾーンのサブネットを指定します。次に、クロスゾーン負荷分散を使用して、制限されたアベイラビリティーゾーンのターゲットにトラフィックを分散します。

別のサブネットを使用するには、内部 Network Load Balancer の作成に使用するサブネットに kubernetes.io/role/internal-elb=1 タグを追加します。詳細については、「Network Load Balancer へのタグ付け」を参照してください。

または、次のアノテーションを追加して、サービスマニフェストファイル内のサブネットを指定します。

service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-xxxx, mySubnet

**注:**subnet-xxxx をご利用のサブネット ID に、mySubnet をご利用のサブネット名に置き換えます。

サブネットの自動検出が使用できない

サブネットに自動検出のタグを付けないと、次のエラーメッセージが表示されることがあります。

"couldn't auto-discover subnets: unable to resolve at least one subnet"

AWS Load Balancer Controller は、デフォルトでネットワークサブネットを自動的に検出します。Application Load Balancer では、異なるアベイラビリティーゾーンにまたがって少なくとも 2 つのサブネットが必要です。Network Load Balancer に必要なサブネットは 1 つだけです。

自動検出を機能させるには、適切なタグをサブネットに適用する必要があります。コントローラーは各アベイラビリティーゾーンから 1 つのサブネットを選択します。アベイラビリティーゾーンにタグ付けされたサブネットが複数ある場合、コントローラーはサブネット ID のアルファベット順に基づいて 1 つだけを選択します。

プライベートサブネットとパブリックサブネットに必要なサブネットタグの詳細については、GitHub のウェブサイト「Subnet auto discovery」を参照してください。

証明書マネージャーまたはウェブフックの設定に問題がある

ウェブフックの検証に失敗すると、次のエラーメッセージが表示されることがあります。

"Internal error occurred: failed calling webhook "vingress.elbv2.k8s.aws": Post "https://aws-load-balancer-webhook-service.kube-system.svc:443/validate-networking-v1beta1-ingress?timeout=10s": x509: certificate has expired or is not yet valid"

このエラーは、AWS Certificate Manager (ACM) がウェブフック用に管理する証明書に問題がある場合に発生します。

この問題を解決するには、Certificate Manager ポッドが実行中かどうかを確認してください。

次のコマンドを実行し、ポッドのステータスを取得します。

kubectl describe pod your-pod-name -n your-namespace

ログを収集するには、次のコマンドを実行します。

kubectl logs your-pod-name -n your-namespace

**注:**上記のコマンドで、your-pod-name をご利用の Pod の名前に、your-namespace をご利用の名前空間名に置き換えます。

ターゲットグループバインディングの作成が失敗する

ターゲットグループバインディングの作成に失敗すると、次のエラーメッセージが表示されることがあります。

"Warning FailedDeployModel 11m (x2 over 39m) ingress Failed deploy model due to Internal error occurred: failed calling webhook "vtargetgroupbinding.elbv2.k8s.aws": failed to call webhook: Post "https://aws-load-balancer-webhook-service.kube-system.svc:443/validate-elbv2-k8s-aws-v1beta1-targetgroupbinding?timeout=10s": context deadline exceeded"

このエラーは、セキュリティグループの制限によりウェブフックサービスへのアクセスがブロックされた場合に発生します。このサービスはデフォルトでポート 9443 を使用します。

この問題を解決するには、ノードセキュリティグループを変更します。ポート 9443 のコントロールプレーンセキュリティグループからの受信トラフィックを許可します。詳細については、GitHub のウェブサイト「Controller configuration options」を参照してください。

ノードロールで AssumeRoleWithWebIdentity が失敗する

ノードロールがサービスアカウントで指定したロールを引き受けることができない場合、次のエラーメッセージが表示されることがあります。

"WebIdentityErr: failed to retrieve credentials\ncaused by: AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity\n\tstatus code: 403, request id: c6241a7d-d8a8-452c-bb67-bf1ff9bab0c0"

このエラーは、サービスアカウントの IAM ロール (IRSA) が誤って設定されたために発生します。

この問題を解決するには、サービスアカウントで正しいロールを使用し、そのロールの信頼ポリシーを定義します。

詳細については、「Amazon EKS で AWS ロードバランサーコントローラーを使用しているときに「WebIdentityErr」エラーが表示される理由は?」および「Amazon EKS における、OIDC プロバイダーと IRSA に関する問題のトラブルシューティング方法を教えてください」を参照してください。

コントローラーポッドログのデータが不足している

デフォルトのコントローラーポッドログが提供する情報よりも多くのデバッグ情報が必要な場合は、コントローラーポッドの設定に**--log-level debug** フラグを追加します。

詳細については、GitHub のウェブサイト「Controller command line flags」を参照してください。

追加情報については、AWS Load Balancer Controller ポッドのログを確認する

AWS Load Balancer Controller のログを確認するには、次のコマンドを実行します。

kubectl logs -n kube-system deployment.apps/aws-load-balancer-controller

問題がある場合は、「Reconciler error」と表示されます。また、Ingress オブジェクトまたはロードバランサーサービスの作成または更新に失敗した理由を示す詳細なエラーメッセージも表示されます。

この失敗は、次の要因で発生する場合があります。

  • コントローラーが AWS API コールを実行しようとしたときにエラーが発生する場合は、アクセス許可または接続に問題があります。コントローラーの IAM アクセス許可を確認します。次に、セキュリティグループまたはネットワークアクセスコントロールリスト (ネットワーク ACL) がアウトバウンド接続を明示的に拒否していないことを確認します。
  • オブジェクトの構成でエラーが発生した場合は、Ingress または Service の仕様かアノテーションを誤って設定しています。アノテーションについては、GitHub のウェブサイト「Application Load Balancer」または「Network Load Balancer」を確認してください。

どのコントローラーポッドにもログが表示されない場合は、次のコマンドを実行してコントローラーポッドが動作していることを確認します。

kubectl get deployment -n kube-system aws-load-balancer-controller

サポートされているコントローラーバージョンへのアップグレード

サポートが終了したバージョンの AWS Load Balancer Controller を使用している場合、それ以降のバージョンにアップグレードすることはできません。代わりに、既存のコントローラーを削除してから最新バージョンをインストールする必要があります。

レガシークラウドプロバイダーではなく AWS Load Balancer Controller を使用する

Kubernetes には、Classic Load Balancer を提供できる AWS 用のレガシークラウドプロバイダーが含まれています。AWS Load Balancer Controller をインストールしない場合、Kubernetes はレガシークラウドプロバイダーを使用します。ただし、AWS Load Balancer Controller を使用するのがベストプラクティスです。

AWS Load Balancer Controller バージョン 2.5 以降は、LoadBalancer タイプの Kubernetes サービスリソースのデフォルトコントローラーです。サービスごとに Network Load Balancer を作成します。最新バージョンでは、サービス用のウェブフックのミューテートも実装されています。最新バージョンは、新しいタイプの LoadBalancer サービスに対して spec.loadBalancerClass フィールドを service.k8s.aws/nlb に設定します。

次のコマンドを実行して、AWS Load Balancer Controller をアップグレードします。

helm upgrade aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=CLUSTER-NAME --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller --set enableServiceMutatorWebhook=false

**注:**CLUSTER-NAME は、ご利用のクラスターの名前に置き換えます。

レガシークラウドプロバイダーを使用する必要がある場合は、enableServiceMutatorWebhook Helm チャートの値を false に設定して、新しい Classic Load Balancer が提供されないようにします。既存の Classic Load Balancer のみが引き続き機能します。

Ingress オブジェクトまたは Service オブジェクトが存在する名前空間用に Fargate プロファイルが作成されていることを確認する

ターゲットポッドを AWS Fargate で実行する場合は、IP ターゲットタイプを含める必要があります。Ingress オブジェクトまたは Service オブジェクトが存在する名前空間の Fargate プロファイルがあることを確認するには、次のコマンドを実行します。

eksctl get fargateprofile --cluster CLUSTER-NAME -o yaml

**注:**CLUSTER-NAME は、ご利用のクラスターの名前に置き換えます。

Fargate プロファイルを作成するには、次のコマンドを実行します。

eksctl create fargateprofile --cluster CLUSTER-NAME --region REGION --name FARGATE-PROFILE-NAME --namespace NAMESPACE

**注:**CLUSTER-NAMEREGIONFARGATE-PROFILE-NAMENAMESPACE をご利用の値に置き換えます。

トラフィックをルーティングするための要件を満たしていることを確認する

すべての要件を満たしていることを確認するには、Application Load Balancer の前提条件と Network Load Balancer の前提条件を参照してください。たとえば、Application Load Balancer を使用する場合、Service オブジェクトでインスタンストラフィックモードを使用するには、NodePort または LoadBalancer を指定する必要があります。

Amazon EKS は、以下のルールをノードのセキュリティグループに追加します。

  • クライアントトラフィックのインバウンドルール
  • 作成した各 Network Load Balancer の VPC 内の各ロードバランサーサブネットのインバウンドルール (ヘルスチェック用)

Amazon EKS が追加したルールによってセキュリティグループが最大ルール数を超えると、ロードバランサーのデプロイが失敗する可能性があります。

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