トラフィックスパイク、過負荷、リソース枯渇、または悪意のある攻撃からサービスを保護するために、トラフィック管理センターでローカル速度制限を設定します。この機能は、トラフィックを制御可能な しきい値 内に維持し、サービスの可用性と安定したパフォーマンスを確保します。ローカル速度制限は Envoy プロキシによって実装され、トークンバケットアルゴリズムを使用してサービスへのリクエストレートを制御します。このアルゴリズムは、一定の間隔でバケットにトークンを追加します。各リクエストは 1 つのトークンを消費します。バケットのトークンがなくなると、新しいリクエストは一時的に拒否され、サービスが過負荷になるのを効果的に防ぎます。
前提条件
-
Service Mesh (ASM) インスタンスが作成されており、次の要件を満たしていること:
-
ASM Enterprise Edition (Professional または Ultimate) の場合、インスタンスのバージョンは 1.14.3 以降である必要があります。ASM インスタンスのアップグレード方法の詳細については、「ASM インスタンスのアップグレード」をご参照ください。
-
ASM Standard Edition の場合、インスタンスのバージョンは 1.9 以降である必要があります。ローカル速度制限の設定には、ネイティブ Istio メソッドのみを使用できます。ドキュメントは Istio のバージョンによって異なります。最新情報については、Istio ドキュメントの Envoy を使用したレート制限の有効化 をご参照ください。
-
-
Kubernetes クラスターの
default名前空間で、自動サイドカープロキシ注入が有効になっていること。詳細については、「自動サイドカープロキシ注入の有効化」をご参照ください。 -
httpbin および sleep サンプルサービスがデプロイされており、sleep サービスが httpbin サービスにアクセスできること。詳細については、「httpbin アプリケーションのデプロイ」をご参照ください。
シナリオ 1:サービスポートへの速度制限の適用
このシナリオでは、httpbin サービスのポート 8000 にローカル速度制限を適用する方法を説明します。設定が完了すると、このルールは特定のポートに送信されるすべてのリクエストに適用されます。
-
ローカル速度制限ルールを作成します。
-
ASM コンソールにログインします。左側のナビゲーションウィンドウで、 を選択します。
-
[メッシュ管理] ページで、対象の ASM インスタンス名をクリックします。左側のナビゲーションウィンドウで、 を選択します。表示されたページで [作成] をクリックします。
-
Create ページでパラメーターを設定し、OK をクリックします。
セクション
パラメーター
説明
Basic Information About Throttling
Namespace
ローカル速度制限の影響を受けるワークロードが存在する名前空間。この例では、[default] を選択します。
Name
ローカル速度制限設定のカスタム名。この例では、「httpbin」と入力します。
Type of Effective Workload
速度制限ルールが適用されるワークロードのタイプ。有効な値: [アプリケーションサービス] と [ゲートウェイ]。この例では、Applicable Application を選択します。
Relevant Workload
特定のワークロードを選択するためのラベルのキーと値のペアのセットを入力します。この例では、Label Name を [app] に、Label Value を [httpbin] に設定します。
List of Throttling Rules
Service Port
Kubernetes サービスで宣言されているポート番号です。このポートは HTTP ポートである必要があります。この例では、httpbin サービスの HTTP ポート 8000 を入力します。
Throttling Configuration
トークンバケットアルゴリズムのタイムウィンドウと、そのウィンドウ内で許可されるリクエストの最大数を指定します。タイムウィンドウ内に送信されたリクエスト数がこの制限を超えると、後続のリクエストは速度制限されます。この例では、次の設定を使用します:
-
Time Window for Throttling Detection を [60s] に設定します。
-
[ウィンドウ内で許可されるリクエスト数] を [10] に設定します。
この設定により、サービスのワークロードは、任意の 60 秒のウィンドウで最大 10 リクエストに制限されます。
次の YAML ファイルは、ローカル速度制限設定の例です。
-
-
-
ローカル速度制限ルールを検証します。
-
次のコマンドを実行して、sleep コンテナで bash セッションを開始します:
kubectl exec -it deploy/sleep -- sh -
次のコマンドを実行して、10 件のリクエストを送信します:
for i in $(seq 1 10); do curl -v http://httpbin:8000/headers; done -
次のコマンドを実行して、11 件目のリクエストを送信します:
curl -v http://httpbin:8000/headers期待される出力:
* Trying 172.16.245.130:8000... * Connected to httpbin (172.16.245.130) port 8000 > GET /headers HTTP/1.1 > Host: httpbin:8000 > User-Agent: curl/8.5.0 > Accept: */* > < HTTP/1.1 429 Too Many Requests < x-local-rate-limit: true < content-length: 18 < content-type: text/plain < date: Tue, 26 Dec 2023 08:02:58 GMT < server: envoy < x-envoy-upstream-service-time: 2出力には HTTP 429 状態コードが表示されます。これは、リクエストが速度制限されたことを示します。
-
シナリオ 2:リクエストパスへの速度制限の適用
このシナリオでは、httpbin サービスのポート 8000 の /headers パスに送信されるリクエストにローカル速度制限を適用する方法を説明します。設定が完了すると、このルールは特定のパスとポートに一致するリクエストにのみ適用されます。
-
ローカル速度制限ルールを作成します。
-
ASM コンソールにログインします。左側のナビゲーションウィンドウで、 を選択します。
-
[メッシュ管理] ページで、対象の ASM インスタンス名をクリックします。左側のナビゲーションウィンドウで、 を選択します。表示されたページで [作成] をクリックします。
-
Create ページでパラメーターを設定し、OK をクリックします。
セクション
パラメーター
説明
Basic Information About Throttling
Namespace
ローカル速度制限の影響を受けるワークロードが存在する名前空間です。この例では、default を選択します。
Name
ローカル速度制限設定のカスタム名です。この例では、httpbin と入力します。
Type of Effective Workload
速度制限ルールが適用されるワークロードのタイプです。有効な値は [アプリケーションサービス] と [ゲートウェイ] です。この例では、Applicable Application を選択します。
Relevant Workload
特定のワークロードを選択するために、ラベルのキーと値のペアのセットを入力します。この例では、Label Name を app に、Label Value を httpbin に設定します。
List of Throttling Rules
Service Port
サービスの Kubernetes サービスで宣言されているポート番号です。これは HTTP ポートである必要があります。この例では、httpbin サービスの HTTP ポートである 8000 を入力します。
Match Request Attributes
リクエストの照合条件を定義します。ルールは、これらの条件に一致するリクエストにのみ適用されます。この例では、次の設定を使用します。
-
Matched Attributes を Request Path に設定します。
-
Matching Method を Prefix Match に設定します。
-
Matched Content を
/headersに設定します。
Throttling Configuration
トークンバケットアルゴリズムのタイムウィンドウと、そのウィンドウ内で許可されるリクエストの最大数を指定します。タイムウィンドウ内に送信されたリクエスト数がこの制限を超えると、後続のリクエストはスロットリングされます。この例では、次の設定を使用します。
-
Time Window for Throttling Detection を 60s に設定します。
-
[ウィンドウ内で許可されるリクエスト数] を 10 に設定します。
この設定により、サービスのワークロードは、任意の 60 秒のウィンドウで最大 10 リクエストに制限されます。
-
-
-
ローカル速度制限ルールを検証します。
-
次のコマンドを実行して、sleep コンテナで bash セッションを開始します:
kubectl exec -it deploy/sleep -- sh -
次のコマンドを実行して、10 件のリクエストを送信します:
for i in $(seq 1 10); do curl -v http://httpbin:8000/headers; done -
次のコマンドを実行して、11 件目のリクエストを送信します:
curl -v http://httpbin:8000/headers期待される出力:
* Trying 172.16.245.130:8000... * Connected to httpbin (172.16.245.130) port 8000 > GET /headers HTTP/1.1 > Host: httpbin:8000 > User-Agent: curl/8.5.0 > Accept: */* > < HTTP/1.1 429 Too Many Requests < x-local-rate-limit: true < content-length: 18 < content-type: text/plain < date: Tue, 26 Dec 2023 08:02:58 GMT < server: envoy < x-envoy-upstream-service-time: 2出力には HTTP 429 状態コードが表示されます。これは、リクエストが速度制限されたことを示します。
-
次のコマンドを実行して、httpbin サービスの
/getパスにリクエストを送信します:curl -v http://httpbin:8000/get期待される出力:
* Trying 192.168.243.21:8000... * Connected to httpbin (192.168.243.21) port 8000 (#0) > GET /get HTTP/1.1 > Host: httpbin:8000 > User-Agent: curl/8.1.2 > Accept: */* > < HTTP/1.1 200 OK < server: envoy < date: Thu, 11 Jan 2024 03:46:11 GMT < content-type: application/json < content-length: 431 < access-control-allow-origin: * < access-control-allow-credentials: true < x-envoy-upstream-service-time: 1 < { "args": {}, "headers": { "Accept": "*/*", "Host": "httpbin:8000", "User-Agent": "curl/8.1.2", "X-Envoy-Attempt-Count": "1", "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=be10819991ba1a354a89e68b3bed1553c12a4fba8b65fbe0f16299d552680b29;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep" }, "origin": "127.0.0.6", "url": "http://httpbin:8000/get" }出力には 200 OK 状態コードが表示されます。これは、httpbin サービスの他のパスへのリクエストが速度制限ルールの影響を受けないことを確認します。
-
関連操作
ローカル速度制限メトリックの表示
ローカル速度制限機能は、次のメトリックを生成します:
|
メトリック |
説明 |
|
envoy_http_local_rate_limiter_http_local_rate_limit_enabled |
レート制限フィルターをトリガーしたリクエストの総数。 |
|
envoy_http_local_rate_limiter_http_local_rate_limit_ok |
トークンが利用可能だったために許可されたリクエストの総数。 |
|
envoy_http_local_rate_limiter_http_local_rate_limit_rate_limited |
トークンが利用できなかったために速度制限のフラグが立てられたリクエストの総数。これはリクエストが拒否されたことを意味するものではありません。 |
|
envoy_http_local_rate_limiter_http_local_rate_limit_enforced |
速度制限されたリクエスト (例えば、429 応答が返されたリクエスト) の総数。 |
サイドカープロキシの proxyStatsMatcher 設定を構成して、これらのメトリックをレポートします。その後、Prometheus を使用して収集および表示できます。
-
proxyStatsMatcherを使用して、サイドカープロキシが速度制限メトリックをレポートするように設定します。proxyStatsMatcherを設定する際、Regular Expression Match を選択し、.*http_local_rate_limit.*に設定します。または、Add Local Throttling Metrics をクリックします。詳細については、「proxyStatsMatcher」をご参照ください。 -
httpbin サービスを再デプロイします。詳細については、「ワークロードの再デプロイ」をご参照ください。
-
シナリオ 1 または シナリオ 2 で説明されているように、ローカル速度制限の設定を完了し、テストリクエストを送信します。
-
次のコマンドを実行して、httpbin サービスのローカル速度制限メトリックを表示します:
kubectl exec -it deploy/httpbin -c istio-proxy -- curl localhost:15020/stats/prometheus|grep http_local_rate_limit期待される出力:
envoy_http_local_rate_limiter_http_local_rate_limit_enabled{} 37 envoy_http_local_rate_limiter_http_local_rate_limit_enforced{} 17 envoy_http_local_rate_limiter_http_local_rate_limit_ok{} 20 envoy_http_local_rate_limiter_http_local_rate_limit_rate_limited{} 17
メトリック収集とアラートの設定
メトリックレポートを設定した後、Prometheus でメトリック収集を設定し、主要なメトリックに基づいてアラートルールを作成して、速度制限が発生したときにタイムリーに通知を受け取ることができます。次の例では、Managed Service for Prometheus を使用します。
-
Managed Service for Prometheus で、データプレーンクラスターに [Alibaba Cloud ASM] コンポーネントを追加するか、最新バージョンにアップグレードします。これにより、Managed Service for Prometheus が公開されたローカル速度制限メトリックをスクレイプできるようになります。詳細については、「統合管理」をご参照ください。サービスメッシュメトリックを収集するために自己管理型 Prometheus インスタンスをすでに統合している場合は、このステップを実行する必要はありません。詳細については、「メッシュモニタリングのための自己管理型 Prometheus インスタンスの統合」をご参照ください。
-
ローカル速度制限のアラートルールを作成します。詳細については、「カスタム PromQL クエリを使用した Prometheus アラートルールの作成」をご参照ください。次の表は、主要なパラメーターの設定例を示しています。他のパラメーターは、要件に基づいて設定できます。
パラメーター
例
説明
カスタム PromQL クエリ
(sum by(namespace, pod_name) (increase(envoy_http_local_rate_limiter_http_local_rate_limit_enforced[1m]))) > 0
この PromQL クエリは、
increase関数を使用して、Pod の名前空間と名前でグループ化された、過去 1 分間の速度制限されたリクエスト数を検索します。1 分間の速度制限されたリクエスト数が 0 より大きい場合にアラートがトリガーされます。アラートメッセージ
ローカル速度制限が発生しました! 名前空間: {{$labels.namespace}}、Pod: {{$labels.pod_name}}。過去 1 分間の速度制限されたリクエスト数: {{ $value }}
アラート通知の内容。このメッセージ例には、アラートをトリガーした Pod の名前空間と名前、および過去 1 分間に速度制限されたリクエスト数が含まれています。
よくある質問
速度制限ルールが機能しないのはなぜですか?
不正なサービスプロトコル
ローカル速度制限は、HTTP プロトコルのみをサポートします。速度制限ルールを設定する前に、サービスが HTTP または gRPC や Dubbo3 などの HTTP 上に構築されたアプリケーション層プロトコルを介して通信することを確認してください。
さらに、サービスメッシュがプロトコルを正確に識別できるように、サービスのプロトコルを正しく定義する必要があります。詳細については、「サービスのプロトコルタイプを正しく定義する方法」をご参照ください。
インバウンドトラフィックに対する Sidecar CRD の影響
デフォルトでは、サービスメッシュは Service 定義のポート宣言に基づいて、サイドカープロキシのインバウンドトラフィックリスナーを自動的に設定します。ローカル速度制限とグローバルレート制限は、どちらもこのデフォルトの動作に依存します。
localhost でリッスンしているアプリケーションに他の Pod がアクセスできるようにするなど、サービスのデフォルトのインバウンドトラフィック構成を変更するために、Sidecar カスタムリソース定義 (CRD) を使用する場合があります。詳細については、「localhost アプリケーションを他の Pod に公開する方法」をご参照ください。
この場合、デフォルトのリスナーが変更されているため、ローカル速度制限ルールで Kubernetes Service ポートを指定しても機能しません。代わりに、ローカル速度制限ルールの [サービスポート] を、Sidecar CRD で指定された実際のインバウンドポートに設定する必要があります。
たとえば、ポート 8000 にローカル速度制限を適用しようとしているときに、httpbin サービスに対して次の Sidecar CRD を設定した場合:
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: localhost-access
namespace: default
spec:
ingress:
- defaultEndpoint: '127.0.0.1:80'
port:
name: http
number: 80
protocol: HTTP
workloadSelector:
labels:
app: httpbin
ローカル速度制限ルールを作成するときは、[サービスポート] を 8000 ではなく 80 に設定する必要があります。
関連ドキュメント
-
ご利用の ASM インスタンスのバージョンが 1.19.0 以降の場合、
ASMLocalRateLimiterYAML のlimit_overridesフィールドを使用して、クエリパラメーターなどの他の属性に基づいてリクエストを照合できます。詳細については、「ASMLocalRateLimiter CRD リファレンス」をご参照ください。 -
ASMGlobalRateLimiterCRD を使用して、イングレスゲートウェイとアプリケーションサービストラフィックのグローバルレート制限を設定します。詳細については、「ASMGlobalRateLimiter を使用したアプリケーションサービスのグローバルレート制限の設定」をご参照ください。 -
ASM コンソールでイングレスゲートウェイのローカル速度制限またはグローバルレート制限を設定します。詳細については、「イングレスゲートウェイのローカル速度制限の設定」および「イングレスゲートウェイのグローバルレート制限の設定」をご参照ください。
-
ウォームアップ機能を使用して、指定した期間にわたってリクエストボリュームを徐々に増やします。これにより、リクエストタイムアウトやデータ損失などの問題を防ぐことができます。詳細については、「ASM ウォームアップ機能の使用」をご参照ください。
-
接続プールを設定してサーキットブレーカーを実装し、障害や過負荷時にシステムをさらなる損傷から保護します。詳細については、「接続プールを設定してサーキットブレーカーを実装する」をご参照ください。