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 1mACCEPTED: 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.yamlGateway と 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: - 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: 80Gateway と HTTPRoute を適用します:
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 2m12sPROGRAMMED: Trueは、ALB がアクティブであり、Gateway のアドレスが利用可能であることを示します。トラブルシューティングに役立つ条件やエラーメッセージなどの詳細なステータス情報を取得するには、次のコマンドを実行します:kubectl get gateway alb -o yamlHTTPRoute のステータスを確認します:
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トラフィックが流れるためには、両方の条件 (
AcceptedとResolvedRefs) でStatus: Trueと表示される必要があります。アプリケーションへのアクセスをテストします。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 は、相対的な重みの値に比例してトラフィックを分散します。
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: - 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 に分割されます。
両方のマニフェストを適用します:
kubectl apply -f nginx.yaml kubectl apply -f httproute-weight.yaml10 回リクエストを送信して、分散を確認します:
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-nginxとnew-nginxの間でほぼ 1:1 の割合で交互に返されます。
TLS 証明書の設定
Gateway に TLS 証明書をアタッチして HTTPS を有効にします。
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 -nooutTLS Secret を作成します:
kubectl create secret tls ingress.top --key server.key --cert server.crt既存の 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更新された Gateway を適用します:
kubectl apply -f gateway-tls.yaml期待される出力:
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 ---証明書チェーンの
CN = ingress.topエントリは、TLS 証明書がアクティブであることを示します。HTTPS 経由でのアプリケーションへのアクセスを検証するには:curl -H "Host: demo.ingress.top" -k https://${ALB_DOMAIN}/version