Inteyとistioでセットアップ料金制限装置をセットしてください
イメージからhttps://istio.io/latest/docs/concepts/what-is-istio/
上記のイメージでわかるように、サービスメッシュデータプレーンはあなたのサービスの前に座っている使者プロキシから成ります.IngressGatewayまたはEGressWidthは、ちょうど端の使節代理人です.メッシュ内のすべてのトラフィックは、これらのプロキシを通過するので、お客様のネットワークトラフィックの観測能力だけでなく、お客様のニーズにプロキシを設定することによって制御を得る.サービスメッシュの可能性をよりよく理解するためには、使節代理人自身をより深く調べる必要があります.
使節は何ですか。
にenvoy docs 以下を読みます.
Envoy is an L7 proxy and communication bus designed for large modern service oriented architectures. The project was born out of the belief that:
"The network should be transparent to applications. When network and application problems do occur it should be easy to determine the source of the problem."
使節はあなたのポッドのサイドカーとして実行されるので、別のサービス自体に触れることなく、その場でプロキシの設定を更新することができます.
すべてのプロキシは、フィルタチェーンに組み込まれています.このチェーンでは、トラフィック管理capabilitesを提供するプラグイン可能なフィルタがあります.フィルタは、バッファリングのような異なるタスクを実行します.あなたのWebサーバーのミドルウェアのようなフィルタチェーンを考えることができます.
混乱を避けるためにはenvoy terminology .
私たちはこの記事の最も重要な用語を使節ドキュメントから引用しました.
Host: An entity capable of network communication (application on a mobile phone, server, etc.). In this documentation a host is a logical network application. A physical piece of hardware could possibly have multiple hosts running on it as long as each of them can be independently addressed.
Downstream: A downstream host connects to Envoy, sends requests, and receives responses.
Upstream: An upstream host receives connections and requests from Envoy and returns responses.
Listener: A listener is a named network location (e.g., port, unix domain socket, etc.) that can be connected to by downstream clients. Envoy exposes one or more listeners that downstream hosts connect to.
Cluster: A cluster is a group of logically similar upstream hosts that Envoy connects to. Envoy discovers the members of a cluster via service discovery. It optionally determines the health of cluster members via active health checking. The cluster member that Envoy routes a request to is determined by the load balancing policy.
今、私たちはistioデータ面を垣間見ることができます.その問題を解決しましょう.
料金制限サービス
使節local (non-distributed) とグローバルなレート制限機能.この記事はglobal rate limiting architecture .
グローバルレート制限を使用するには、レート制限する必要があるドメインを追跡する外部レートリミッターサービスが必要です.幸いにも使者はレッドベースを提供ratelimit service . 次の節では、REDISベースのRatelimitサービスの設定方法と、制限された特定のルートの制限方法を学びます.
画像描画を作成します.ナタリアSattlerとMoritzリーガーによるIo
RatLimitサービスを配備する
RatLimitサービスの展開についてはratelimitservice.yaml 出発点として.あなたが既にあなたのKubernetesクラスタでRedisインスタンスを持っているならば、レートリミッターサービスのためにそれを使うのを自由に感じて、Redis関連部分を削除してください.
コンフィギュレーションの調整
ratelimit-config
あなたのレート制限ルールとREDIS_URL
にratelimit
展開.これで、KatbernetesクラスタにRatLimitサービスを配備できます.制限ルール
RatLimitサービスをチェックしてくださいdocumentation レート制限規則を設定する方法の詳細については.今のところ、以下の例の設定を使用して、お客様のニーズに合わせて調整できます.
設定例
apiVersion: v1
kind: ConfigMap
metadata:
name: ratelimit-config
data:
config.yaml: |
domain: foo-domain
descriptors:
- key: BAR
value: "/foo"
rate_limit:
unit: minute
requests_per_unit: 1
- key: BAR
rate_limit:
unit: minute
requests_per_unit: 100
レート制限ドキュメントからDomain: A domain is a container for a set of rate limits. All domains known to the Ratelimit service must be globally unique.
Descriptor: A descriptor is a list of key/value pairs owned by a domain that the Ratelimit service uses to select the correct rate limit to use when limiting.
使用例では
foo-domain
レート制限規則をグループ化するには、次の手順に従います.BAR
と値/foo
分あたり1リクエストのレート制限がありますBAR
分あたり100リクエストのレート制限があります.("BAR","/foo")
, Rateリミッタのルール番号1を使用します("BAR","/foobar")
, 番目のルールはキック.特別扱いはないからです/foobar
値.別のリクエストなら("BAR","/test")
で、ルール番号2は、同様に使用されます.ただし、レート制限は("BAR","/foobar")
. 各要求は、毎分100回照会することができます.レート制限サービスが何かで呼び出された場合、暗黙のルール番号("FOO","/foo")
. 指定されていないキーでは、ラセミネーションは全く適用されません.言及する1つの重要な点は、それがURIの一部のように見えるけれども、ディスクリプタの値が要求されたURIを示す必要はないということです.それは単にディスクリプタの値で、何でもありえます.この例では、私たちが後で設定する使節フィルタのため、このように指定されます.
レートリミッタの構成が行われ、サービスがKubernetesクラスタに反映されると、すべての着信要求がこのサービスによって守られるようになります.
遣唐使のサービスを紹介する
最初に、Ratelimitサービスを使節クラスタとして登録してください.これは、クラスタレベルで適用される使節フィルターパッチを介して行われます.CONFIG PATHは、あなたの選択の名前とRate Rimuler Service(線11 - 36)の対応する終点を持つ新しい特使クラスタを指定します.
そして、フィルタがどこでレート制限質問を送るかについてわかっているように、このクラスタはそれからratelimit HTTPフィルタから参照されることができます.
これは正確に2番目のパスが何であるかです.レート制限HTTPフィルタをイングルゲートゲートウェイのフィルタチェーンに挿入します.ライン55 - 62で、我々はフィルタ定義で以前につくられたクラスタとレートリミッター・ドメインに言及します.
例
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: filter-ratelimit
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: CLUSTER
match:
proxy:
proxyVersion: ^1\.15.*
cluster:
# kubernetes dns of your ratelimit service
service: ratelimit.default.svc.cluster.local
patch:
operation: ADD
value:
name: rate_limit_cluster
type: STRICT_DNS
connect_timeout: 10s
lb_policy: ROUND_ROBIN
http2_protocol_options: {}
load_assignment:
# arbitrary name
cluster_name: rate_limit_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
# kubernetes dns of your ratelimit service
address: ratelimit.default.svc.cluster.local
port_value: 8081
- applyTo: HTTP_FILTER
match:
context: GATEWAY
proxy:
proxyVersion: ^1\.15.*
listener:
filterChain:
filter:
name: 'envoy.http_connection_manager'
subFilter:
name: 'envoy.router'
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.ratelimit
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
# arbirary domain, ensure it matches with the domain used in the ratelimit service config
domain: foo-domain
failure_mode_deny: true
rate_limit_service:
grpc_service:
envoy_grpc:
# must match load_assignment.cluster_name from the patch to the CLUSTER above
cluster_name: rate_limit_cluster
timeout: 10s
transport_api_version: V3
入口ゲートウェイにおけるレート制限フィルタの使用
ここまでレート制限フィルタとクラスタを設定しました.今では着信レートのリクエストを制限するために我々のイングルのゲートウェイでこのフィルタを使用する時間です.
私たちは、レート制限フィルタをEngressゲートウェイVirtual Host Filter Chainに付けて、レートリミッタサービス質問で使用される記述子を指定します.
例
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: filter-ratelimit-svc
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: VIRTUAL_HOST
match:
proxy:
proxyVersion: ^1\.15.*
context: GATEWAY
routeConfiguration:
# Should be in the namespace/name format. Use this field in conjunction with the portNumber and portName to accurately select the Envoy route configuration for a specific HTTPS server within a gateway config object.
gateway: istio-system/istio-gateway
portNumber: 443
portName: https
patch:
operation: MERGE
value:
rate_limits:
- actions:
# This action results in the following descriptor ("BAR","/foo") where "/foo" is the requested path.
# :path is resolved to the actual requested path at runtime and used as the descriptor value
- request_headers:
header_name: ':path'
descriptor_key: 'BAR'
テスト特使の設定
イングルゲートウェイに2回連続して次のリクエストを発行するだけでYOR設定をテストします
curl -i https://<your host>/foo
. 第2の要求は429のHTTPエラーをもたらすでしょう.そうでなければ、設定をトラブルシューティングします.
レートリミッタクラスタが登録されているかチェックする
あなたのレートリミッタークラスタが適切に登録されていることを確認します
istioctl proxy-config cluster <your-istio-ingressgateway-pod>.istio-system -o json
このコマンドは[
{
"name": "rate_limit_cluster",
"type": "STRICT_DNS",
"connectTimeout": "10s",
"loadAssignment": {
"clusterName": "rate_limit_cluster",
"endpoints": [
{
"lbEndpoints": [
{
"endpoint": {
"address": {
"socketAddress": {
"address": "ratelimit.default.svc.cluster.local",
"portValue": 8081
}
}
}
}
]
}
]
},
"http2ProtocolOptions": {}
},
...
]
そうでなければ、istioctl proxy-status
クラスタの状態をチェックするコマンドです.istioctl proxy-status <your-istio-ingressgateway-pod>.istio-system
レートリミッタフィルタがHTTPフィルタチェーンに接続されているかどうかを確認する
レートリミッタフィルタがHTTPフィルタチェーンに接続されていることを確認する
istioctl proxy-config listener <your-istio-ingressgateway-pod>.istio-system -o json
このコマンドは[
{
"name": "0.0.0.0_8443",
"address": {
"socketAddress": {
"address": "0.0.0.0",
"portValue": 8443
}
},
"filterChains": [
{
"filterChainMatch": {
"serverNames": [
"www.example.com"
]
},
"filters": [
{
"name": "envoy.filters.network.http_connection_manager",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
"statPrefix": "outbound_0.0.0.0_8443",
"rds": {
"configSource": {
"ads": {},
"resourceApiVersion": "V3"
},
"routeConfigName": "https.443.https.istio-gateway.istio-system"
},
"httpFilters": [
...
{
"name": "envoy.filters.http.ratelimit",
"typedConfig": {
"@type": "type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit",
"domain": "foo-domain",
"failureModeDeny": true,
"rateLimitService": {
"grpcService": {
"envoyGrpc": {
"clusterName": "rate_limit_cluster"
},
"timeout": "10s"
},
"transportApiVersion": "V3"
}
}
},
...
そうでなければ、上記と同じコマンドで問題をチェックしてください.(3)レートリミッタのアクション設定がイングルゲートゲートウェイ仮想ホスト構成に適用されているかどうかを確認します
ルート設定を次のコマンドで確認します
istioctl proxy-config route <your-istio-ingressgateway-pod>.istio-system -o json
このコマンドは
[
{
"name": "https.443.https.istio-gateway.istio-system",
"virtualHosts": [
{
"name": "www.example.com:443",
"domains": [
"www.example.com",
"www.example.com:*"
],
"routes": [...],
"rateLimits": [
{
"actions": [
{
"requestHeaders": {
"headerName": ":path",
"descriptorKey": "PATH"
}
}
]
}
],
...
そうでなければ、上記と同じコマンドで問題をチェックしてください.落とし穴に気づいてください!
クエリパラメータはパスを一意にする
あなたが上記からすべての構成を適用したあと、ratelimitingが働くと確認しました.リクエストに適用される規則を制限するのと同じレートを得ることを期待しているかもしれません
https://<your host>/foo?param=value
に関してhttps://<your host>/foo
. しかし、これはそうではありません.適用ルールは2番目の(100 req/min)である.ギフィーからのイメージ.コム
これはpseudo-header field
:path
, ディスクリプタ値に使用されるターゲットは、ターゲットURIのパスとすべての問い合わせ部分を含んでいる.その部分のRatelimiterサービスはディスクリプタの特別な設定を検出しない("BAR", "/foo?param=value")
とキーのデフォルトを使用します"BAR"
.検索Paramsをレートリミッタで予想通りに動作させるには、値を切り取る必要があります.これは別のフィルタで行うことができますenvoy.filters.http.header_to_metadata .
このフィルタを使用するには、フィルタ定義を変更する必要があります.
フィルタラ
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: filter-ratelimit
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: CLUSTER
match:
proxy:
proxyVersion: ^1\.15.*
cluster:
# kubernetes dns of your ratelimit service
service: ratelimit.default.svc.cluster.local
patch:
operation: ADD
value:
name: rate_limit_cluster
type: STRICT_DNS
connect_timeout: 10s
lb_policy: ROUND_ROBIN
http2_protocol_options: {}
load_assignment:
# arbitrary name
cluster_name: rate_limit_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
# kubernetes dns of your ratelimit service
address: ratelimit.default.svc.cluster.local
port_value: 8081
- applyTo: HTTP_FILTER
match:
proxy:
proxyVersion: ^1\.15.*
context: GATEWAY
listener:
filterChain:
filter:
name: 'envoy.http_connection_manager'
subFilter:
name: 'envoy.router'
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.header_to_metadata
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config
request_rules:
- header: ':path'
on_header_present:
# use an arbitary name for the namespace
# will be used later to extract descriptor value
metadata_namespace: example
# use an arbitary key for the metadata
# will be used later to extract descriptor value
key: uri
regex_value_rewrite:
pattern:
# regex matcher
google_re2: {}
# truncates parameters from path
regex: '^(\/[\/\d\w-]+)\??.*$'
substitution: '\1'
- applyTo: HTTP_FILTER
match:
proxy:
proxyVersion: ^1\.15.*
context: GATEWAY
listener:
filterChain:
filter:
name: 'envoy.http_connection_manager'
subFilter:
name: 'envoy.filters.http.header_to_metadata'
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.ratelimit
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
# ensure the domain matches with the domain used in the ratelimit service config
domain: foo-domain
failure_mode_deny: true
rate_limit_service:
grpc_service:
envoy_grpc:
# must match load_assignment.cluster_name from the patch to the CLUSTER above
cluster_name: rate_limit_cluster
timeout: 10s
transport_api_version: V3
これは、レートリミッタフィルタの直前に登録され、:path
ヘッダーとメタデータに追加します.ディスクリプタ値更新のメタデータを使用するには、次の特使フィルタ定義を更新します.フィルタラティス
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: filter-ratelimit-svc
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: VIRTUAL_HOST
match:
context: GATEWAY
routeConfiguration:
# Should be in the namespace/name format. Use this field in conjunction with the portNumber and portName to accurately select the Envoy route configuration for a specific HTTPS server within a gateway config object.
gateway: istio-system/istio-gateway
portNumber: 443
portName: https
patch:
operation: MERGE
value:
rate_limits:
- actions:
- dynamic_metadata:
descriptor_key: BAR
metadata_key:
key: example
path:
- key: uri
今すぐあなたのサービスを呼び出すときcurl -i https://<your host>/foo?param=value
続いてcurl -i https://<your host>/foo
. あなたは両方のURIが同じ規則によって制限されることを確かめる2番目の呼び出しで429を受け取るべきです.使節フィルタの構文変更
EnvironFilterをISIOサービスメッシュ構成に導入する場合は、マイナーアップグレードでも特使フィルタに特別な注意を払う必要があります.
As EnvoyFilter is a break glass API without backwards compatibility guarantees, we recommend users explicitly bind EnvoyFilters to specific versions and appropriately test them prior to upgrading.
使節版≠ バージョン
どのバージョンの使節があなたのistioサービスメッシュに配備されるかについてわかっていてください.istioと使節のバージョンは同期していません.
使節のバージョンを次のコマンドで確認できます.
kubectl exec -it <PODNAME-WITH-ENVOY-SIDECAR> -c istio-proxy -n istio-system -- pilot-agent request GET server_info
{
"version": "dc78069b10cc94fa07bb974b7101dd1b42e2e7bf/1.15.1-dev/Clean/RELEASE/BoringSSL",`
...
}
タイトルイメージTim Gouw on Unsplash ・・・アクションボタン
背景色:こっち重要
色:千円!重要
ボーダーカラー:こっち重要
}
NSATTLERフォローアップ
モリッツ・リーガー
Cloud Native, loves everything from DEV to OPS and in between. :)
Reference
この問題について(Inteyとistioでセットアップ料金制限装置をセットしてください), 我々は、より多くの情報をここで見つけました https://dev.to/tresmonauten/setup-an-ingress-rate-limiter-with-envoy-and-istio-1i9gテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol