すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:Gateway API と ALB を使用したサービスの公開

最終更新日:Jun 16, 2026

Gateway、HTTPRoute、および TLS リソースを構成して、Application Load Balancer (ALB) インスタンス経由で外部トラフィックを Container Service for Kubernetes (ACK) サービスにルーティングします。

リソースモデル

Gateway API では、3 つのリソースタイプが定義されており、それぞれに異なる役割が割り当てられています。

リソース 所有者 目的
[GatewayClass] インフラストラクチャプロバイダー (Alibaba Cloud) コントローラー (ここでは ALB Ingress コントローラー) がサポートする GatewayClass を定義します。
Gateway クラスターオペレーター ALB インスタンスをプロビジョニングし、リスナー (ポート、プロトコル、ホスト名) を構成します。
HTTPRoute アプリケーション開発者 受信リクエストをバックエンド Service にマッピングするルーティングルールを定義します。

プラットフォームチームがインフラストラクチャを管理し、アプリケーションチームがルーティングルールを独立して管理します。

ALB Ingress コントローラーは、バージョン 2.17.0 以降で Gateway API をサポートしています。

前提条件

次の条件を満たしていることを確認してください。

  • Kubernetes 1.24 以降を実行するACK マネージドクラスター

  • クラスターにALB Ingress コントローラーバージョン 2.17.0 以降がインストールされていること

  • クラスターにGateway API バージョン 1.1.0 以降がインストールされていること

  • クラスターがデプロイされている VPC 内に、ALB をサポートする 2 つの vSwitch があること

環境の検証

ALB Ingress コントローラーは、alb という名前の GatewayClass リソースを自動的に作成します。作業を続ける前に、このリソースが存在することを確認してください。

kubectl

GatewayClass を確認します。

kubectl get gatewayclass

出力例:

NAME   CONTROLLER                         ACCEPTED   AGE
alb    gateways.alibabacloud.com/alb/v1   True       1m

ACCEPTED: True は、GatewayClass が準備完了であることを示します。

サンプルアプリケーションのデプロイ

httpbin.yaml ファイルを作成します。

Service はデフォルトで ClusterIP を使用します。クラスターが Flannel ネットワークプラグインを使用している場合は、spec.typeNodePort に変更してください。
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 を作成すると ALB インスタンスがプロビジョニングされ、料金が発生します。Gateway が作成した ALB インスタンスは、クラスターを削除しても自動的には削除されません。意図しない料金の発生を避けるため、クラスターを削除する前に Gateway リソースを削除してください。

ステップ1:Gateway と HTTPRoute を作成する

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
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:       # 一致したトラフィックをポート 80 の go-httpbin に転送します
        - kind: Service
          name: go-httpbin
          port: 80

Gateway は、*.ingress.top 用にポート 80 で HTTP リスナーを設定した ALB インスタンスをプロビジョニングします。HTTPRoute は、demo.ingress.top のトラフィックを go-httpbin Service に転送します。

マニフェストを適用します。

kubectl apply -f gateway.yaml

ステップ2:Gateway が準備完了になるまで待機する

kubectl wait --for=condition=programmed gateway/alb --timeout=120s

Gateway のアドレスを確認します。

kubectl get gateway alb

出力例:

NAME   CLASS   ADDRESS                                                  PROGRAMMED   AGE
alb    alb     alb-0mwhq4ck6xxxxxxxxx.cn-hangzhou.alb.aliyuncsslb.com   True         2m12s

ステップ3:HTTPRoute のステータスを確認する

kubectl describe httproute demo-route | grep Status -A 20

出力例:

Status:
  Parents:
    Conditions:
      Last Transition Time:  2024-05-23T08:21:25Z
      Message:               Route is accepted.
      Observed Generation:   1
      Reason:                Accepted
      Status:                True
      Type:                  Accepted
      Last Transition Time:  2024-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

Accepted: TrueResolvedRefs: True は、ルートがアクティブであることを示します。

ステップ4:アクセスをテストする

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

ユースケース

フィルターを使用したリクエストヘッダーの変更

HTTPRoute フィルターを使用すると、転送中のリクエストまたはレスポンスを書き換えることができます。この例では、カスタムリクエストヘッダーを追加します。

httproute-filter.yaml ファイルを作成します。

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: demo-filter
spec:
  parentRefs:
    - group: gateway.networking.k8s.io
      kind: Gateway
      name: alb
  hostnames:
    - filter.ingress.top
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            add:
              - name: my-header
                value: foo
      backendRefs:
        - kind: Service
          name: go-httpbin
          port: 80

