全部產品
Search
文件中心

Alibaba Cloud Service Mesh:在流量管理中心配置本地限流

更新時間:Oct 24, 2024

在高流量衝擊、潛在服務過載、資源耗盡或惡意攻擊等情況下,您可以在流量管理中心配置本地限流,將流量維持在可控的閾值內,確保服務持續可用並維持效能穩定。本地限流通過Envoy代理實現,它採用令牌桶演算法來控制向服務端的請求流量。此演算法定期向令牌桶添加令牌,每個請求消耗一枚令牌。令牌耗盡時,系統將暫停接受新請求,有效預防過載情況發生。

前提條件

  • 已建立ASM執行個體,且ASM執行個體符合以下要求:

    • ASM商業版(專業版或旗艦版):版本需為1.14.3及以上。關於升級ASM執行個體的具體操作,請參見升級ASM執行個體

    • ASM標準版:僅支援Istio原生方式配置本地限流功能,且版本需為1.9及以上。不同Istio版本需參考相應版本文檔,關於最新的Istio版本配置本地限流功能的具體操作,請參見Enabling Rate Limits using Envoy

  • 已為Kubernetes叢集中的default命名空間開啟自動注入。具體操作,請參見啟用自動注入

  • 已部署httpbin和sleep樣本服務,並且sleep服務可以正常訪問httpbin服務。具體操作,請參見部署httpbin應用

情境一:對服務的特定連接埠進行限流

對httpbin服務的8000連接埠進行限流。配置限流規則後,發往httpbin服務8000連接埠的所有請求都將受到流量速率限制。

  1. 建立本地限流規則。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇流量管理中心 > 限流防護,然後單擊建立

    3. 建立頁面,按需進行以下配置,然後單擊確定

      配置地區

      配置項

      說明

      限流基本資料

      命名空間

      本地限流配置的命名空間,需要配置為限流生效的工作負載所在的命名空間。本樣本選擇default

      名稱

      本地限流配置的自訂名稱。本樣本填寫httpbin

      生效工作負載類型

      限流生效的工作負載類型,支援應用服務生效網關生效。本樣本選擇應用服務生效

      關聯工作負載

      需要填寫一系欄標籤索引值對,以選中具體工作負載。本樣本填寫標籤名app標籤值httpbin。

      限流規則列表

      服務Service連接埠

      填寫服務的Kubernetes Service中聲明的連接埠號碼,需要為HTTP連接埠。本樣本填寫httpbin服務的HTTP連接埠8000

      限流配置

      指定本地限流令牌桶演算法的檢測時間視窗長度與時間視窗內允許的請求數量。在時間視窗內發送的請求數量超過該允許的數量則會對請求進行限流。本樣本配置如下:

      • 限流檢測時間視窗填寫60秒

      • 時間視窗內允許請求數量填寫10

      以上配置表示發往此服務的工作負載的請求不得在60秒內連續發送10個以上。

      image

      以上配置對應的本地限流配置YAML如下。

      展開查看本地限流配置YAML

      apiVersion: istio.alibabacloud.com/v1beta1
      kind: ASMLocalRateLimiter
      metadata:
        name: httpbin
        namespace: default
      spec:
        configs:
          - limit:
              fill_interval:
                seconds: 60
              quota: 10
            match:
              vhost:
                name: '*'
                port: 8000
                route:
                  header_match:
                    - invert_match: false
                      name: ':path'
                      prefix_match: /
        isGateway: false
        workloadSelector:
          labels:
            app: httpbin

  2. 驗證本地限流規則。

    1. 執行以下命令,進入sleep環境開啟bash。

      kubectl exec -it deploy/sleep -- sh
    2. 執行以下命令,發送10個請求。

      for i in $(seq 1 10); do curl -v http://httpbin:8000/headers; done
    3. 執行以下命令,發送第11個請求。

      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: 2

      由預期輸出得到,返回HTTP 429的狀態代碼。請求已被限流。

情境二:在服務特定連接埠上,針對發往指定路徑的請求進行限流

