Gateway API は、Kubernetes の公式プロジェクトであり、トラフィックルールを設定できる Kubernetes のルーティングとロードバランシングのための次世代 API です。このトピックでは、Gateway API を使用して、Application Load Balancer (ALB) インスタンスを使用してクラスターの外部からのトラフィックにサービスを公開する方法について説明します。
背景情報
Gateway API は、サービスネットワークトラフィックをモデル化するために使用される Kubernetes リソースのコレクションです。Gateway API の目標は、サービスネットワーキングのための表現力豊かで、拡張可能で、ロール指向のモデルを提供することです。
ALB Ingress Controller は、バージョン 2.17.0 以降、Gateway API をサポートしています。ALB Ingress Controller をインストールし、Gateway API を使用して ALB インスタンスを介してサービスを公開できます。
前提条件
Kubernetes 1.24 以降を実行する ACK マネージドクラスター が作成されていること。
バージョン 2.17.0 以降の ALB Ingress Controller がクラスターにインストールされていること。
バージョン 1.1.0 以降の Gateway API がクラスターにインストールされていること。
ALB をサポートする 2 つの vSwitch が、クラスターがデプロイされている VPC に作成されていること。
環境の確認
クラスターが前提条件を満たしている場合、alb という名前の GatewayClass リソースが自動的に作成されます。これは、次の方法で確認できます。
コンソール
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
クラスター ページで、対象のクラスターを見つけてその名前をクリックします。左側のナビゲーションウィンドウで、 を選択します。
[gateway.networking.k8s.io] をクリックし、[v1] の下にある [GatewayClass] を表示します。

