Inteyとistioでセットアップ料金制限装置をセットしてください


istio 1のミキサ成分の除去により,速度制限の構成が変化した.istio>1.5以降では、あなたのプロキシに適用されるEnVoiceFilterで制限を行います.したがって、使節についてより良い理解を得るために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_URLratelimit 展開.これで、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. :)