サービスメッシュ(ASM)トラフィックスケジューリングスイートは、グローバルスロットリング、ユーザー固有のスロットリング、バーストトラフィックウィンドウの設定、指定されたサービスへのトラフィックのカスタム消費レートの設定など、高度なスロットリング機能を実装するための高度なスロットリングポリシーを提供します。このトピックでは、ASM トラフィックスケジューリングスイートによって提供される RateLimitingPolicy を使用して、ユーザー固有のスロットリングを実装する方法について説明します。
背景情報
ASM トラフィックスケジューリングスイートのスロットリングポリシーは、トークンバケットアルゴリズムを使用します。システムは一定のレートでトークンを生成し、バケットの容量に達するまでトークンバケットに追加します。サービス間のリクエストの送信には、トークンの消費が必要です。バケットに十分なトークンが存在する場合、リクエストは送信時にトークンを消費します。バケット内のトークンが不足している場合、リクエストはキューに入れられるか、破棄される可能性があります。トークンバケットアルゴリズムは、データ送信の平均レートがトークン生成のレートを超えないようにすると同時に、ある程度のバーストトラフィックを処理します。
前提条件
バージョン 1.21.6.83 以降の ASM インスタンスに、コンテナサービス Kubernetes 版(ACK)マネージドクラスターが追加されています。詳細については、「ASM インスタンスへのクラスターの追加」をご参照ください。
kubectl を使用して ACK クラスターに接続しています。詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。
ASM トラフィックスケジューリングスイートが有効になっています。詳細については、「ASM トラフィックスケジューリングスイートを有効にする」をご参照ください。
ACK クラスターのデフォルトの名前空間で、自動サイドカープロキシインジェクションが有効になっています。詳細については、「グローバル名前空間の管理」をご参照ください。
ingressgateway という名前のイングレスゲートウェイが作成され、ポート 80 が有効になっています。詳細については、「イングレスゲートウェイの作成」をご参照ください。
準備
サンプルの HTTPBin サービスと sleep サービスをデプロイし、sleep サービスが HTTPBin サービスにアクセスできるかどうかを確認します。
以下の内容を含む httpbin.yaml ファイルを作成します。
次のコマンドを実行して、HTTPBin サービスをデプロイします。
kubectl apply -f httpbin.yaml -n default以下の内容を含む sleep.yaml ファイルを作成します。
次のコマンドを実行して、sleep サービスをデプロイします。
kubectl apply -f sleep.yaml -n default次のコマンドを実行して、sleep ポッドにアクセスします。
kubectl exec -it deploy/sleep -- sh次のコマンドを実行して、HTTPBin サービスにリクエストを送信します。
curl -I http://httpbin:8000/headers期待される出力:
HTTP/1.1 200 OK server: envoy date: Tue, 26 Dec 2023 07:23:49 GMT content-type: application/json content-length: 353 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 1200 OK が返されます。これは、アクセスが成功したことを示します。
ステップ 1:RateLimitingPolicy を使用してスロットリングポリシーを作成する
kubectl を使用して ASM インスタンスに接続します。詳細については、「コントロールプレーンで kubectl を使用して Istio リソースにアクセスする」をご参照ください。
以下の内容を含む ratelimitingpolicy.yaml ファイルを作成します。
apiVersion: istio.alibabacloud.com/v1 kind: RateLimitingPolicy metadata: name: ratelimit namespace: istio-system spec: rate_limiter: bucket_capacity: 2 fill_amount: 2 parameters: interval: 30s limit_by_label_key: http.request.header.user_id selectors: - agent_group: default control_point: ingress service: httpbin.default.svc.cluster.local次の表に、いくつかのフィールドについて説明します。詳細については、「RateLimitingPolicy フィールドの説明」をご参照ください。
フィールド
説明
fill_amount
interval フィールドで指定された時間間隔内に追加されるトークンの数。この例では、値は 2 です。これは、interval フィールドで指定された各間隔の後、トークンバケットに 2 つのトークンが追加されることを示します。
interval
トークンバケットにトークンが追加される間隔。この例では、値は 30 秒です。これは、30 秒ごとにトークンバケットに 2 つのトークンが追加されることを示します。
bucket_capacity
トークンバケットの最大トークン数。リクエストレートがトークンバケットの補充レートよりも低い場合、トークンバケット内のトークン数は最大数
bucket_capacityに達するまで増加し続けます。bucket_capacityは、ある程度のバーストトラフィックを許可するために使用されます。この例では、値は 2 で、fill_amount フィールドの値と同じです。この場合、バーストトラフィックは許可されません。limit_by_label_key
スロットリングポリシーでリクエストをグループ化するために使用されるラベル。これらのラベルを指定すると、異なるラベルを持つリクエストは個別にスロットリングされ、個別のトークンバケットが使用されます。この例では、
http.request.header.user_idが使用されています。これは、user_idリクエストヘッダーを使用してリクエストがグループ化されることを示します。これは、ユーザー固有のスロットリングのシナリオをシミュレートします。この例では、異なるユーザーによって開始されたリクエストには、異なるused_idリクエストヘッダーがあると仮定しています。selectors
スロットリングポリシーが適用されるサービス。この例では、
service: httpbin.default.svc.cluster.localが使用されています。これは、httpbin.default.svc.cluster.localサービスでスロットリングが実行されることを示します。
次のコマンドを実行して、RateLimitingPolicy を使用してスロットリングポリシーを作成します。
kubectl apply -f ratelimitingpolicy.yaml
ステップ 2:ユーザー固有のスロットリングの結果を確認する
kubectl を使用して ACK クラスターに接続し、次のコマンドを実行して sleep サービスの bash を有効にします。
kubectl exec -it deploy/sleep -- sh次のコマンドを実行して、user1 として HTTPBin サービスの /headers パスに 2 回連続してアクセスします。
curl -H "user_id: user1" httpbin:8000/headers -v curl -H "user_id: user1" httpbin:8000/headers -v期待される出力:
< HTTP/1.1 429 Too Many Requests < retry-after: 14 < date: Mon, 17 Jun 2024 11:48:53 GMT < server: envoy < content-length: 0 < x-envoy-upstream-service-time: 1 < * Connection #0 to host httpbin left intact前のステップを実行してから 30 秒以内に、次のコマンドを実行して、user2 として HTTPBin サービスの /headers パスに 1 回アクセスします。
curl -H "user_id: user2" httpbin:8000/headers -v期待される出力:
< HTTP/1.1 200 OK < server: envoy < date: Mon, 17 Jun 2024 12:42:17 GMT < content-type: application/json < content-length: 378 < access-control-allow-origin: * < access-control-allow-credentials: true < x-envoy-upstream-service-time: 5 < { "headers": { "Accept": "*/*", "Host": "httpbin:8000", "User-Agent": "curl/8.1.2", "User-Id": "user2", "X-Envoy-Attempt-Count": "1", "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=ddab183a1502e5ededa933f83e90d3d5266e2ddf87555fb3da1ad40dde3c722e;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep" } } * Connection #0 to host httpbin left intact出力は、user2 が同じパスにアクセスしたときにスロットリングがトリガーされないことを示しています。これは、ユーザー固有のスロットリングが成功したことを示します。
関連情報
RateLimitingPolicy が Grafana で有効になっているかどうかを確認できます。Grafana の Prometheus インスタンスが ASM トラフィックスケジューリングスイート で構成されていることを確認する必要があります。
RateLimitingPolicy のダッシュボードを作成するには、次の内容を Grafana にインポートできます。
ダッシュボードは次のとおりです。
