Amazon EKS でのアプリケーション負荷分散 - Amazon EKS

Amazon EKS でのアプリケーション負荷分散

Kubernetes ingress を作成するとき、アプリケーショントラフィックの負荷分散を行う AWS Application Load Balancer (ALB) がプロビジョニングされます。詳細については、「Application Load Balancer ユーザーガイド」の「Application Load Balancer とは?」および「Kubernetes ドキュメント」の「イングレス」を参照してください。ALB は、ノードまたは AWS Fargate にデプロイされた pods で使用できます。ALB をパブリックサブネットまたはプライベートサブネットにデプロイできます。

アプリケーショントラフィックは、OSI モデルの L7 で負荷分散されます。L4 でネットワークトラフィックの負荷分散をするには、LoadBalancer タイプの Kubernetes service をデプロイします。このタイプは、 AWS Network Load Balancer をプロビジョニングします。詳細については、「Amazon EKS でのネットワーク負荷分散」を参照してください。2 種類の負荷分散の違いについては、AWS ウェブサイトの「Elastic Load Balancing の特徴」を参照してください。

前提条件

あるアプリケーションに対してアプリケーショントラフィックの負荷分散を行うには、次の要件を満たす必要があります。

  • 既存のクラスターがある。既存のクラスターがない場合は、「Amazon EKS の使用開始」を参照してください。既存のクラスターのバージョンを更新する必要がある場合は、Amazon EKS クラスターの Kubernetes バージョンの更新 を参照して下さい。

  • クラスターにデプロイ済みの AWS Load Balancer Controller があること。詳細については、「AWS Load Balancer Controller アドオンのインストール」を参照してください。バージョン 2.4.4 以降をお勧めします。

  • 少なくとも 2 つのサブネットが異なるアベイラビリティーゾーンに存在している。AWS Load Balancer Controller は、各アベイラビリティーゾーンから 1 つのサブネットを選択します。タグ付けされたサブネットがアベイラビリティーゾーンで複数見つかった場合、コントローラーは、サブネット ID が辞書式順序で最初に来るサブネットを選択します。各サブネットには最低 8 個の利用可能な IP アドレスが必要です。

    ワーカーノードにアタッチされた複数のセキュリティグループを使用している場合は、次のように 1 つのセキュリティグループにタグを付ける必要があります。my-cluster をクラスター名に置き換えます。

    • キーkubernetes.io/cluster/my-cluster

    • shared または owned

  • AWS Load Balancer Controller のバージョン 2.1.1 以前を使用している場合、サブネットに次のようにタグ付けする必要があります。バージョン 2.1.2 以降を使用している場合、このタグ付けはオプションです。ただし、次のいずれかの場合は、サブネットにタグ付けることをお勧めします。同じVPCで実行されている複数のクラスターがあるか、VPCでサブネットを共有する複数の AWS サービスがあります。または、各クラスターに対してロードバランサーをプロビジョニングする場所を詳細に制御する必要があります。my-cluster をクラスター名に置き換えます。

    • キーkubernetes.io/cluster/my-cluster

    • shared または owned

  • パブリックサブネットとプライベートサブネットは次の要件を満たしている必要があります。サービスオブジェクトまたは Ingress オブジェクトのアノテーションとしてサブネット ID を明示的に指定しない限り、これは例外です。サービスオブジェクトまたは Ingress オブジェクトのアノテーションとしてサブネット ID を明示的に指定して、ロードバランサーをプロビジョニングすることを想定しています。このような状況では、Kubernetes と AWS ロードバランサーコントローラーは、これらのサブネットを直接使用してロードバランサーを作成します。次のタグは必要ありません。

    • プライベートサブネット — 次の形式でタグ付けする必要があります。これは、サブネットを内部ロードバランサーに使用できることを、Kubernetes と AWS ロードバランサーコントローラーが認識できるようにするためです。eksctl または Amazon EKS AWS CloudFormation テンプレートを使用して、2020 年 3 月 26 日以降に VPC を作成する場合、サブネットは、作成時に適切にタグ付けされます。Amazon EKS AWS CloudFormation VPC テンプレートの詳細については、「Amazon EKS クラスター VPC の作成」を参照してください。

      • キーkubernetes.io/role/internal-elb

      • 1

    • パブリックサブネット — 次の形式でタグ付けする必要があります。これは、外部ロードバランサー用に指定されたサブネットのみが使用できることを、Kubernetes が認識できるようにするためです。この方法では、Kubernetes は各アベイラビリティーゾーンでパブリックサブネットを (サブネット ID に基づいて辞書順に) 選択しません。eksctl または Amazon EKS AWS CloudFormation テンプレートを使用して、2020 年 3 月 26 日以降に VPC を作成する場合、サブネットは、作成時に適切にタグ付けされます。Amazon EKS AWS CloudFormation VPC テンプレートの詳細については、「Amazon EKS クラスター VPC の作成」を参照してください。

      • キーkubernetes.io/role/elb

      • 1

    サブネットロールタグが明示的に追加されていない場合、Kubernetes サービスコントローラーはクラスター VPC サブネットのルートテーブルを調べます。これは、サブネットがプライベートかパブリックかを判断するためです。この動作に頼らないことをお勧めします。代わりに、プライベートまたはパブリックロールタグを明示的に追加します。AWS Load Balancer Controller は、ルートテーブルを精査しません。また、自動検出を正常に実行するには、プライベートタグとパブリックタグが必要です。

