スロットリングは、サービスに送信されるリクエスト数を制限するメカニズムです。これは、クライアントが一定期間内にサービスに送信できるリクエストの最大数を指定します(1分あたり300リクエスト、1秒あたり10リクエストなど)。バージョン 1.18.0.131以降の Service Mesh (ASM) では、イングレスゲートウェイと、サイドカープロキシが挿入されたサービスへのインバウンドトラフィックに対してグローバルスロットリングを設定できます。このトピックでは、ASMGlobalRateLimiterを使用して、ASMのサービスへのインバウンドトラフィックのグローバルスロットリングを設定する方法について説明します。
前提条件
コンテナサービスKubernetes (ACK) マネージドクラスターがASMインスタンスに追加されます。ASMインスタンスのバージョンは V1.18.0.131以降です。詳細については、「ASMインスタンスへのクラスターの追加」をご参照ください。
ACKクラスターのデフォルトの名前空間で、サイドカープロキシの自動挿入が有効になっています。詳細については、「グローバル名前空間の管理」トピックの「サイドカープロキシの自動挿入を有効にする」セクションをご参照ください。
ingressgatewayという名前のASMイングレスゲートウェイが作成され、ポート 80 が有効になっています。詳細については、「イングレスゲートウェイの作成」をご参照ください。
サンプルアプリケーションであるsleepとHTTPBinがデプロイされています。詳細については、「HTTPBinアプリケーションのデプロイ」と「データプレーンのクラスターへのsleepサービスのデプロイ」をご参照ください。
スロットリングサービスのデプロイ
グローバルスロットリング機能を有効にする前に、データプレーンのクラスターにスロットリングサービスをデプロイする必要があります。次の手順では、スロットリングサービスと、スロットリングサービスが依存するサンプルアプリケーションをデプロイする方法について説明します。
Envoyプロキシは、グローバルスロットリングとローカルスロットリングの2つのモードでスロットリングを実装します。このトピックでは、グローバルスロットリングの設定方法のみについて説明します。スロットリングとローカルスロットリングの設定方法の詳細については、「Traffic Management Centerでのローカルスロットリングの設定」をご参照ください。
次の内容を含む ratelimit-svc.yamlファイルを作成します。
kubeconfigファイルの情報に基づいてkubectlを使用してACKクラスターに接続し、次のコマンドを実行して、スロットリングサービスと、スロットリングサービスが依存するRedisサービスを作成します。
kubectl apply -f ratelimit-svc.yaml
シナリオ 1: サービスの特定のポートでグローバルスロットリングを設定する
HTTPBinサービスのポート 8000 にスロットリングルールを設定します。スロットリングルールが設定されると、HTTPBinサービスのポート 8000 宛てのすべてのリクエストがスロットリングの対象となります。
次の内容を含む global-ratelimit-svc.yamlファイルを作成します。
次の表に、いくつかのフィールドについて説明します。詳細については、「ASMGlobalRateLimiterフィールドの説明」をご参照ください。
フィールド
説明
workloadSelectorスロットリングルールが有効になるワークロード。この例では、グローバルスロットリングをHTTPBinサービスのワークロードで有効にする必要があります。このフィールドに
app: httpbinを設定します。isGatewayスロットリングルールをゲートウェイで有効にするかどうかを指定します。この例では、値は
falseに設定されています。rateLimitServiceスロットリングサービスのドメイン名、ポート、および接続タイムアウト設定。シナリオ 1:サービスの特定のポートでグローバルスロットリングを設定する でデプロイされたスロットリングサービスの設定を次のコードブロックに示します。
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5limit有効にするスロットリングパラメーター。
unitは、スロットリング検出の時間単位を示します。quotaは、単位時間あたりに許可されるリクエストの総数を示します。この例では、
unitはMINUTEに設定され、quotaは1に設定されています。これは、一致するルートでは1分あたり1つのリクエストしか送信できないことを示します。リクエスト数が1を超えると、スロットリングがトリガーされます。vhostスロットリングが有効になるドメイン名とルート。設定をHTTPBinサービスで有効にするには、
nameを'*'に設定し、portをHTTPBinサービスのサービスポートに設定する必要があります。kubeconfigファイルの情報に基づいてkubectlを使用してASMインスタンスに接続し、次のコマンドを実行して、HTTPBinサービスのインバウンドトラフィックで有効になるグローバルスロットリングルールを作成します。
kubectl apply -f global-ratelimit-svc.yaml次のコマンドを実行して、グローバルスロットリングルールの設定を取得します。
kubectl get asmglobalratelimiter global-svc-test -o yaml前の手順で生成されたASMGlobalRateLimiterの
statusセクションにあるconfig.yamlフィールドの内容をコピーして ratelimit-config.yamlファイルに貼り付け、グローバルスロットリングサービス設定を生成します。ASMGlobalRateLimiterの
statusセクションにあるconfig.yamlフィールドの文字列コンテンツは、変更せずにConfigMapのdataセクションにあるconfig.yamlフィールドに貼り付ける必要があります。kubeconfigファイルの情報に基づいてkubectlを使用してACKクラスターに接続し、次のコマンドを実行して、ACKクラスターのグローバルスロットリングサービス設定を更新します。
kubectl apply -f ratelimit-config.yaml次のコマンドを実行して、sleepサービスのbashを有効にします。
kubectl exec -it deploy/sleep -- sh次のコマンドを実行して、HTTPBinサービスに2回アクセスします。
curl httpbin:8000/get -v curl httpbin:8000/get -v予期される出力:
< HTTP/1.1 429 < x-envoy-ratelimited: true < x-ratelimit-limit: 1, 1;w=60 < x-ratelimit-remaining: 0 < x-ratelimit-reset: 5 < date: Thu, 26 Oct 2023 04:23:54 GMT < server: envoy < content-length: 0 < x-envoy-upstream-service-time: 2 < * Connection #0 to host httpbin left intactグローバルスロットリング設定では、1分以内にHTTPBinアプリケーションにアクセスできるリクエストは1つだけです。HTTPBinアプリケーションに2回アクセスすると、2番目のリクエストでスロットリングがトリガーされることがわかります。これは、サイドカープロキシが挿入されたサービスのインバウンドトラフィックでグローバルスロットリングが有効になっていることを示します。
シナリオ 2:サービスの特定のポートの指定されたパス宛てのリクエストに対してスロットリングルールを設定する
HTTPBinサービスのポート 8000 にスロットリングルールを設定し、/headers パス宛てのリクエストに対してのみスロットリングが有効になるように指定します。スロットリングルールが設定されると、HTTPBinサービスのポート 8000 と /headers パス宛てのすべてのリクエストがスロットリングの対象となります。
ASMインスタンスのバージョンに基づいて、必要に応じて次のコンテンツを使用して global-ratelimit-svc.yamlファイルを作成します。
v1.19.0より前のASMインスタンスの場合
v1.19.0以降のASMインスタンスの場合
次の表に、いくつかのフィールドについて説明します。詳細については、「ASMGlobalRateLimiterフィールドの説明」をご参照ください。
フィールド
説明
workloadSelectorスロットリングルールが有効になるワークロード。この例では、グローバルスロットリングをHTTPBinサービスのワークロードで有効にする必要があります。このフィールドに
app: httpbinを設定します。isGatewayスロットリングルールをゲートウェイで有効にするかどうかを指定します。この例では、値は
falseに設定されています。rateLimitServiceスロットリングサービスのドメイン名、ポート、および接続タイムアウト設定。シナリオ 1:サービスの特定のポートでグローバルスロットリングを設定する でデプロイされたスロットリングサービスの設定を次のコードブロックに示します。
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5limit有効にするスロットリングパラメーター。
unitは、スロットリング検出の時間単位を示します。quotaは、単位時間あたりに許可されるリクエストの総数を示します。この例では、
unitはMINUTEに設定され、quotaは1に設定されています。これは、一致するルートでは1分あたり1つのリクエストしか送信できないことを示します。リクエスト数が1を超えると、スロットリングがトリガーされます。ASMインスタンスが V1.19.0以降の場合は、unitは SECOND に設定され、quotaは 100000 に設定されます。これは、一致するルートでは1秒あたり 100,000 件のリクエストを送信できることを示します。スロットリングが設定されていないとみなすことができます。
limit_overridesフィールドを使用して、特定の要件を満たすリクエストに対してスロットリングを設定できます。vhostスロットリングが有効になるドメイン名とルート。設定をHTTPBinサービスで有効にするには、
nameを'*'に設定し、portをHTTPBinサービスのサービスポートに設定する必要があります。ASMインスタンスが V1.19.0より前の場合、
routeセクションでリクエストのヘッダー照合ルールを設定することもできます。この例では、:pathという名前の特殊なヘッダーを使用してリクエストパスを照合します。これは、パスがスラッシュ (/) で始まるすべてのリクエストが一致することを示します。ASMインスタンスが V1.19.0以降の場合は、
limit_overridesフィールドでリクエストのヘッダー照合ルールを設定できます。
limit_overridesスロットリングしきい値のオーバーライド設定。このフィールドは、V1.19.0以降のASMインスタンスでのみサポートされています。さまざまなリクエスト属性を照合できます。オーバーライド設定で指定されたスロットリングアクションは、一致するリクエストに適用されます。この例では、
limit_overridesフィールドで、:pathという名前の特殊なヘッダーを使用してリクエストパスを照合するように指定しています。これは、パスが/headersで始まるすべてのリクエストが一致することを示します。
kubeconfigファイルの情報に基づいてkubectlを使用してASMインスタンスに接続し、次のコマンドを実行して、HTTPBinサービスのインバウンドトラフィックで有効になるグローバルスロットリングルールを作成します。
kubectl apply -f global-ratelimit-svc.yaml次のコマンドを実行して、グローバルスロットリングルールの設定を取得します。
kubectl get asmglobalratelimiter global-svc-test -o yaml前の手順で生成されたASMGlobalRateLimiterの
statusセクションにあるconfig.yamlフィールドの内容をコピーして ratelimit-config.yamlファイルに貼り付け、グローバルスロットリングサービス設定を生成します。ASMGlobalRateLimiterの
statusセクションにあるconfig.yamlフィールドの文字列コンテンツは、変更せずにConfigMapのdataセクションにあるconfig.yamlフィールドに貼り付ける必要があります。kubeconfigファイルの情報に基づいてkubectlを使用してACKクラスターに接続し、次のコマンドを実行して、ACKクラスターのグローバルスロットリングサービス設定を更新します。
kubectl apply -f ratelimit-config.yaml次のコマンドを実行して、sleepサービスのbashを有効にします。
kubectl exec -it deploy/sleep -- sh次のコマンドを実行して、HTTPBinサービスの
/headersパスに2回アクセスします。curl httpbin:8000/headers -v curl httpbin:8000/headers -v予期される出力:
< HTTP/1.1 429 Too Many Requests < x-envoy-ratelimited: true < x-ratelimit-limit: 1, 1;w=60 < x-ratelimit-remaining: 0 < x-ratelimit-reset: 5 < date: Thu, 26 Oct 2023 04:23:54 GMT < server: envoy < content-length: 0 < x-envoy-upstream-service-time: 2 < * Connection #0 to host httpbin left intactグローバルスロットリング設定では、1分以内にHTTPBinサービスの
/headersパスにアクセスできるリクエストは1つだけです。1分以内にHTTPBinサービスの /headers パスに2回アクセスすると、2番目のリクエストがスロットリングされることがわかります。これは、サイドカープロキシが挿入されたHTTPBinサービスのインバウンドトラフィックでグローバルスロットリングが有効になっていることを示します。次のコマンドを実行して、HTTPBinサービスの
/getパスにアクセスします。curl httpbin:8000/get -v出力は、HTTPBinサービスの /get パス宛てのリクエストが成功したことを示しています。これは、HTTPBinサービスの他のパスへのリクエストはスロットリングルールの対象ではないことを示しています。
関連操作
グローバルスロットリングに関連するメトリックを表示する
次の表に、グローバルスロットリングに関連するメトリックを示します。
メトリック | メトリックタイプ | 説明 |
envoy_cluster_ratelimit_ok | カウンター | グローバルスロットリングで許可されたリクエストの総数 |
envoy_cluster_ratelimit_over_limit | カウンター | グローバルスロットリングによってスロットリングがトリガーされると判断されたリクエストの総数 |
envoy_cluster_ratelimit_error | カウンター | グローバルスロットリングの呼び出しに失敗したリクエストの総数 |
サイドカープロキシの proxyStatsMatcher パラメーターを設定して、サイドカープロキシがメトリックを報告できるようにすることができます。その後、Prometheusを使用して、スロットリングに関連するメトリックを収集して表示できます。
proxyStatsMatcherパラメーターを設定して、サイドカープロキシがスロットリング関連のメトリックを報告できるようにします。proxyStatsMatcherを選択した後、[正規表現一致] を選択し、値を
.*ratelimit.*に設定します。詳細については、「サイドカープロキシの設定」トピックの「proxyStatsMatcher」セクションをご参照ください。HTTPBinサービスを再デプロイします。詳細については、「サイドカープロキシの設定」トピックの「(オプション) ワークロードの再デプロイ」セクションをご参照ください。
ローカルスロットリングを設定し、リクエストテストを実行します。詳細については、シナリオ 1 または「Traffic Management Centerでのローカルスロットリングの設定」をご参照ください。
次のコマンドを実行して、HTTPBinサービスのグローバルスロットリングメトリックを表示します。
kubectl exec -it deploy/httpbin -c istio-proxy -- curl localhost:15090/stats/prometheus|grep envoy_cluster_ratelimit予期される出力:
# TYPE envoy_cluster_ratelimit_ok counter envoy_cluster_ratelimit_ok{cluster_name="inbound|80||"} 904 # TYPE envoy_cluster_ratelimit_over_limit counter envoy_cluster_ratelimit_over_limit{cluster_name="inbound|80||"} 3223
グローバルスロットリングのメトリック収集とアラートを設定する
Prometheusインスタンスを設定して、メッシュプロキシによって公開されるグローバルスロットリングメトリックを収集できます。また、主要なメトリックに基づいてアラートルールを設定して、スロットリングが発生したときにアラートが生成されるようにすることもできます。このセクションでは、グローバルスロットリングのメトリック収集とアラートを設定する方法について説明します。この例では、Managed Service for Prometheusを使用します。
Managed Service for Prometheusで、データプレーンのACKクラスターを [alibaba Cloud ASM] コンポーネントに接続するか、Alibaba Cloud ASMコンポーネントを最新バージョンにアップグレードします。これにより、グローバルスロットリングメトリックを Managed Service for Prometheus で確実に収集できます。コンポーネントをARMSに接続する方法の詳細については、「コンポーネントの管理」をご参照ください。(自己管理型Prometheusインスタンスを統合してASMインスタンスのメトリックを収集している場合は、追加の操作は必要ありません。詳細については、「自己管理型Prometheusインスタンスを使用したASMインスタンスの監視」をご参照ください。)
グローバルスロットリングのアラートルールを作成します。詳細については、「カスタムPromQLステートメントを使用したアラートルールの作成」をご参照ください。次の表に、アラートルールを設定するための主要なパラメーターの指定方法を示します。その他のパラメーターの詳細については、上記のドキュメントをご参照ください。
パラメーター
例
説明
カスタム PromQL ステートメント
(sum by(namespace, service_istio_io_canonical_name) (increase(envoy_cluster_ratelimit_over_limit[1m]))) > 0
increaseステートメントを実行して、過去1分以内にスロットリングが実行されたリクエスト数をクエリできます。スロットリングされたリクエスト数は、スロットリングをトリガーしたサービスの名前空間と名前でグループ化されます。1分以内にスロットリングされたリクエスト数が 0 より大きい場合、アラートがトリガーされます。
アラートメッセージ
グローバルスロットリングが発生しました! 名前空間:{{$labels.namespace }}. スロットリングをトリガーしたサービス:{{$labels.service_istio_io_canonical_name}}. 現在の1分間にスロットリングされたリクエスト数 :{{ $value }}
この例の警告情報には、スロットリングをトリガーしたサービスの名前空間、サービスの名前、および過去1分間にサービスに送信されてスロットリングされたリクエスト数が表示されます。
参照
ASMGlobalRateLimiterフィールドの詳細については、「ASMGlobalRateLimiterフィールドの説明」をご参照ください。
Traffic Management Centerでローカルスロットリングを設定する方法の詳細については、「Traffic Management Centerでのローカルスロットリングの設定」をご参照ください。
イングレスゲートウェイでグローバルスロットリングを設定する方法の詳細については、「イングレスゲートウェイでのグローバルスロットリングの設定」をご参照ください。