RequestHeaderModifier フィルターは、リクエストがバックエンドに到達する前にリクエストを変更します。

  • 一致するリクエストに my-header: foo を追加します。

  • add アクションは、同じ名前の既存のヘッダーを置き換えるのではなく、ヘッダーを追加します。

ルーティングルールを適用します。

kubectl apply -f httproute-filter.yaml

リクエストヘッダーを返す /header エンドポイントでテストします。

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

出力に My-Header: foo が含まれていることで、フィルターが機能していることを確認できます。

重みによるトラフィックの分割

複数のバックエンド Service に重みを割り当てて、カナリアデプロイメントなどのためにトラフィックを比例的に分散させます。

2 つの NGINX Deployment を含む nginx.yaml ファイルを作成します。

展開してYAMLコンテンツを表示

apiVersion: apps/v1
kind: Deployment
metadata:
  name: old-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      run: old-nginx
  template:
    metadata:
      labels:
        run: old-nginx
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx
        imagePullPolicy: Always
        name: old-nginx
        ports:
        - containerPort: 80
          protocol: TCP
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: old-nginx
spec:
  type: ClusterIP
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: old-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: new-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      run: new-nginx
  template:
    metadata:
      labels:
        run: new-nginx
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
        imagePullPolicy: Always
        name: new-nginx
        ports:
        - containerPort: 80
          protocol: TCP
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: new-nginx
spec:
  type: ClusterIP
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: new-nginx

old-nginxold を返し、new-nginxnew を返します。両方とも default 名前空間にデプロイされます。

httproute-weight.yaml ファイルを作成します。

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: demo-weight
spec:
  parentRefs:
    - group: gateway.networking.k8s.io
      kind: Gateway
      name: alb
  hostnames:
    - weight.ingress.top
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        # 重みはパーセンテージではなく相対値のため、合計が 100 になる必要はありません。
        - kind: Service
          name: old-nginx
          port: 80
          weight: 100
        - kind: Service
          name: new-nginx
          port: 80
          weight: 100

両方のバックエンドの重みが等しい (100:100) ため、トラフィックは 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

トラフィックは 2 つのバックエンド間でほぼ 1:1 に分割されます。

TLS 証明書の構成

TLS 証明書を含む Kubernetes Secret を参照して、Gateway に HTTPS 終端を追加します。

ステップ1:自己署名証明書を作成する

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 -noout

ステップ2:TLS Secret を作成する

kubectl create secret tls ingress.top --key server.key --cert server.crt

ステップ3:Gateway を更新して HTTPS リスナーを追加する

gateway-tls.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
    - name: https
      protocol: HTTPS
      port: 443
      hostname: "*.ingress.top"
      allowedRoutes:
        namespaces:
          from: Same
      tls:
        mode: Terminate          # ALB が TLS を終端し、平文の HTTP をバックエンドに転送します
        certificateRefs:
          - kind: Secret
            name: ingress.top   # 前のステップで作成した Secret

Terminate モードでは、ALB が HTTPS トラフィックを復号化し、平文の HTTP をバックエンドに転送します。certificateRefs フィールドは、証明書とプライベートキーが格納された Secret を参照します。

更新を適用します。

kubectl apply -f gateway-tls.yaml

ステップ4:証明書を検証する

Gateway の PROGRAMMED ステータスが True に戻るまで待機します。

kubectl wait --for=condition=programmed gateway/alb --timeout=120s

証明書を検証します。

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 2024 GMT; NotAfter: Jun 24 10:49:39 2025 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
subject=CN = ingress.top
issuer=CN = ingress.top
---
...
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
...
Verify return code: 18 (self-signed certificate)

CN = ingress.topTLSv1.2 暗号は、TLS 終端が機能していることを示します。self-signed certificate エラーは想定内の動作です。本番環境では CA 署名証明書を使用してください。

自己署名証明書の検証をスキップする -k フラグを使用して、HTTPS アクセスをテストします。

curl -H "Host: demo.ingress.top" -k https://${ALB_DOMAIN}/version

出力例:

version: v1
hostname: go-httpbin-547xxxxxf6-xxxxx

次のステップ

  • Gateway API:ヘッダーベースのマッチングやトラフィックミラーリングなどの高度なルーティングを含む完全な仕様。

  • ALB Ingress コントローラー:本番ワークロード向けの ALB 固有のアノテーションと構成。