考慮事項

  • Kubernetes のイングレスリソースが kubernetes.io/ingress.class: alb アノテーションを使用してクラスターで作成されるたびに、AWS Load Balancer Controller により、ALB およびサポートされた必要な AWS リソースが作成されます。イングレスリソースは、HTTP または HTTPS トラフィックをクラスター内の異なる pods にルーティングするように ALB を設定します。イングレスオブジェクトに AWS Load Balancer Controller を確実に使用させるには、Kubernetes イングレス仕様に次のアノテーションを追加します。詳細については、GitHub の「[Ingress specification]」(イングレス仕様) を参照してください。

    annotations: kubernetes.io/ingress.class: alb
    注記

    IPv6 pods へのロードバランサーを行う場合は、イングレス仕様に次のアノテーションを追加します。IPv6 を使用して負荷分散を行えるのは、IP ターゲットにのみです。インスタンスターゲットには行えません。このアノテーションを使用しない場合、負荷分散には IPv4 が使用されます。

    alb.ingress.kubernetes.io/ip-address-type: dualstack
  • AWS Load Balancer Controller は、以下のトラフィックモードをサポートしています。

    • インスタンス – クラスター内のノードを ALB のターゲットとして登録します。ALB に到達するトラフィックは、サービスの NodePort にルーティングされてから、pods にプロキシされます。これがデフォルトのトラフィックモードです。alb.ingress.kubernetes.io/target-type: instance の注釈を使用して明示的に指定することもできます。

      注記

      このトラフィックモードを使用するには、Kubernetes サービスで NodePort または「LoadBalancer」 タイプを指定する必要があります。

    • IP - pods を ALB のターゲットとして登録します。ALB に到達するトラフィックは、サービスの pods に直接ルーティングされます。このトラフィックモードを使用するには、 alb.ingress.kubernetes.io/target-type: ip の注釈を指定する必要があります。IP ターゲットタイプは、ターゲットの pods が Fargate で実行されている場合に必要です。

  • コントローラーによって作成された ALB にタグを付けるには、次のアノテーションをコントローラーに追加します: alb.ingress.kubernetes.io/tags。AWS Load Balancer Controller でサポートされるすべての使用可能なアノテーションのリストについては、「GitHub」の「[Ingress annotations]」(イングレスアノテーション) を参照してください。

  • ALB コントローラーのバージョンをアップグレードまたはダウングレードすると、ALB コントローラーのバージョンに依存する機能が大きく変更される可能性があります。各リリースで導入された新しい変更の詳細については、「GitHub」の「ALB controller release noted」(ALB コントローラーリリースノート) を参照してください。

IngressGroups を使用して複数のサービスのリソース間でアプリケーションロードバランサーを共有するには

イングレスをグループに参加させるには、Kubernetes のイングレスリソース仕様に次のアノテーションを追加します。

alb.ingress.kubernetes.io/group.name: my-group

グループ名は、次のようにする必要があります。

  • 長さが 63 文字以下。

  • 名前は、小文字の英文字、-、および . で構成されます。

  • 数字または文字で始めます。

コントローラーは、同じイングレスグループ内のすべてのイングレスのイングレスルールを自動的にマージします。これは、単一のALBでそれらをサポートしています。イングレスで定義されたほとんどのアノテーションは、そのイングレスで定義されたパスにのみ適用されます。デフォルトでは、イングレスリソースはどのイングレスグループにも属していません。

警告

潜在的なセキュリティリスク: イングレスリソースを作成または変更する RBAC 権限を持つすべての Kubernetes ユーザーが同じ信頼境界内にいる場合にのみ、イングレスにイングレスグループを指定します。アノテーションをグループ名で追加すると、他の Kubernetes ユーザーが、同じイングレスグループに属するイングレスを作成または変更する可能性があります。これにより、優先度の高いルールで既存のルールを上書きするなど、望ましくない動作が発生する可能性があります。

イングレスリソースの順序番号を追加できます。

alb.ingress.kubernetes.io/group.order: '10'

