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

kubectl
kubectl get gatewayclass期待される出力:
NAME CONTROLLER ACCEPTED AGE
alb gateways.alibabacloud.com/alb/v1 True 1mサンプルアプリケーションのデプロイ
httpbin.yaml ファイルを作成します。
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 とルートのデプロイ
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 という名前のサービス - 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 という名前のサービス - 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を実行してアプリケーションにアクセスできます。期待される出力は、「アプリケーションへのアクセスをテストする」ステップの出力と同じです。