BLOG | NGINX

レート制限をNGINXサービスメッシュで実現する方法

NGINX-Part-of-F5-horiz-black-type-RGB
Saylor Berman サムネール
Saylor Berman
Published May 12, 2021

悪意のあるリクエスト(ブルートフォースパスワード推測やDDoS攻撃)であるか、正常なリクエストであるか(セールに集まる大量の顧客)に関係なく、大量のHTTPリクエストは、サービスに負荷をかけ、アプリケーションを停止させる可能性があります。この問題を簡単に解決する方法が、レート制限であり、一定時間内に各ユーザーが行えるリクエストの数を制限することなのです。しかし、Kubernetes環境では、サービスに到達する総トラフィック量のかなりの部分が、他のサービスとの通信という形で、Ingressコントローラーの管理対象とするスコープの外になっている可能性があります。このような状況では、サービスメッシュを使用してレート制限ポリシーを設定することが理にかなっていることが多いのです。

NGINXサービスメッシュでレート制限を設定するのは簡単で、10分もかからずに完了することができます。このデモをご覧になり、レート制限ポリシーを定義して適用する方法をご確認ください。

デモ:NGINXサービスメッシュによるレート制限の設定

このデモでは、NGINXサービスメッシュサイドカーを注入した3つのコンテナを利用します。バックエンドサービス、フロントエンドサービス、そしてbashターミナルの3つです。

NGINXサービスメッシュコントロールプレーンもデプロイされています。フロントエンドサービスはバックエンドサービスに1秒ごとにリクエストを送信し、そのレスポンスをフロントエンドサービスのログで確認することができます。

backend v1backend v1backend v1backend v1

レート制限ポリシーの適用(1:00)

バックエンドサービスにあまり多くのリクエストを転送したくない場合を考えてみましょう。 以下のフィールドを持つカスタムリソースとして、レート制限ポリシーを定義することができます。

  • destination – リクエストを受け取るサービスです。ここではバックエンドのサービスです。
  • sources – リクエストが来るクライアントのリストで、それぞれレート制限の対象となります。ここでは、1つのソース、フロントエンドサービスだけを定義しています。
  • rate – レート制限です。ここでは、1 分あたり 10 リクエスト、あるいは 6 秒に 1 リクエストの割合になっています。
apiVersion: specs.smi.nginx.com/v1alpha1kind: RateLimitmetadata:  name: backend-rate-limit  namespace: defaultspec:  destination:    kind: Service    name: backend-svc    namespace: default  sources:  - kind: Deployment    name: frontend    namespace: default  name: 10rm  rate: 10r/m  burst: 0  delay: nodelay

以下のコマンドを実行して、ポリシーを有効にします。

$ kubectl create -f rate-limit.yaml

フロントエンドのログを見ると、6つのリクエストのうち5つが以下のメッセージとともに拒否されていることがわかります。

<html><head><title>503 Service Temporarily Unavailable</title</head><body><center><h1>503 Service Temporarily Unavailable</h1></center><hr><center>nginx/1.19.5</center></body></html>

すべてのクライアントにレート制限を適用する (2:32)

レート制限は、sourcesフィールドに指定されたクライアント(デモ環境ではフロントエンドサービス)にのみ適用されます。バックエンドサービスは、他のすべてのクライアントからのリクエストを、 リクエストの転送レートに関わらず受け付け、各リクエストは成功を示すbackend v1 レスポンスを受け取ります。

すべてのクライアントにレート制限を適用するには、2つの方法があります。1つ目は、sourcesフィールドに対象の名前を追加する方法です。2つ目は、よりシンプルな方法で、sourcesフィールドを完全に削除することです。以下コマンドを実行して、ポリシーを編集します。

$ kubectl edit ratelimits.specs.smi.nginx.com backend-rate-limit

編集したポリシーを保存した後、再びbashターミナルでリクエストしてみると、レート制限を超えたソースからのリクエストは、上記のようなフォーマットされた503エラーで拒否されることがわかります。

リクエストのバーストを許可する (3:43)

レート制限をカスタマイズするために、その他のいくつかのフィールドがポリシーには存在します。アプリケーションの中には、「バースト的」に連続した複数のリクエストを送信するものがあることが分かっています。これに対応するために、burstフィールドを指定することが可能です。ここでは 3 に設定しています。つまり、バックエンドサービスは 6 秒ごとにその数の追加リクエストを受け付けます。それ以上のリクエストは拒否されます。

delayフィールドは、リクエストが許容するバーストがバックエンドサービスにどのように転送されるかを制御します。これがなければ (つまりデフォルトでは)、バーストリクエストはキューに入れられ、指定したレート制限に従って、リクエストごとの間隔を保ち、新しいリクエストとともに転送されます。バーストしたリクエストをすぐに送るために、delayフィールドを値 nodelayに設定することができます。

また、delayフィールドを整数に設定することもできます。例えば、これを 3 に設定し、burstフィールドを 5 に増やすと、6 秒周期で 5 つ以上のバーストリクエストが到着すると、3 つは直ちに送信され、2 つはキューに入れられ、残りは拒否されます。

burst: 3delay: nodelay と設定した場合の効果をログで観察することができます。リクエストが拒否される前に、3つの余分なリクエストが受け入れられるのがわかります。

backend v1backend v1backend v1backend v1<html><head><title>503 Service Temporarily Unavailable</title</head><body><center><h1>503 Service Temporarily Unavailable</h1></center><hr><center>nginx/1.19.5</center></body></html>. . .

レート制限の解除 (6:30)

このデモの最後のアクションは、レート制限ポリシーを解除し、すべてのリクエストを受け入れます。そのために、以下のコマンドを実行します。

$ kubectl delete -f rate-limit.yml

NGINXサービスメッシュによるレート制限を試してみる

burstとdelayのパラメータの詳細については、reference documentationを参照してください。その他のトラフィックマネジメントパターンについては、ブログ「高度なトラフィック管理で実現する強靭なKubernetesプラットフォーム」をご覧ください。

また、NGINXサービスメッシュの機能を紹介するビデオデモもご覧ください。

NGINXサービスメッシュは完全に無料で、すぐにダウンロードでき、10分以内にデプロイすることができます! まずはドキュメントを確認し、GitHubで使い方のフィードバックをください。


"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."