Gateway API は、Kubernetes における次世代の Ingress およびロードバランシング API のための公式 Kubernetes プロジェクトです。 Gateway API を使用してトラフィックルーティングルールを構成できます。 このトピックでは、Gateway with Inference Extension を使用して Gateway API の基本機能を構成する方法について説明します。
背景情報
Gateway with Inference Extension は、Envoy Gateway プロジェクトに基づいて開発されており、Gateway API のすべての基本機能とオープンソースの Envoy Gateway 拡張機能を提供します。
Envoy Gateway のアーキテクチャは、次のコンポーネントで構成されています。
コントロールプレーン: Envoy Gateway コンポーネントで構成されます。 コントロールプレーンは、クラスタのトラフィックルーティングルールを監視し、Envoy プロキシインスタンスを動的に作成および管理する役割を担います。 コントロールプレーンは、Envoy プロキシインスタンスのトラフィック転送ルールを更新しますが、トラフィックの転送には直接使用されません。
データプレーン: 実行中の Envoy プロキシインスタンスで構成されます。 データプレーンは、効率的かつ信頼性の高いトラフィック処理と転送を実行する役割を担います。
前提条件
Kubernetes 1.30 以降を実行する Container Compute Service (ACS) クラスタ が作成されていること。
Gateway with Inference ExtensionGateway with Inference Extension がクラスターにインストールされていること。
準備
2 つのアプリケーション、
backendとbackend-2を作成します。説明backend アプリケーションを作成した後、YAML ファイルを修正し、
をbackend-2に置き換えて、修正した YAML ファイルを使用して backend-2 アプリケーションを作成します。apiVersion: v1 kind: ServiceAccount metadata: name: backend --- apiVersion: v1 kind: Service metadata: name: backend labels: app: backend service: backend spec: ports: - name: http port: 3000 targetPort: 3000 selector: app: backend --- apiVersion: apps/v1 kind: Deployment metadata: name: backend spec: replicas: 1 selector: matchLabels: app: backend version: v1 template: metadata: labels: app: backend version: v1 spec: serviceAccountName: backend containers: - image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/envoygateway-echo-basic:v20231214-v1.0.0-140-gf544a46e imagePullPolicy: IfNotPresent name: backend ports: - containerPort: 3000 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespaceGatewayClass を作成し、
controllerNameをgateway.envoyproxy.io/gatewayclass-controllerに設定します。apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: eg spec: controllerName: gateway.envoyproxy.io/gatewayclass-controllerGateway を作成します。
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: eg spec: gatewayClassName: eg listeners: - name: http protocol: HTTP port: 80Gateway を作成すると、Gateway with Inference Extension のコントロールプレーンは Gateway の構成を自動的に使用して、EnvoyProxy デプロイメントと、指定されたポートでリッスンする対応するロードバランシングサービスを作成します。 Server Load Balancing (SLB) インスタンスの請求ルールの詳細については、「SLB 請求」をご参照ください。
EnvoyProxy デプロイメントの構成をカスタマイズし、サービスのパラメーターをカスタマイズできます。 また、ゲートウェイの水平ポッド自動スケーリングを有効にすることもできます。
ゲートウェイの IP アドレスを取得します。
export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
パス・プレフィックス・マッチングに基づく HTTP ルーティングの構成
次の YAML ファイルのサンプルは、HTTPRoute を作成するために使用され、/get プレフィックスと一致します。
HTTPRoute を作成します。
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: eg hostnames: - "www.example.com" rules: - backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 1 matches: - path: type: PathPrefix value: /getアプリケーションにアクセスします。
curl -H "Host: www.example.com" http://$GATEWAY_HOST/get予期される出力:
{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "User-Agent": [ "curl/8.9.1" ], "X-Envoy-External-Address": [ "115.XX.XXX.55" ], "X-Forwarded-For": [ "115.XX.XXX.55" ], "X-Forwarded-Proto": [ "http" ], "X-Request-Id": [ "953b2f8f-26d3-4ba9-93ba-a482b197b1ff" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }
リクエストヘッダーを追加する
HTTPRoute を更新して、リクエストにヘッダーを追加します。
HTTPRoute を更新します。
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: eg hostnames: - "www.example.com" rules: - matches: - path: type: PathPrefix value: /get backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 1 filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: "added-header" value: "foo"アプリケーションにアクセスします。
curl -H "Host: www.example.com" http://$GATEWAY_HOST/get予期される出力:
{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "Added-Header": [ "foo" ], "User-Agent": [ "curl/8.9.1" ], "X-Envoy-External-Address": [ "115.XX.XXX.55" ], "X-Forwarded-For": [ "115.XX.XXX.55" ], "X-Forwarded-Proto": [ "http" ], "X-Request-Id": [ "d37f19e5-25c1-45cf-90e5-51453e7ae3ed" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }%アプリケーションの機能は、リクエストの内容を返すことです。 リクエストヘッダーが出力に表示されている場合、ヘッダーは正常に追加されています。
比例トラフィック分割を構成する
次の YAML テンプレートに基づいて HTTPRoute を更新します。 次の YAML テンプレートでは、backend-2 サービスのルーティングルールが追加され、backend サービスと backend-2 サービスのトラフィックウェイトが指定されています。
backendRefs パラメーターで指定するウェイトの合計は 100 である必要はありません。サービスにルーティングされるトラフィックの割合 =
HTTPRoute を更新します。
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: eg hostnames: - "www.example.com" rules: - matches: - path: type: PathPrefix value: /get backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 8 - group: "" kind: Service name: backend-2 port: 3000 weight: 2アプリケーションに 20 回アクセスし、2 つのサービス間の実際のトラフィック比率を確認します。
説明次のコマンドは、出力に
backendとbackend-2のみを表示するために使用されます。for i in $(seq 1 20); do curl -sS -H "Host: www.example.com" http://$GATEWAY_HOST/get |grep backend; done | \ sed -E 's/".*"(backend(-2)?)-[0-9a-zA-Z]*-.*/\1/'予期される出力:
backend-2 backend backend backend backend backend backend backend backend backend backend backend-2 backend-2 backend backend backend-2 backend backend backend backend出力は、リクエストの約 80% が backend サービスに転送され、残りの 20% が backend-2 サービスに転送されることを示しています。
TLS トラフィックを処理する
証明書と TLS リスナーを追加して、Gateway を更新します。
証明書を生成し、それを使用してシークレットを作成します。
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization" openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt kubectl create secret tls example-cert --key=www.example.com.key --cert=www.example.com.crt前の手順で作成した TLS リスナーと証明書を追加します。
kubectl patch gateway eg --type=json --patch ' - op: add path: /spec/listeners/- value: name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret group: "" name: example-cert '変更が成功したかどうかを確認します。
kubectl get gateway/eg -o yaml | grep spec: -A 20予期される出力:
spec: gatewayClassName: eg listeners: - allowedRoutes: namespaces: from: Same name: http port: 80 protocol: HTTP - allowedRoutes: namespaces: from: Same name: https port: 443 protocol: HTTPS tls: certificateRefs: - group: "" kind: Secret name: example-cert mode: Terminate status:出力は、変更が成功したことを示しています。
アプリケーションにアクセスします。
curl -H Host:www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ --cacert example.com.crt https://www.example.com/get予期される出力:
{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "User-Agent": [ "curl/8.9.1" ], "X-Envoy-External-Address": [ "115.XX.XXX.55" ], "X-Forwarded-For": [ "115.XX.XXX.55" ], "X-Forwarded-Proto": [ "https" ], "X-Request-Id": [ "ac539756-3826-474b-be2f-5e57fdd49dac" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }