Amazon Web Services ブログ

Kubernetes アプリケーションの公開 Part 2: AWS Load Balancer Controller

この記事は Exposing Kubernetes Applications, Part 2: AWS Load Balancer Controller (記事公開日: 2022 年 11 月 22 日) を翻訳したものです。

はじめに

連載「Kubernetes アプリケーションの公開」では、Kubernetes クラスターで実行されているアプリケーションを、外部からのアクセスのために公開する方法に焦点を当てます。

Part 1 では、Kubernetes クラスターでインバウンドトラフィックの制御を定義する 2 つの方法である Service と Ingress リソースタイプについて探りました。Service と Ingress コントローラーによるこれらのリソースタイプの処理について説明し、その後、いくつかのコントローラーの実装バリエーションの利点と欠点について概要を説明しました。

今回、Part 2 では、Service と Ingress 両方のコントローラーの AWS のオープンソース実装である AWS Load Balancer Controller の概要を説明します。このコントローラーのセットアップ、設定、想定されるユースケース、制限事項について説明します。

Part 3 では、Ingress コントローラーのまた別のオープンソース実装である NGINX Ingress Controller について、AWS Load Balancer Controller とのいくつかの違いも含めて、同様のウォークスルーを行います。

AWS Load Balancer Controller の概要

連載の Part 1 では、Kubernetes アプリケーションを公開するための 2 つのアプローチに焦点を当てました。トラフィックをアプリケーションの Pod に直接ルーティングする「外部ロードバランサー」と、アプリケーションへの単一エントリーポイントとして機能し Pod にトラフィックをルーティングする「クラスター内リバースプロキシ」です。

AWS Load Balancer Controller は、以下の図で模式的に示すような「外部ロードバランサー」のアプローチをとります。

外部ロードバランサーを使用した Ingress コントローラーの実装

なお、AWS Load Balancer Controller には、Service コントローラーも含まれています。その使用例については、連載の Part 3 で紹介します。

以下の図では、Ingress のバックエンドにあるアプリケーションを公開するためのステップバイステップのプロセスを示しています。

  1. alb-ingress-controller が Ingress イベントを監視します。(訳注: これは以前のバージョンでの名前で、現在のバージョンでは aws-load-balancer-controller です。)
  2. Ingress オブジェクトごとに ALB が管理されます。 必要に応じて作成、設定、および削除されます。
  3. ターゲットグループが、instance (ServiceA および ServiceB) または ip (ServiceC) モードで作成されます。
  4. ALB リスナーが作成され、設定されます。
  5. ルールは、リスナーからターゲットグループにトラフィックを転送するように設定されます。

Ingress の背後にあるアプリケーションを公開するためのステップバイステップのプロセス

Part 1 では、Elastic Load Balancing のようなマネージドで可用性が高くスケーラブルなロードバランサーサービスに作業をアウトソーシングするメリットについて説明しました。この記事 (Part 2) では、セットアップ、設定、コード例についてウォークスルーを行い、AWS Load Balancer Controller の使い方を説明します。

ウォークスルー

前提条件

1. AWS アカウントへのアクセスの取得

AWS アカウントと、AWS コマンドラインインターフェイス (AWS CLI) や同様のツールを使用して、ターミナルから AWS と通信できる必要があります。

以下のコード例では、AWS アカウント ID やリージョンなど、置き換えることを前提とした文字列がいくつか含まれています。これらは、あなたの環境に合った値で置き換えてください。

2. AWS Load Balancer Controller 用の AWS IAM ポリシーの作成

この手順のステップ 2 と 3 のみを実行して、AWSLoadBalancerControllerIAMPolicy を作成します。IRSA (IAM Roles for Service Accounts) を使用して、コントローラーに IAM アクセス許可を提供します。

なお、OIDC IAM プロバイダーの登録と AWS Load Balancer Controller の Service Account の作成、および IAM ロールの作成は、後続の設定で eksctl が自動的に行うため、明示的に行う必要はありません。