kubectl
kubectl get gatewayclass期待される出力:
NAME CONTROLLER ACCEPTED AGE
alb gateways.alibabacloud.com/alb/v1 True 1mサンプルアプリケーションのデプロイ
httpbin.yaml ファイルを作成します。
説明このトピックでは、アプリケーションの Service はデフォルトで
ClusterIPを使用します。クラスターが Flannel ネットワークプラグインを使用している場合は、Service のspec.typeをNodePortに変更してください。apiVersion: apps/v1 kind: Deployment metadata: name: go-httpbin namespace: default spec: replicas: 1 selector: matchLabels: app: go-httpbin template: metadata: labels: app: go-httpbin version: v1 spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/mse/go-httpbin args: - "--port=8090" - "--version=v1" imagePullPolicy: Always name: go-httpbin ports: - containerPort: 8090 --- apiVersion: v1 kind: Service metadata: name: go-httpbin namespace: default spec: type: ClusterIP ports: - port: 80 targetPort: 8090 protocol: TCP selector: app: go-httpbinアプリケーションをデプロイします。
kubectl apply -f httpbin.yaml
Gateway とルートのデプロイ
この操作により ALB インスタンスが作成され、料金が発生します。Gateway によって作成された ALB インスタンスは、クラスターを削除しても自動的に削除されません。予期しない課金を避けるために、クラスターを削除する前に Gateway リソースを削除してください。
gateway.yaml ファイルを作成します。
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: alb namespace: default spec: gatewayClassName: alb listeners: - name: http protocol: HTTP port: 80 hostname: "*.ingress.top" allowedRoutes: namespaces: from: Same --- apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: demo-route spec: parentRefs: # Gateway リソースを参照します - group: gateway.networking.k8s.io kind: Gateway name: alb hostnames: - demo.ingress.top # ホストを demo.domain.ingress.top に設定します rules: - matches: # マッチングルールはパスのプレフィックスマッチです - path: type: PathPrefix value: / backendRefs: # バックエンドはポート 80 の go-httpbin という名前の Service です - kind: Service name: go-httpbin port: 80Gateway とルーティングルールをデプロイします。
kubectl apply -f gateway.yaml約 2 分待ってから、Gateway の作成ステータスを確認します。
kubectl get gateway alb期待される出力:
NAME CLASS ADDRESS PROGRAMMED AGE alb alb alb-0mwhq4ck6xxxxxxxxx.cn-hangzhou.alb.aliyuncsslb.com True 2m12s出力は Gateway が作成されたことを示します。
ルートの作成ステータスを確認します。
kubectl describe httproute demo-route|grep Status -A 20期待される出力:
Status: Parents: Conditions: Last Transition Time: 2025-05-23T08:21:25Z Message: Route is accepted. Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-05-23T08:21:25Z Message: Route is resolved. Observed Generation: 1 Reason: ResolvedRefs Status: True Type: ResolvedRefs Controller Name: gateways.alibabacloud.com/alb/v1 Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: albアプリケーションへのアクセスをテストします。
Gateway アドレスを取得します。
export ALB_DOMAIN=$(kubectl get gateway alb -n default -o jsonpath='{.status.addresses[?(@.type=="Hostname")].value}')アプリケーションにアクセスします。
curl -H "Host: demo.ingress.top" http://${ALB_DOMAIN}/version期待される出力:
version: v1 hostname: go-httpbin-547xxxxxf6-xxxxx
シナリオ
シナリオ 1: フィルターを使用してリクエストヘッダーを変更する
HTTPRoute のフィルター機能を使用すると、リクエストまたはレスポンスフェーズで追加の処理を実行できます。次の例では、フィルターを使用して、バックエンドに送信されるリクエストにリクエストヘッダーを追加する方法を示します。
httproute-filter.yaml ファイルを作成します。
apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: demo-filter spec: parentRefs: # Gateway リソースを参照します - group: gateway.networking.k8s.io kind: Gateway name: alb hostnames: - filter.ingress.top # ホストを filter.ingress.top に設定します rules: - matches: # マッチングルールはパスのプレフィックスマッチです - path: type: PathPrefix value: / filters: - type: RequestHeaderModifier # リクエストヘッダー my-header: foo を追加します requestHeaderModifier: add: - name: my-header value: foo backendRefs: # バックエンドはポート 80 の go-httpbin という名前の Service です - kind: Service name: go-httpbin port: 80このファイルは
demo-filterという名前の HTTPRoute リソースを作成します。リソースをデプロイした後、ドメイン名filter.ingress.topを使用して go-httpbin アプリケーションにアクセスすると、リクエストヘッダーmy-header: fooが自動的にリクエストに追加されます。ルーティングルールをデプロイします。
kubectl apply -f httproute-filter.yamlアプリケーションにアクセスします。
curl -H "Host: filter.ingress.top" http://${ALB_DOMAIN}/header期待される出力:
headers: { "Accept": [ "*/*" ], "Connection": [ "close" ], "Host": [ "filter.ingress.top" ], "My-Header": [ "foo" ], "Path": [ "/header" ], "Protocol": [ "HTTP/1.1" ], "Remoteip": [ "118.xx.xx.91" ], "URL": [ "/header" ], "User-Agent": [ "curl/8.9.1" ] } query param: , hostname: go-httpbin-547xxxxxf6-xxxxx
シナリオ 2: 重みに基づいてトラフィックを分割する
複数のバックエンドサービスに重みを設定して、リクエストトラフィックを分割できます。
nginx.yaml ファイルを作成します。
上記のファイルは 2 つの NGINX アプリケーションをデプロイします。
old-nginxサービスはold文字列を返し、new-nginxサービスはnew文字列を返します。デプロイされたリソースはdefault名前空間にあります。httproute-weight.yaml ファイルを作成します。
apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: demo-weight spec: parentRefs: # Gateway リソースを参照します - group: gateway.networking.k8s.io kind: Gateway name: alb hostnames: - weight.ingress.top # ホストを weight.ingress.top に設定します rules: - matches: # マッチングルールはパスのプレフィックスマッチです - path: type: PathPrefix value: / backendRefs: # バックエンドとそれに対応する重みを設定します。重みはパーセンテージではなく、合計が 100 になる必要はありません。 - kind: Service name: old-nginx port: 80 weight: 100 # old-nginx の重みを 100 に設定します - kind: Service name: new-nginx port: 80 weight: 100 # new-nginx の重みを 100 に設定しますこのルーティングルールは、
old-nginxサービスとnew-nginxサービスに同じ重みを設定します。したがって、アプリケーションにアクセスすると、トラフィックはnew-nginxサービスとold-nginxサービスの間で 1:1 の比率で分散されます。アプリケーションとルーティングルールをデプロイします。
kubectl apply -f nginx.yaml kubectl apply -f httproute-weight.yamlアプリケーションに 10 回アクセスします。
for i in {1..10}; do curl -H "Host: weight.ingress.top" http://${ALB_DOMAIN}/; done期待される出力:
old new new old new old old new new old出力は、トラフィックが
new-nginxサービスとold-nginxサービスの間で 1:1 の比率で分散されていることを示します。
関連操作
アプリケーションの証明書を設定する
Gateway リソースでアプリケーションの TLS 証明書を設定できます。
ドメイン名
ingress.tapの自己署名証明書を作成します。openssl req -subj '/CN=ingress.top' -new -newkey rsa:2048 -sha256 \ -days 365 -nodes -x509 -keyout server.key -out server.crt \ -addext "subjectAltName = DNS:ingress.top" \ -addext "keyUsage = digitalSignature" \ -addext "extendedKeyUsage = serverAuth" 2> /dev/null; openssl x509 -in server.crt -subject -nooutTLS Secret を作成します。
kubectl create secret tls ingress.top --key server.key --cert server.crtgateway-tls.yaml ファイルを作成して Gateway を更新します。
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: alb namespace: default spec: gatewayClassName: alb listeners: - name: http protocol: HTTP port: 80 hostname: "*.ingress.top" allowedRoutes: namespaces: from: Same - name: https protocol: HTTPS port: 443 hostname: "*.ingress.top" allowedRoutes: namespaces: from: Same tls: # TLS を設定 mode: Terminate certificateRefs: # 作成したシークレットを参照 - kind: Secret name: ingress.topGateway を更新します。
gateway.gateway.networking.k8s.io/alb configuredGateway の Programmed ステータスが True に変更された後、証明書の設定を確認できます。
openssl s_client -servername ingress.top -connect ${ALB_DOMAIN}:443期待される出力:
CONNECTED(00000003) depth=0 CN = ingress.top verify error:num=18:self-signed certificate verify return:1 depth=0 CN = ingress.top verify return:1 --- Certificate chain 0 s:CN = ingress.top i:CN = ingress.top a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256 v:NotBefore: Jun 24 10:49:39 2025 GMT; NotAfter: Jun 24 10:49:39 2026 GMT --- Server certificate -----BEGIN CERTIFICATE----- ... ... ... -----END CERTIFICATE----- subject=CN = ingress.top issuer=CN = ingress.top --- No client certificate CA names sent Peer signing digest: SHA256 Peer signature type: RSA-PSS Server Temp Key: X25519, 253 bits --- SSL handshake has read 1506 bytes and written 410 bytes Verification error: self-signed certificate --- New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES128-GCM-SHA256 Session-ID: xxxxxxxxxxxxxxxxxxxxxxxxx Session-ID-ctx: Master-Key: xxxxxxxxxxxxxxxxxxxxxxxxxxx PSK identity: None PSK identity hint: None SRP username: None TLS session ticket lifetime hint: 300 (seconds) TLS session ticket: ... ... ... Start Time: 1750820008 Timeout : 7200 (sec) Verify return code: 18 (self-signed certificate) Extended master secret: yes ---上記と同様の出力が返された場合、証明書は有効です。
説明curl -H "Host: demo.ingress.top" -k https://${ALB_DOMAIN}/versionを実行してアプリケーションにアクセスできます。期待される出力は、「アプリケーションへのアクセスをテストする」の出力と同じです。