對httpbin服務的8000連接埠進行限流,並限制限流只在訪問/headers路徑的請求上生效。配置限流規則後,發往httpbin服務8000連接埠且訪問路徑/headers的所有請求都將受到流量速率限制。

  1. 建立本地限流規則。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇流量管理中心 > 限流防護,然後單擊建立

    3. 建立頁面,按需進行以下配置,然後單擊確定

      配置地區

      配置項

      說明

      限流基本資料

      命名空間

      本地限流配置的命名空間,需要配置為限流生效的工作負載的所在命名空間。本樣本選擇default

      名稱

      本地限流配置的自訂名稱。本樣本填寫httpbin

      生效工作負載類型

      限流生效的工作負載類型,支援應用服務生效網關生效。本樣本選擇應用服務生效

      關聯工作負載

      需要填寫一系欄標籤索引值對,以選中具體工作負載。本樣本填寫標籤名app標籤值httpbin。

      限流規則列表

      服務Service連接埠

      填寫服務的Kubernetes Service中聲明的連接埠號碼,需要為HTTP連接埠。本樣本填寫httpbin服務的HTTP連接埠8000

      匹配請求屬性

      填寫生效限流配置的具體請求匹配規則。本樣本配置如下:

      • 匹配屬性選擇請求路徑

      • 匹配方法選擇首碼匹配

      • 匹配內容填寫/headers

      限流配置

      指定本地限流令牌桶演算法的檢測時間視窗長度與時間視窗內允許的請求數量。在時間視窗內發送的請求數量超過該允許的數量則會對請求進行限流。本樣本配置如下:

      • 限流檢測時間視窗填寫60秒

      • 時間視窗內允許請求數量填寫10

      以上配置表示發往此服務的工作負載的請求不得在60秒內連續發送10個以上。

      image

  2. 驗證本地限流規則。

    1. 執行以下命令,進入sleep環境開啟bash。

      kubectl exec -it deploy/sleep -- sh
    2. 執行以下命令,發送10個請求。

      for i in $(seq 1 10); do curl -v http://httpbin:8000/headers; done
    3. 執行以下命令,發送第11個請求。

      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: 2

      由預期輸出得到,返回HTTP 429的狀態代碼。請求已被限流。

    4. 執行以下命令,向httpbin服務的/get路徑發送請求。

      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狀態代碼。發往httpbin服務的其他路徑的請求並未受到限流規則影響。

相關操作

查看本地限流相關指標

本地限流功能會產生以下指標:

Metric

描述

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

最終收到限流響應的總數(例如返回429)。

您可以通過配置Sidecar代理的proxyStatsMatcher使Sidecar代理上報相關指標,然後使用Prometheus採集並查看限流相關指標。

  1. 通過proxyStatsMatcher配置Sidecar代理上報限流指標。

    在配置proxyStatsMatcher時,選中正則匹配,配置為.*http_local_rate_limit.*;或者直接單擊添加本地限流指標。具體操作,請參見proxyStatsMatcher

  2. 重新部署httpbin服務。具體操作,請參見重新部署工作負載

  3. 參照上文情境一情境二,完成本地限流配置及請求訪問。

  4. 執行以下命令,查看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版為例說明如何配置本地限流指標採集和警示。

  1. 在可觀測監控Prometheus版中,為資料面叢集接入阿里雲ASM組件或升級至最新版,以保證可觀測監控Prometheus版可以採集到暴露的本地限流指標。關於接入組件的具體操作,請參見接入組件管理。(如果您已經整合自建Prometheus實現網格監控來採集服務網格指標,則無需做額外操作。)

  2. 建立針對本地限流的警示規則。具體操作,請參見通過自訂PromQL建立Prometheus警示規則。配置警示規則的關鍵參數的填寫樣本如下,其餘參數可參考上述文檔根據實際需求填寫。

    參數

    樣本

    說明

    自訂PromQL語句

    (sum by(namespace, pod_name) (increase(envoy_http_local_rate_limiter_http_local_rate_limit_enforced[1m]))) > 0

    樣本PromQL通過increase查詢最近1分鐘之內被限流的請求數量,並根據觸發限流的pod所在命名空間以及pod名稱進行分組。當1分鐘內被限流的請求數量大於0時觸發警示。

    警示內容

    發生本地限流!命名空間:{{$labels.namespace}},觸發限流的pod:{{$labels.pod_name}}。當前1分鐘內被限流的請求數量:{{ $value }}

    使用者收到的警示資訊。樣本的警示資訊向使用者展示了觸發限流的pod所在命名空間以及pod名稱,以及最近1分鐘內被限流的請求數量

FAQ

為什麼針對服務配置本地限流後沒有生效?

服務沒有使用HTTP協議進行通訊、或者協議沒有被服務網格正確識別

本地限流僅支援HTTP協議,在對服務配置限流規則之前,您需要確保服務正在使用HTTP協議,或其它基於HTTP協議構建的應用程式層協議(如gRPC、dubbo3)進行通訊。

在服務本身使用HTTP協議通訊的基礎上,您還需要規範定義服務的協議類型,以保證服務網格可以正確識別服務所採用的應用程式層協議。具體操作,請參見如何規範定義服務的協議類型

使用Sidecar CRD修改了服務入向流量配置導致限流不生效

服務網格預設會根據Service定義中的連接埠聲明,自動為Sidecar代理配置入向流量監聽器。本地限流和全域限流功能都基於這一預設設定實現。

當您需要使叢集中監聽localhost的應用被其它Pod訪問時,可能會使用Sidecar CRD來修改服務預設的入向流量配置。具體操作,請參見如何使叢集中監聽localhost的應用被其它Pod訪問

在這種情況下,由於預設監聽器被修改,在本地限流中直接指定服務Service連接埠將無法讓限流生效。此時需要將本地限流中的服務Service連接埠配置為Sidecar CRD中指定的實際入向連接埠。

以本文中對httpbin服務的8000連接埠進行限流為例,若針對httpbin服務配置了以下的Sidecar CRD:

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

此時建立本地限流規則時服務Service連接埠應該填寫為80,而不是8000。

相關文檔