3. クラスターの作成

eksctl を使用して Amazon EKS クラスターをプロビジョニングします。eksctl はクラスター自体の作成に加えて、VPC、サブネット、セキュリティグループといった必要なネットワークリソースもプロビジョニングおよび設定します (eksctl のインストール手順については、こちらを参照してください) 。

以下の eksctl 設定ファイルは、Amazon EKS クラスターとその設定を定義します。

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: aws-load-balancer-controller-walkthrough
  region: ${AWS_REGION}
  version: '1.27'
iam:
  withOIDC: true
  serviceAccounts:
    - metadata:
        name: aws-load-balancer-controller
        namespace: kube-system
      attachPolicyARNs:
        - arn:aws:iam::${AWS_ACCOUNT}:policy/AWSLoadBalancerControllerIAMPolicy
managedNodeGroups:
  - name: main-ng
    instanceType: m5.large
    desiredCapacity: 1
    privateNetworking: true

上記のコードを config.yml ファイルに記述してください。

AWS_REGION および AWS_ACCOUNT 環境変数を定義してください。その後、クラスターを作成します。

envsubst < config.yml | eksctl create cluster -f -

なお、このウォークスルーでは、Kubernetes バージョン 1.23 の Amazon EKS プラットフォームバージョン eks.3 を使用しています。(訳注: 翻訳時には、Kubernetes バージョン 1.27 の Amazon EKS プラットフォームバージョン eks.4 を使用して動作を確認しています。)

シンプルにするため、上記の構成では、セキュリティやモニタリングなど、Kubernetes クラスターのプロビジョニングと管理の多くの側面は考慮していません。より詳細な情報とベストプラクティスについては、Amazon EKSeksctl のドキュメントを参照してください。

クラスターが稼働していることを確認します。

kubectl get nodes
kubectl get pods -A

上記のコマンドは、1 つの Amazon EKS ノードと 4 つの実行中の Pod を返すはずです。

4. Helm のインストール

コントローラーのインストールと設定には、Kubernetes において一般的なパッケージマネージャーである Helm を使用します。こちらの手順に従って Helm をインストールしてください。

AWS Load Balancer Controller のインストール

1. CustomResourceDefinition (CRD) のインストール

以下のコマンドで、コントローラーが機能するために必要なカスタムリソース定義 (CRD) をインストールします。

kubectl apply -k \
    "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"

2. Helm を使用したコントローラーのインストール

ここでは eksctl によって自動的に作成された Service Account を使用していることに注意してください。

helm repo add eks https://aws.github.io/eks-charts

helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller \
    --namespace kube-system \
    --set clusterName=aws-load-balancer-controller-walkthrough \
    --set serviceAccount.create=false \
    --set serviceAccount.name=aws-load-balancer-controller

kubectl -n kube-system rollout status deployment aws-load-balancer-controller

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

テスト用 Service のデプロイ

1. Namespace の作成

kubectl create namespace apps

2. Service のマニフェストファイルの作成

以下のコードを service.yml ファイルに記述します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ${SERVICE_NAME}
  namespace: ${NS}
  labels:
    app.kubernetes.io/name: ${SERVICE_NAME}
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: ${SERVICE_NAME}
  replicas: 1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ${SERVICE_NAME}
    spec:
      terminationGracePeriodSeconds: 0
      containers:
        - name: ${SERVICE_NAME}
          image: hashicorp/http-echo
          imagePullPolicy: IfNotPresent
          args:
            - -listen=:3000
            - -text=${SERVICE_NAME}
          ports:
            - name: app-port
              containerPort: 3000
          resources:
            requests:
              cpu: 0.125
              memory: 50Mi
---
apiVersion: v1
kind: Service
metadata:
  name: ${SERVICE_NAME}
  namespace: ${NS}
  labels:
    app.kubernetes.io/name: ${SERVICE_NAME}
spec:
  type: ClusterIP
  selector:
    app.kubernetes.io/name: ${SERVICE_NAME}
  ports:
    - name: svc-port
      port: 80
      targetPort: app-port
      protocol: TCP