番号は 1 ~ 1000 の範囲で指定できます。同じイングレスグループ内のすべてのイングレスについて、最小の番号を持つものが最初に評価されます。このアノテーションがないイングレスはすべて、値 0 で評価されます。番号が小さいルールと番号が大きいルールが重複すると、番号が小さいルールが上書きされる可能性があります。デフォルトでは、同じイングレスグループ内のイングレス間のルールの順序は、名前空間と名前に基づき辞書式順序で決定されます。

重要

同じイングレスグループの各イングレスに、一意のプライオリティ番号があることを確認します。  イングレス間で重複する順序番号を持つことはできません。

(オプション) サンプルアプリケーションをデプロイする

前提条件

  • クラスター VPC に少なくとも 1 つのパブリックサブネットまたはプライベートサブネットが存在する。

  • クラスターにデプロイ済みの AWS Load Balancer Controller があること。詳細については、「AWS Load Balancer Controller アドオンのインストール」を参照してください。バージョン 2.4.4 以降をお勧めします。

サンプルアプリケーションをデプロイするには

Amazon EC2 ノード、Fargate pods、またはその両方を持つクラスターで、サンプルアプリケーションを実行できます。

  1. Fargate にデプロイしない場合は、このステップを省略してください。Fargate にデプロイする場合は、Fargate プロファイルを作成します。次のコマンドを実行するか、コマンドにある AWS Management Console と name に同じ値を使用して、namespace でプロファイルを作成できます。example values を自分の値に置き換えます。

    eksctl create fargateprofile \ --cluster my-cluster \ --region region-code \ --name alb-sample-app \ --namespace game-2048
  2. サンプルアプリケーションとして、ゲーム 2048 をデプロイし、AWS Load Balancer Controller が Ingress オブジェクトの結果として AWS ALB を作成することを確認します。デプロイ先のサブネットのタイプに関する手順を実行します。

    1. IPv6 ファミリーを使用して作成したクラスター内の pods にデプロイしている場合には、次のステップに進みます。

      • Public

        kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.4/docs/examples/2048/2048_full.yaml
      • プライベート

        1. マニフェストをダウンロードします。

          curl -o 2048_full.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.4/docs/examples/2048/2048_full.yaml
        2. ファイルを編集して、alb.ingress.kubernetes.io/scheme: internet-facing と記述された行を探します。

        3. internet-facinginternal に変更し、ファイルを保存します。

        4. マニフェストをクラスターに適用します。

          kubectl apply -f 2048_full.yaml
    2. IPv6 ファミリー を使用して作成したクラスター内の pods にデプロイする場合は、次のステップを完了します。

      1. マニフェストをダウンロードします。

        curl -o 2048_full.yaml https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.4/docs/examples/2048/2048_full.yaml
      2. エディタでファイルを開き、イングレス仕様のアノテーションに次の行を追加します。

        alb.ingress.kubernetes.io/ip-address-type: dualstack
      3. pods に向いているインターネットではなく、内部の pods へのロードバランサーを行う場合は、alb.ingress.kubernetes.io/scheme: internet-facing と書いてある行を alb.ingress.kubernetes.io/scheme: internal に変更します。

      4. ファイルを保存します。

      5. マニフェストをクラスターに適用します。

        kubectl apply -f 2048_full.yaml
  3. 数分後、次のコマンドを使用して、イングレスリソースが作成されたことを確認します。

    kubectl get ingress/ingress-2048 -n game-2048

    出力例を次に示します。

    NAME CLASS HOSTS ADDRESS PORTS AGE ingress-2048 <none> * k8s-game2048-ingress2-xxxxxxxxxx-yyyyyyyyyy.region-code.elb.amazonaws.com 80 2m32s
    注記

    プライベートサブネットでロードバランサーを作成した場合、前の出力の ADDRESS の下の値の前に internal- が付けられます。

    数分後、イングレスが正常に作成されていない場合は、次のコマンドを実行して AWS Load Balancer Controller のログを表示します。これらのログには、デプロイに関する問題の診断に使用できるエラーメッセージが含まれている場合があります。

    kubectl logs -n kube-system deployment.apps/aws-load-balancer-controller
  4. パブリックサブネットにデプロイした場合は、ブラウザを開き、前のコマンドの出力から ADDRESS URL に移動してサンプルアプリケーションを表示します。何も表示されない場合は、ブラウザを更新してからもう一度試してください。プライベートサブネットにデプロイした場合は、踏み台ホストなどの VPC 内のデバイスからページを表示する必要があります。詳細については、「AWS の Linux 踏み台ホスト」を参照してください。

    
                        2048 サンプルアプリケーション
  5. サンプルアプリケーションの試用が終了したら、次のコマンドのいずれかを実行して削除します。

    • ダウンロードしたコピーを適用するのではなくマニフェストを適用した場合は、次のコマンドを使用します。

      kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.4/docs/examples/2048/2048_full.yaml
    • マニフェストをダウンロードして編集した場合は、次のコマンドを使用します。

      kubectl delete -f 2048_full.yaml