トラフィックスパイク、サービスの過負荷、リソースの枯渇、または悪意のあるリクエストによって可用性が脅かされる場合、ローカルレート制限は各サイドカープロキシでリクエスト量を制限し、個々のサービスインスタンスを保護します。
各サイドカープロキシは、トークンバケットアルゴリズムを使用して、独立してレート制限を適用します。トークンは固定間隔でバケットに追加され、各インバウンドリクエストは 1 つのトークンを消費します。トークンがなくなると、プロキシは新しいリクエストを HTTP 429 (Too Many Requests) で拒否します。
前提条件
次のバージョン要件を満たす Service Mesh (ASM) インスタンス:
Enterprise Edition または Ultimate Edition:バージョン 1.14.3 以降。アップグレードするには、「ASM インスタンスのアップグレード」をご参照ください。
Standard Edition:バージョン 1.9 以降。Standard Edition は、ネイティブ Istio レート制限のみをサポートします。参照ドキュメントは Istio のバージョンによって異なります。最新バージョンについては、Istio ドキュメントの「Enabling rate limits using Envoy」をご参照ください。
ご利用の Container Service for Kubernetes (ACK) クラスターの
default名前空間で、サイドカープロキシの自動インジェクションが有効になっていること。詳細については、「グローバル名前空間の管理」の「サイドカープロキシの自動インジェクションを有効にする」セクションをご参照ください。HTTPBin および sleep サンプルサービスがデプロイされており、sleep サービスが HTTPBin サービスに到達できること。デプロイメントの手順については、「HTTPBin アプリケーションのデプロイ」をご参照ください。
シナリオ 1:サービスポートによるレート制限
リクエストパスに関係なく、HTTPBin サービスのポート 8000 でのすべてのリクエストにレート制限を適用します。
ステップ 1:ローカルレート制限ルールの作成
ASM コンソールにログインします。左側のナビゲーションウィンドウで、[Service Mesh] > [メッシュ管理] を選択します。
[メッシュ管理] ページで、対象の ASM インスタンス名をクリックします。左側のナビゲーションウィンドウで、[トラフィック管理センター] > [レート制限] を選択します。
[作成] をクリックし、次のパラメーターを設定します:
セクション パラメーター 値 スロットリングの基本情報 名前空間 default を選択します。 名前 httpbin と入力します。 有効なワークロードのタイプ 適用可能なアプリケーションを選択します。 関連ワークロード [キー] を app に、[値] を httpbin に設定します。 スロットリングルールリスト サービスポート 8000 (HTTPBin Kubernetes Service で宣言された HTTP ポート) を入力します。 スロットリング設定 [スロットリング検出の時間枠] を 60 秒に、[時間枠内で許可されるリクエスト数] を 10 に設定します。 [OK] をクリックします。

ステップ 2:レート制限の検証
sleep Pod でシェルを開きます:
kubectl exec -it deploy/sleep -- sh10 件のリクエストを送信して、トークンバケットを使い切ります:
for i in $(seq 1 10); do curl -v http://httpbin:8000/headers; doneもう 1 件リクエストを送信します:
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: 2429 Too Many Requests応答とx-local-rate-limit: trueヘッダーは、ローカルレート制限がアクティブであることを示します。
シナリオ 2:ポートとリクエストパスによるレート制限
ポート 8000 で、/headers パスを対象とするリクエストにのみレート制限を適用します。/get などの他のパスへのリクエストは、レート制限なしで通過します。
ステップ 1:ローカルレート制限ルールの作成
ASM コンソールにログインします。左側のナビゲーションウィンドウで、[Service Mesh] > [メッシュ管理] を選択します。
[メッシュ管理] ページで、対象の ASM インスタンス名をクリックします。左側のナビゲーションウィンドウで、[トラフィック管理センター] > [レート制限] を選択します。
[作成] をクリックし、次のパラメーターを設定します:
セクション パラメーター 値 スロットリングの基本情報 名前空間 default を選択します。 名前 httpbin と入力します。 有効なワークロードのタイプ 適用可能なアプリケーションを選択します。 関連ワークロード [キー] を app に、[値] を httpbin に設定します。 スロットリングルールリスト サービスポート 8000 と入力します。 リクエスト属性を照合 [照合属性] を [リクエストパス] に、[照合方法] を [プレフィックス一致] に、[照合コンテンツ] を /headersに設定します。スロットリング設定 [スロットリング検出の時間枠] を 60 秒に、[時間枠内で許可されるリクエスト数] を 10 に設定します。 [OK] をクリックします。