http-echo イメージを使用する上記の Service は、${SERVICE_NAME} 変数で定義した Service 名でリクエストに応答します。シンプルにするため、レプリカは 1 つとしています。

3. サービスのデプロイと検証

以下のコマンドを実行します (これからこの記事を通して、これらの Service を使用します) 。

SERVICE_NAME=first NS=apps envsubst < service.yml | kubectl apply -f -
SERVICE_NAME=second NS=apps envsubst < service.yml | kubectl apply -f -
SERVICE_NAME=third NS=apps envsubst < service.yml | kubectl apply -f -
SERVICE_NAME=fourth NS=apps envsubst < service.yml | kubectl apply -f -
SERVICE_NAME=error NS=apps envsubst < service.yml | kubectl apply -f -

すべてのリソースがデプロイされていることを確認しましょう。

kubectl get pod,svc -n apps

以下のような出力が得られるはずです。

アプリケーションの Namespace にある Pod と Service オブジェクトのリスト

シンプルな Ingress のデプロイ

1. Ingress のマニフェストファイルの作成

以下のコードを ingress.yml ファイルにコピーしてください。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ${NS}-ingress
  namespace: ${NS}
  annotations:
    alb.ingress.kubernetes.io/load-balancer-name: ${NS}-ingress
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /first
            pathType: Prefix
            backend:
              service:
                name: first
                port:
                  name: svc-port
          - path: /second
            pathType: Prefix
            backend:
              service:
                name: second
                port:
                  name: svc-port

Ingress の概要については、連載の Part 1 をご参照いただくか、Kubernetes の公式ドキュメントで概要や完全な仕様を調べることができます。

上記のコードは、AWS Load Balancer Controller に追加の情報を提供するためにいくつかのことを行っています。

  • ingressClassNamealb に設定することで、AWS Load Balancer Controller がこの Ingress リ ソースを処理することを指示します
  • アノテーションを介して以下を定義します
    • コントローラーが作成するロードバランサーの名前
    • ロードバランサーのターゲットタイプが ip であること (すなわち、Pod の IP アドレスをターゲットとして登録します)
    • ロードバランサーが internet-facing であること
    • ヘルスチェックのパス

Kubernetes 1.19 より前では、kubernetes.io/ingress.class: alb という形式の Ingress アノテーションを介して IngressClass を定義することもできましたが、これは非推奨となりました。このアノテーションはまだ使用可能ですが、ingressClassName が優先されます。

利用可能なアノテーションの完全なリストについては、こちらを参照してください。

2. Ingress リソースのデプロイ

次のコマンドを実行します。

NS=apps envsubst < ingress.yml | kubectl apply -f -

しばらくすると、デプロイされた Ingress リソースの状態を確認できます。

kubectl get ingress -n apps

次のような出力が得られます (ID とリージョンはプレースホルダに置き換えてあります) 。

アプリケーションの Namespace にある Ingress オブジェクトのリスト

Application Load Balancer の URL を環境変数に格納します。

