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

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

最終更新日:Mar 26, 2026

Gateway API は、トラフィックルーティングと負荷分散のための次世代 Kubernetes API です。このトピックでは、Gateway API を Application Load Balancer (ALB) と組み合わせて使用し、ルーティングルールを設定してクラスター外部にサービスを公開する方法について説明します。

前提条件

作業を開始する前に、以下の前提条件を満たしていることを確認してください:

  • バージョン 1.31 以降を実行している ACS クラスター

  • クラスターにインストールされているバージョン 2.17 以降の ALB Ingress Controller

  • クラスターにインストールされているバージョン 1.3.0 以降の Gateway API

  • クラスターの VPC に作成された、ALB をサポートする 2 つの vSwitch

環境の確認

すべての前提条件が満たされると、ALB Ingress Controller は自動的に alb という名前の GatewayClass を作成します。続行する前に、このリソースを確認してください。

kubectl

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

kubectl get gatewayclass

期待される出力:

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

ACCEPTED: True のステータスは、GatewayClass の準備が完了したことを示します。

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

次の内容で 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 と HTTPRoute のデプロイ

  1. 次の内容で 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:
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: alb
      hostnames:
        - demo.ingress.top
      rules:
        - matches:
            - path:
                type: PathPrefix
                value: /
          backendRefs:
            - kind: Service
              name: go-httpbin
              port: 80
  2. Gateway と HTTPRoute を適用します:

    kubectl apply -f gateway.yaml
  3. 約 2 分後、Gateway のステータスを確認します:

    kubectl get gateway alb

    期待される出力:

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

    PROGRAMMED: True は、ALB がアクティブであり、Gateway のアドレスが利用可能であることを示します。トラブルシューティングに役立つ条件やエラーメッセージなどの詳細なステータス情報を取得するには、次のコマンドを実行します:

    kubectl get gateway alb -o yaml
  4. HTTPRoute のステータスを確認します:

    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

    トラフィックが流れるためには、両方の条件 (AcceptedResolvedRefs) で Status: True と表示される必要があります。

  5. アプリケーションへのアクセスをテストします。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

適用してテストします:

kubectl apply -f httproute-filter.yaml
curl -H "Host: filter.ingress.top" http://${ALB_DOMAIN}/header

期待される出力 — フィルターによって挿入された My-Header: foo フィールドに注意してください:

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

重みに基づくトラフィック分割

複数のバックエンド Service に重みを割り当てて、トラフィックを比例的に分散します。重みはパーセンテージではなく、合計が 100 になる必要はありません。ALB は、相対的な重みの値に比例してトラフィックを分散します。

  1. 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

    上記のファイルは 2 つの NGINX アプリケーションをデプロイします。old-nginx サービスは old という文字列を返し、new-nginx サービスは new という文字列を返します。デプロイされたリソースは default 名前空間に配置されます。

  2. 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:
            - kind: Service
              name: old-nginx
              port: 80
              weight: 100
            - kind: Service
              name: new-nginx
              port: 80
              weight: 100

    等しい重みにより、2 つの Service 間でトラフィックが 1:1 に分割されます。

  3. 両方のマニフェストを適用します:

    kubectl apply -f nginx.yaml
    kubectl apply -f httproute-weight.yaml
  4. 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

    応答は old-nginxnew-nginx の間でほぼ 1:1 の割合で交互に返されます。

TLS 証明書の設定

Gateway に TLS 証明書をアタッチして HTTPS を有効にします。

  1. ingress.top ドメインの自己署名証明書を作成します:

    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
            certificateRefs:
              - kind: Secret
                name: ingress.top
  4. 更新された Gateway を適用します:

    kubectl apply -f gateway-tls.yaml

    期待される出力:

    gateway.gateway.networking.k8s.io/alb configured
  5. Gateway の 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
    ---

    証明書チェーンの CN = ingress.top エントリは、TLS 証明書がアクティブであることを示します。HTTPS 経由でのアプリケーションへのアクセスを検証するには:

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

次のステップ