Gateway with Inference Extension コンポーネントを使用すると、クラスターのグローバルレート制限を有効にして、高い同時実行性や異常なトラフィックが発生した場合でもシステムの安定性を確保できます。このトピックでは、Gateway with Inference Extension コンポーネントを使用してグローバルレート制限を構成する方法と、サポートされているシナリオのデモについて説明します。
仕組み
レート制限は、サーバーに送信されるリクエストの数を制限するメカニズムです。これにより、クライアントが特定の期間内にサーバーに送信できるリクエストの最大数が指定されます。これは通常、1 分あたり 300 リクエストや 1 秒あたり 10 リクエストなど、単位時間あたりのリクエスト数として表されます。Gateway with Inference Extension コンポーネントでグローバルレート制限を有効にすると、グローバルレート制限サービスが自動的にデプロイされます。このサービスは、グローバルレート制限ポリシーとリアルタイムのトラフィックデータを一元的に管理し、動的に提供します。Gateway with Inference Extension は、Rate Limit Filter などの組み込みフィルターを介してグローバルレート制限サービスと対話します。1 秒あたりのリクエスト数や同時接続数などの事前に設定されたしきい値をリアルタイムで取得し、これらのポリシーを使用して受信リクエストのレートを制限します。
前提条件
Gateway with Inference Extension 1.4.0 以降がインストールされていること。
「事前準備」の手順を完了していること。
操作手順
ステップ 1: グローバルレート制限の有効化
グローバルレート制限のために自動的にデプロイされるレート制限サービスは、グローバルストレージとして Redis サービスに依存します。本 Topic では、セルフマネージド Redis サービスを例として使用します。また、Tair (Redis OSS-compatible) を使用して、Redis インスタンスをすばやく作成することもできます。Tair を使用する場合は、envoy-gateway-system 名前空間にある ack-gateway-config 設定項目の設定情報を更新する必要があります。設定の詳細については、「Envoy Gateway」をご参照ください。
redis-service.yaml という名前のファイルを作成します。
kind: Namespace apiVersion: v1 metadata: name: redis-system --- apiVersion: apps/v1 kind: StatefulSet metadata: name: redis namespace: redis-system labels: app: redis spec: serviceName: "redis" replicas: 1 selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - image: registry-cn-hangzhou.ack.aliyuncs.com/dev/redis:6.0.6-for-ack-gateway name: redis ports: - containerPort: 6379 resources: limits: cpu: 1500m memory: 512Mi requests: cpu: 200m memory: 256Mi --- apiVersion: v1 kind: Service metadata: name: redis namespace: redis-system labels: app: redis spec: ports: - name: redis port: 6379 protocol: TCP targetPort: 6379 selector: app: redisenable-global-rate-limit.yaml という名前のファイルを作成します。
apiVersion: v1 kind: ConfigMap metadata: name: ack-gateway-config namespace: envoy-gateway-system data: ack-gateway.yaml: | apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyGateway rateLimit: backend: type: Redis redis: url: redis.redis-system.svc.cluster.local:6379Redis サービスをデプロイし、グローバルレート制限を有効にします。
kubectl apply -f redis-service.yaml kubectl apply -f enable-global-rate-limit.yaml
ステップ 2: HTTPRoute リソースのデプロイ
テスト用の HTTPRoute リソースを作成します。レート制限ルールはこのリソースに適用されます。
httproute.yaml という名前のファイルを作成します。
--- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: http-ratelimit spec: parentRefs: - name: eg hostnames: - ratelimit.example rules: - matches: - path: type: PathPrefix value: / backendRefs: - group: "" kind: Service name: backend port: 3000HTTPRoute リソースをデプロイします。
kubectl apply -f httproute.yamlGateway のパブリック IP アドレスを取得します。
export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
ステップ 3: デモ
特定のユーザーに対するレート制限
リクエストヘッダー `x-user-id` の値が `one` であるリクエストを 1 時間あたり 3 リクエストに制限するグローバルレート制限ルールを構成します。
backendtrafficpolicy.yamlという名前のファイルを作成します。apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: name: policy-httproute spec: targetRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: http-ratelimit rateLimit: type: Global global: rules: - clientSelectors: - headers: - name: x-user-id value: one limit: requests: 3 unit: Hourレート制限ルールをデプロイします。
kubectl apply -f backendtrafficpolicy.yamlx-user-id: oneリクエストヘッダーを持つリクエストのレート制限をテストします。for i in {1..4}; do kubectl exec deployment/sleep -it -- curl -I --header "Host: ratelimit.example" --header "x-user-id: one" http://$GATEWAY_HOST/get ; sleep 1; done期待される出力:
HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:47:49 GMT content-length: 504 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 2 x-ratelimit-reset: 731 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:47:50 GMT content-length: 504 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 1 x-ratelimit-reset: 730 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:47:52 GMT content-length: 504 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 0 x-ratelimit-reset: 728 HTTP/1.1 429 Too Many Requests x-envoy-ratelimited: true x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 0 x-ratelimit-reset: 727 date: Tue, 27 May 2025 07:47:52 GMT transfer-encoding: chunked出力から、最初の 3 つのリクエストは
200を返し、4 番目のリクエストは429を返すことがわかります。これは、レート制限ルールがx-user-id: oneリクエストヘッダーを持つリクエストに適用されることを示しています。x-user-id: twoリクエストヘッダーを持つリクエストに対するレート制限をテストします。for i in {1..4}; do kubectl exec deployment/sleep -it -- curl -I --header "Host: ratelimit.example" --header "x-user-id: two" http://$GATEWAY_HOST/get ; sleep 1; done期待される出力:
HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:50:11 GMT content-length: 504 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:50:12 GMT content-length: 504 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:50:14 GMT content-length: 504 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:50:15 GMT content-length: 504出力は、4つのリクエストすべてが
200を返したことを示しています。これは、x-user-id: twoリクエストヘッダーを持つリクエストにはレート制限ルールが適用されていないことを意味します。
管理者以外のユーザーに対する個別レート制限
グローバルレート制限ルールを更新して、リクエストヘッダー `x-user-id` が `admin` に設定されているリクエストは制限せず、他のヘッダー値を持つリクエストは 1 時間あたり 3 リクエストに制限します。
レート制限ルールを編集します。
kubectl edit BackendTrafficPolicy policy-httprouteレート制限ルールを次の内容で更新します。
... rateLimit: type: Global global: rules: - clientSelectors: - headers: - type: Distinct name: x-user-id - name: x-user-id value: admin invert: true limit: requests: 3 unit: Hour保存して終了すると、レート制限ルールはすぐに有効になります。
x-user-id: oneリクエストヘッダーを持つリクエストのレート制限をテストします。for i in {1..4}; do kubectl exec deployment/sleep -it -- curl -I --header "Host: ratelimit.example" --header "x-user-id: one" http://$GATEWAY_HOST/get ; sleep 1; done期待される出力:
HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:47:49 GMT content-length: 504 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 2 x-ratelimit-reset: 731 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:47:50 GMT content-length: 504 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 1 x-ratelimit-reset: 730 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:47:52 GMT content-length: 504 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 0 x-ratelimit-reset: 728 HTTP/1.1 429 Too Many Requests x-envoy-ratelimited: true x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 0 x-ratelimit-reset: 727 date: Tue, 27 May 2025 07:47:52 GMT transfer-encoding: chunked出力は、最初の 3 つのリクエストが
200を返し、4 番目のリクエストが429を返すことを示しています。これは、x-user-id: oneリクエストヘッダーを持つリクエストにレート制限ルールが適用されることを示します。x-user-id: twoリクエストヘッダーを含むリクエストのレート制限をテストします。for i in {1..4}; do kubectl exec deployment/sleep -it -- curl -I --header "Host: ratelimit.example" --header "x-user-id: two" http://$GATEWAY_HOST/get ; sleep 1; done期待される出力:
HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:53:38 GMT content-length: 504 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 2 x-ratelimit-reset: 382 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:53:39 GMT content-length: 504 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 1 x-ratelimit-reset: 381 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:53:41 GMT content-length: 504 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 0 x-ratelimit-reset: 379 HTTP/1.1 429 Too Many Requests x-envoy-ratelimited: true x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 0 x-ratelimit-reset: 378 date: Tue, 27 May 2025 07:53:41 GMT transfer-encoding: chunked出力結果では、最初の 3 つのリクエストが
200を返し、4 番目のリクエストが429を返します。これは、x-user-id: twoリクエストヘッダーを持つリクエストにレート制限ルールが適用されていることを示しています。x-user-id: adminリクエストヘッダーを持つリクエストのレート制限をテストします。for i in {1..4}; do kubectl exec deployment/sleep -it -- curl -I --header "Host: ratelimit.example" --header "x-user-id: admin" http://$GATEWAY_HOST/get ; sleep 1; done期待される出力:
HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:57:44 GMT content-length: 506 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:57:45 GMT content-length: 506 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:57:46 GMT content-length: 506 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 07:57:47 GMT content-length: 506出力から、4つのリクエストすべてが
200を返すことがわかります。これは、x-user-id: adminリクエストヘッダーを持つリクエストにはレート制限ルールが適用されないことを示しています。
すべてのリクエストに対するレート制限
グローバルレート制限ルールを更新して、すべてのリクエストを 1 時間あたり 3 リクエストに制限します。
レート制限ルールを編集します。
kubectl edit BackendTrafficPolicy policy-httprouteレート制限ルールを次の内容で更新します。
... rateLimit: type: Global global: rules: - limit: requests: 3 unit: Hour保存して終了すると、レート制限ルールはすぐに有効になります。
通常のリクエストのレート制限をテストします。
for i in {1..4}; do kubectl exec deployment/sleep -it -- curl -I --header "Host: ratelimit.example" http://$GATEWAY_HOST/get ; sleep 1; done期待される出力:
HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 08:02:53 GMT content-length: 473 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 2 x-ratelimit-reset: 3427 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 08:02:55 GMT content-length: 473 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 1 x-ratelimit-reset: 3425 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 08:02:56 GMT content-length: 473 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 0 x-ratelimit-reset: 3424 HTTP/1.1 429 Too Many Requests x-envoy-ratelimited: true x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 0 x-ratelimit-reset: 3423 date: Tue, 27 May 2025 08:02:57 GMT transfer-encoding: chunked出力は、最初の3つのリクエストが
200を返し、4番目のリクエストが429を返すことを示しています。これは、レート制限ルールが適用されていることを意味します。
クライアント IP アドレスに基づくレート制限
グローバルレート制限ルールを更新して、CIDR ブロック内の各 IP アドレスを個別に 1 時間あたり 3 リクエストに制限します。
このシナリオでは、デモのため 0.0.0.0/0 CIDR ブロックを使用します。必要に応じて CIDR ブロックを調整してください。
レート制限ルールを編集します。
kubectl edit BackendTrafficPolicy policy-httprouteレート制限ルールを次の内容で更新します。
... rateLimit: type: Global global: rules: - clientSelectors: - sourceCIDR: value: 0.0.0.0/0 type: Distinct limit: requests: 3 unit: Hour保存して終了すると、レート制限ルールはすぐに有効になります。
通常のリクエストのレート制限をテストします。
for i in {1..4}; do kubectl exec deployment/sleep -it -- curl -I --header "Host: ratelimit.example" http://$GATEWAY_HOST/get ; sleep 1; done期待される出力:
HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 08:02:53 GMT content-length: 473 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 2 x-ratelimit-reset: 3427 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 08:02:55 GMT content-length: 473 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 1 x-ratelimit-reset: 3425 HTTP/1.1 200 OK content-type: application/json x-content-type-options: nosniff date: Tue, 27 May 2025 08:02:56 GMT content-length: 473 x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 0 x-ratelimit-reset: 3424 HTTP/1.1 429 Too Many Requests x-envoy-ratelimited: true x-ratelimit-limit: 3, 3;w=3600 x-ratelimit-remaining: 0 x-ratelimit-reset: 3423 date: Tue, 27 May 2025 08:02:57 GMT transfer-encoding: chunked出力は、最初の 3 つのリクエストが
200を返し、4 番目のリクエストが429を返すことを示しています。これは、0.0.0.0/0のレート制限ルールが有効になったことを示しています。
(オプション) ステップ 4: テストリソースのクリーンアップ
レート制限ルールを削除します。
kubectl delete BackendTrafficPolicy policy-httproute他のリソースを削除します。
kubectl delete -f httproute.yaml kubectl delete -f redis-service.yaml kubectl delete -f enable-global-rate-limit.yaml