export ALB_URL=$(kubectl get -n apps ingress/apps-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')

数分後、ロードバランサーのプロビジョニングが完了し、リクエストを送ることができるようになります。

curl ${ALB_URL}/first
curl ${ALB_URL}/second

以下のような結果が得られれば、Service と Ingress は正常に機能しています。

first および second サービスの HTTP リクエストに対するレスポンス

AWS Load Balancer Controller は、Ingress リソースでの定義に従って、apps-ingress という名前の Application Load Balancer をプロビジョニングし、リスナールールを設定し、ターゲットグループとそのターゲットを定義します。

リスナールールでのターゲットグループの設定を示す AWS マネジメントコンソールのスクリーンショット

AWS Application Load Balancer Controller のベストプラクティスでは、アベイラビリティゾーンをまたいで、少なくとも 2 つのパブリックサブネットと 2 つのプライベートサブネットを構成することが必要です。Amazon EKS クラスターのノードはプライベートサブネットに存在し、パブリックサブネットは、ロードバランサーがプライベートサブネットの IP にトラフィックをルーティングするための内部リソースをプロビジョニングするために使用されます。

コントローラーは、タグに基づいてこれらのサブネットを自動検出できます。

  • パブリックサブネットには、kubernetes.io/role/elb キーに 1 または '' を値として指定します
  • プライベートサブネットには、kubernetes.io/role/internal-elb キーに 1 または '' を値として指定します

これらのタグの作成は、クラスターのプロビジョニングに使用した eksctl ツールが自動的に行ってくれるため、明示的にタグを作成する必要はありません。また、alb.ingress.kubernetes.io/subnets アノテーションを使用して、関連するサブネットを明示的に設定することもできます。

ターゲットグループのいずれかを開くと、登録された Pod の IP アドレスとポート、そして Ingress 定義の alb.ingress.kubernetes.io/healthcheck-path アノテーションで定義したターゲットのヘルスチェック設定が、プロビジョニングされたターゲットグループに反映されていることが確認できます。また、コントローラーはクラスターセキュリティグループを更新し、ロードバランサーから Pod へのトラフィックを許可しています。

ロードバランサーのターゲットのリストを表示した AWS マネジメントコンソールのスクリーンショット

ALB のヘルスチェック設定を示した AWS マネジメントコンソールのスクリーンショット

リスナー設定では、特定のパスのいずれにもルーティングされないリクエストに対する、デフォルトの「キャッチオール」ルールがあることに気づいたかもしれません。このルールは固定の 404 レスポンスを返します。

追加のアノテーションを介してこれをさらに設定するか、Ingress 設定を介してデフォルトのバックエンド (Default Backend) を明示的に定義できます。

Default Backend

1. Ingress 定義の更新

ingress.yml ファイルに defaultBackend の設定を追加します。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ${NS}-ingress
  namespace: ${NS}
  annotations:
    alb.ingress.kubernetes.io/load-balancer-name: ${NS}-ingress
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
  ingressClassName: alb
  defaultBackend:
    service:
      name: error
      port:
        name: svc-port
  rules:
    - http:
        paths:
          - path: /first
            pathType: Prefix
            backend:
              service:
                name: first
                port:
                  name: svc-port
          - path: /second
            pathType: Prefix
            backend:
              service:
                name: second
                port:
                  name: svc-port

2. Ingress の更新

NS=apps envsubst < ingress.yml | kubectl apply -f -

わずかな時間の後、Application Load Balancer のリスナールールの設定が適切に更新されます。

新しいリスナールールの設定を示す AWS マネジメントコンソールのスクリーンショット

以下のコマンドを実行することで、リスナールールの設定を検証しましょう。

curl ${ALB_URL}
curl ${ALB_URL}/first
curl ${ALB_URL}/first/something
curl ${ALB_URL}/second
curl ${ALB_URL}/third
curl ${ALB_URL}/something

次の出力が得られます。

HTTP リクエストに対するレスポンス

ホストベースのルーティング

上記の Ingress の定義では、どのルールにも host 設定を指定していませんでした。つまり、Host ヘッダーにかかわらず、Application Load Balancer に送信されるすべてのリクエストが、これらのルールにマッチすることになります。

Ingress 定義では、パスベースルーティングとホストベースルーティングを組み合わせることができます。

1. Ingress 定義の更新

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ${NS}-ingress
  namespace: ${NS}
  annotations:
    alb.ingress.kubernetes.io/load-balancer-name: ${NS}-ingress
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
  ingressClassName: alb
  defaultBackend:
    service:
      name: error
      port:
        name: svc-port
  rules:
    - host: a.example.com
      http:
        paths:
          - path: /first
            pathType: Prefix
            backend:
              service:
                name: first
                port:
                  name: svc-port
          - path: /second
            pathType: Prefix
            backend:
              service:
                name: second
                port:
                  name: svc-port
    - host: '*.example.com'
      http:
        paths:
          - path: /third
            pathType: Prefix
            backend:
              service:
                name: third
                port:
                  name: svc-port
          - path: /fourth
            pathType: Prefix
            backend:
              service:
                name: fourth
                port:
                  name: svc-port

ワイルドカードを使用して、a.example.com 以外の *.example.com へのすべてのリクエストをルーティングします (ワイルドカードに関するその他の考慮事項はこちらを参照してください) 。

2. Ingress の更新

NS=apps envsubst < ingress.yml | kubectl apply -f -

ロードバランサーの設定が期待どおりに更新されます。

新しいリスナールールの設定を示す AWS マネジメントコンソールのスクリーンショット

curl を使用して構成をテストしましょう (2 番目のリクエストのドメインが正しくないことに注意してください) 。

curl ${ALB_URL}/first -H 'Host: a.example.com'
curl ${ALB_URL}/first -H 'Host: a.example.net'
curl ${ALB_URL}/third -H 'Host: b.example.com'
curl ${ALB_URL}/fourth -H 'Host: c.example.com'

以下のような結果が期待されます。

HTTP リクエストに対するレスポンス

もちろん、本番環境では、上記のサブドメインの DNS レコードを ALB の DNS 名 にポイントします。

これ以降のコード例は説明のみを目的としており、ウォークスルーの一部ではありません。必要に応じてデプロイし、その影響を調査することができます。

複数の Ingress リソース

これまで、ALB を使用して、同じ Namespace にあるバックエンドの Service にトラフィックをルーティングする単一の Ingress リソースを扱ってきました。多くの Namespace にまたがって複数の Ingress リソースが必要な場合はどうすればよいでしょうか?それぞれに ALB をプロビジョニングする必要があるのでしょうか?

答えは「No」です。

複数の Ingress リソースが同じロードバランサーの下で処理されるように設定することができます。これは、すべての Ingress リソースに alb.ingress.kubernetes.io/group.name アノテーションで同じ値を設定することで実現できます。alb.ingress.kubernetes.io/group.order アノテーションを追加することで、マージ順序を制御することもできます。

このような集約のユースケースとして考えられるのは、中央でプロビジョニングされた同じロードバランサーを引き続き使用しながら、チーム間の依存関係を減らし、それぞれが一部のサービスに責任を持つようにすることです。

例えば、次のような Ingress リソースについて考えてみましょう (わかりやすくするために簡略化しています) 。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: apps-ingress
  namespace: apps
  annotations:
    alb.ingress.kubernetes.io/load-balancer-name: apps-ingress
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/healthcheck-path: /healthz
    alb.ingress.kubernetes.io/group.name: common-ingress-group
spec:
  ingressClassName: alb
  defaultBackend:
    service:
      name: error
      port:
        name: svc-port
  rules:
    - host: a.example.com
    ...

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ops-ingress
  namespace: ops
  annotations:
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/group.name: common-ingress-group
    alb.ingress.kubernetes.io/group.order: '10'
spec:
  ingressClassName: alb
  rules:
    - host: a.example.com
    ...
    - host: b.example.com
    ...

これらの Ingress 定義は同じロードバランサーの下にマージされます。

Ingress リソースがマージされたリスナールール設定を示す AWS マネジメントコンソールのスクリーンショット

2 番目の Ingress リソースに対して定義した order10 で、1 番目の Ingress リソースのデフォルトの order である 0 より大きく (すなわち優先度が低く) なっています。したがって、2 番目の Ingress からの a.example.com へのルートは、ルールリストの下位にあります (/first がルール #1 では first.apps Service にポイントされ、ルール #3 では third.ops Service にポイントされているのを確認してください) 。

両方の Ingress リソースで target-type を定義する必要があること、および、Default Backend を定義できるのは 1 回だけであることに注意してください。

IngressClass

上記のすべての Ingress リソース定義における ingressClassName プロパティは、クラスターの IngressClass リソースの指定です。alb はコントローラーの ingressClass 設定値のデフォルト値であり、コントローラーとともに alb IngressClass がインストールされています。

これは次のような定義です。

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: alb
  ...
spec:
  controller: ingress.k8s.aws/alb

同じように独自の IngressClass を定義することもできます。

デフォルトの IngressClass

Ingress リソース内で IngressClass を指定することができますが、デフォルトの IngressClass を定義して、指定を不要にすることもできます。これは、IngressClass の定義に ingressclass.kubernetes.io/is-default-class アノテーションを追加することで可能です。

IngressClass を指定してないすべての Ingress リソースは、上記の controller フィールドで定義されたコントローラーによって処理されます。

IngressClassParams

コントローラーと一緒にインストールした CRD (Custom Resource Definition) の中に、IngressClassParams があります。これは、コントローラーに追加のパラメータを渡すためのもので、これらのパラメータの一部は、以前はアノテーションを介して処理されていました。 実際、groupscheme のアノテーションもこの中に移動できます。加えて、Namespace に基づいて、どの Ingress リソースに特定の IngressClassParams の使用を許可するかを制御する namespaceSelector を指定できます。

apiVersion: elbv2.k8s.aws/v1beta1
kind: IngressClassParams
metadata:
  name: alb-ingress-class-params
  ...
spec:
  namespaceSelector:
    matchLabels:
      team: some-team
  group:
    name: common-ingress-group
  scheme: internet-facing
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: alb
  ....
spec:
  controller: ingress.k8s.aws/alb
  parameters:
    apiGroup: elbv2.k8s.aws
    kind: IngressClassParams
    name: alb-ingress-class-params

コントローラーのスコープの制限

ウォークスルーの冒頭で AWS Load Balancer Controller をデプロイした際、処理対象の Ingress と Service のリソースを明示的に制限しませんでした。

もうひとつの方法として、特定の Namespace の Ingress と Service リソースを監視するようにコントローラーのスコープを指定することができます。

helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller \
    -n kube-system \
    --set clusterName=aws-load-balancer-controller-walkthrough \
    --set serviceAccount.create=false \
    --set watchNamespace=apps \
    --set serviceAccount.name=aws-load-balancer-controller

AWS Load Balancer Controller は、watchNamespace 設定値を指定して特定の Namespace を監視するか、省略することですべての Namespace を監視することができます。現在のところ、複数の特定の Namespace を監視するオプションはありません。

複数の AWS Load Balancer Controller インスタンス

上記のようにコントローラーを特定の Namespace に制限できる機能を考慮すると、AWS Load Balancer Controller の複数のインスタンスを、それぞれ特定の Namespace に制限し、異なる構成でデプロイすることが合理的である可能性があります。現在、AWS Load Balancer Controller は複数のインスタンスをサポートしていませんが、この Issue を追跡することで進捗を確認できます。

クリーンアップ

ウォークスルーで作成したリソースを削除するには、以下のコマンドを実行します。

NS=apps envsubst < ingress.yml | kubectl delete -f -

helm uninstall -n kube-system aws-load-balancer-controller

envsubst < config.yml | eksctl delete cluster -f -

aws iam delete-policy --policy-arn arn:aws:iam::${AWS_ACCOUNT}:policy/AWSLoadBalancerControllerIAMPolicy

まとめ

AWS Load Balancer Controller は、受信トラフィック処理を可用性と拡張性の高いマネージドサービスである AWS Application Load Balancer にオフロードすることで、運用の複雑さを軽減します。Ingress リソースをロードバランサーのプロビジョニングと設定に変換することで、インフラストラクチャのプロビジョニングプロセスとは独立して、受信トラフィック処理のあらゆる側面を制御する機能をアプリケーションに提供します。

AWS Load Balancer Controller は Ingress コントローラーだけでなく、Service コントローラーも提供するため、Kubernetesアプリケーションを外部トラフィックに公開するための完全なソリューションです。

翻訳はプロフェッショナルサービスの杉田が担当しました。原文はこちらです。