ステップ 2:レート制限の検証
sleep Pod でシェルを開きます:
kubectl exec -it deploy/sleep -- sh/headersパスに 10 件のリクエストを送信して、トークンバケットを使い切ります:for i in $(seq 1 10); do curl -v http://httpbin:8000/headers; done/headersにもう 1 件リクエストを送信します: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: 2429応答は、/headersへのリクエストがレート制限されていることを示します。影響を受けないことを確認するために、別のパスにリクエストを送信します:
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応答は、他のパスへのリクエストがレート制限ルールの対象外であることを示します。
レート制限メトリクスの収集とクエリ
ローカルレート制限は、次の Envoy メトリクスを生成します:
| メトリック | 説明 |
|---|---|
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 | 実際に拒否されたリクエスト数 (HTTP 429 が返された) |
サイドカープロキシからレート制限メトリクスを公開するには:
proxyStatsMatcherを設定して、サイドカープロキシがレート制限メトリクスを報告できるようにします。[正規表現一致] を選択し、.*http_local_rate_limit.*と入力します。または、[ローカルスロットリングメトリクスを追加] をクリックします。詳細については、「サイドカープロキシの設定」の「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 アラートの設定
メトリクスを有効にした後、Prometheus がそれらを収集するように設定し、レート制限イベントのアラートルールを作成します。次の例では、Managed Service for Prometheus を使用します。
Managed Service for Prometheus で、データプレーンの ACK クラスターを [Alibaba Cloud ASM] コンポーネントに接続するか、コンポーネントを最新バージョンにアップグレードします。これにより、レート制限メトリクスが Managed Service for Prometheus によって収集されるようになります。統合の詳細については、「コンポーネント管理」をご参照ください。
説明すでにセルフマネージド Prometheus インスタンスを使用して ASM メトリクスを収集している場合 (「セルフマネージド Prometheus インスタンスを使用した ASM インスタンスのモニタリング」をご参照ください)、このステップはスキップしてください。
レート制限イベントのアラートルールを作成します。完全な設定手順については、「カスタム PromQL 文を使用したアラートルールの作成」をご参照ください。次の表に、主要なパラメーターの例を示します:
パラメーター 例 説明 カスタム PromQL 文 (sum by(namespace, pod_name) (increase(envoy_http_local_rate_limiter_http_local_rate_limit_enforced[1m]))) > 0過去 1 分間の Pod ごとのレート制限されたリクエスト数をカウントします。カウントが 0 を超えるとアラートが発動します。 アラートメッセージ Local throttling occurs! Namespace: {{$labels.namespace}}, Pod that triggers throttling: {{$labels.pod_name}}. Number of requests that are throttled in the current 1 minute: {{ $value }}名前空間、Pod 名、およびスロットリングされたリクエスト数が含まれます。
よくある質問
ローカルレート制限ルールが有効にならないのはなぜですか?
サービスが HTTP を使用していない:ローカルレート制限は、HTTP および HTTP ベースのプロトコル (gRPC、dubbo3) でのみ機能します。ご利用のサービスがサポートされているプロトコルを使用しており、そのプロトコルが Kubernetes Service の定義で正しく宣言されていることを確認してください。ガイダンスについては、「標準的な方法でサービスのプロトコルを指定するにはどうすればよいですか?」をご参照ください。
Sidecar CRD がインバウンドトラフィック設定をオーバーライドしている:ASM は、サービス宣言に基づいてサイドカープロキシのインバウンドトラフィックリスナーを自動的に設定します。ローカルレート制限ルールは、このデフォルト設定に依存します。
Sidecar CRD を使用してデフォルトのインバウンドトラフィック設定を変更した場合 (たとえば、「localhost アプリケーションを他の Pod に公開する」ため)、インバウンドポートがサービスポートと異なる場合があります。この場合、レート制限ルールを元のサービスポートではなく、Sidecar CRD で定義されたポートを使用するように設定してください。
たとえば、次の Sidecar CRD がインバウンドトラフィックをポート 80 にマッピングしている場合:
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 以降) には、「ASMLocalRateLimiter フィールドの説明」をご参照ください。
すべてのインスタンスにわたってサービス全体のレート制限を適用するには、「ASMGlobalRateLimiter を使用したインバウンドトラフィックのグローバルスロットリングの設定」をご参照ください。
サイドカープロキシではなくイングレスゲートウェイでレート制限を設定するには、「イングレスゲートウェイでのローカルスロットリングの設定」または「イングレスゲートウェイでのグローバルスロットリングの設定」をご参照ください。
デプロイ後にサービスへのトラフィックを徐々に増やすには、「ウォームアップ機能の使用」をご参照ください。
カスケード障害からサービスを保護するには、「connectionPool フィールドを設定したサーキットブレーカーの実装」をご参照ください。