在面臨高流量衝擊、服務過載、資源耗盡或惡意攻擊的情況下,通過對入口網關的特定路由配置全域限流,可以實現對流量的精準控制,從而保護後端服務的穩定性,降低成本並提升使用者體驗。
前提條件
已添加Kubernetes託管版叢集到ASM執行個體,且ASM執行個體為1.18.0.131及以上。具體操作,請參見添加叢集到ASM執行個體。
已為Kubernetes叢集中的default命名空間開啟自動注入。具體操作,請參見啟用自動注入。
已建立名為ingressgateway的入口網關,並開啟80連接埠。具體操作,請參見建立入口網關。
準備工作
一、部署限流服務
使用以下內容,建立ratelimit-svc.yaml。
在ACK叢集對應的KubeConfig環境下,執行以下命令,在叢集中建立限流服務和限流服務依賴的Redis服務。
關於如何通過kubectl串連叢集,請參考擷取叢集KubeConfig並通過kubectl工具串連叢集。
kubectl apply -f ratelimit-svc.yaml
二、部署bookinfo樣本應用
從Github的Istio專案庫中下載bookinfo應用的YAML檔案bookinfo.yaml。
在ACK叢集對應的KubeConfig環境下,執行以下命令,將bookinfo應用部署到ASM執行個體的叢集中。
kubectl apply -f bookinfo.yaml
使用以下內容,建立bookinfo-gateway.yaml。
在ASM執行個體對應的KubeConfig環境下,執行以下命令,建立入口網關ingressgateway對bookinfo應用的路由規則。
該路由規則的名稱
為productpage-route-name1
,匹配請求網域名稱bf2.example.com
。關於如何通過kubectl串連ASM執行個體,請參考通過控制面kubectl訪問Istio資源。kubectl apply -f bookinfo-gateway.yaml
情境一:對入口網關的特定路由配置全域限流
對bf2.example.com:80
這個網域名稱和連接埠組合下的productpage-route-name1路由配置限流規則。productpage-route-name1是準備工作中建立的虛擬服務booinfo中的一條路由項,匹配了請求的/productpage
、/static
、/login
、/logout
等路徑並將匹配的請求轉寄到productpage服務。配置限流規則後,發往上述路徑的請求都將收到流量速率的限制。
使用以下內容,建立global-ratelimit-gw.yaml。
部分欄位說明如下。關於欄位的更多資訊,請參見ASMGlobalRateLimiter CRD說明。
欄位
說明
workloadSelector
用於匹配限流生效的工作負載。本樣本全域限流生效於ingressgateway入口網關,設定為
istio: ingressgateway
。isGateway
是否作用於網關。本樣本中設定為
true
。rateLimitService
限流服務的網域名稱、連接埠和連線逾時設定。根據準備工作中部署的限流服務,配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5
limit
需要生效的限流配置參數。其中
unit
表示限流檢測的時間單位,quota
表示單位時間內允許的請求總量。本樣本配置
unit
為MINUTE
、quota
為1
,表示匹配路由上每分鐘只能發送一個請求,超出的請求將被限流。vhost
限流匹配的網域名稱和路由項配置。其中
name
、port
需要分別和應用於網關的虛擬服務中的網域名稱以及入口網關連接埠匹配,route.name_match
中填寫的路由名稱需要與虛擬服務中路由項的名稱一致。在ASM執行個體對應的KubeConfig環境下,執行以下命令,建立生效於網關上
productpage-route-name1
路由項的全域限流規則。kubectl apply -f global-ratelimit-gw.yaml
執行以下命令,擷取調諧完成的全域限流規則配置內容。
kubectl get asmglobalratelimiter global-test -n istio-system -o yaml
將上一步預期輸出的ASMGlobalRateLimiter資源中
status
欄位的config.yaml
內容,粘貼至ratelimit-config.yaml,產生全域限流服務配置。ASMGlobalRateLimiter中
status
欄位下的config.yaml
欄位中的字串內容,需原樣粘貼至ConfigMap中data
中的同名config.yaml
欄位中。在ACK叢集對應的KubeConfig環境下,執行以下命令,在叢集中更新全域限流服務配置。
kubectl apply -f ratelimit-config.yaml
執行以下命令,連續訪問bookinfo應用兩次。
請將
<ASM網關IP>
替換為實際網關IP。關於如何擷取網關IP,請參見擷取入口網關地址。curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v
第二次訪問bookinfo應用的預期輸出如下:
< HTTP/1.1 429 Too Many Requests < x-envoy-ratelimited: true < x-ratelimit-limit: 1, 1;w=60 < x-ratelimit-remaining: 0 < x-ratelimit-reset: 48 < date: Thu, 26 Oct 2023 04:10:11 GMT < server: istio-envoy < content-length: 0 < * Connection #0 to host 116.62.XXX.XXX left intact
在全域限流配置中,限制1分鐘之內只能有一次訪問bookinfo應用的請求。當連續兩次訪問bookinfo應用時,可以看到第一條請求成功,第二條請求被限流,表明對入口網關的特定路由配置全域限流成功。
情境二:對入口網關的網域名稱和連接埠組合配置全域限流
對bf2.example.com:80
這個網域名稱和連接埠組合配置全域限流規則。配置限流規則後,發往該網域名稱和連接埠組合的請求都將受到流量速率的限制。
使用以下內容,建立global-ratelimit-gw.yaml。
部分欄位說明如下。關於欄位的更多資訊,請參見ASMGlobalRateLimiter CRD說明。
欄位
說明
workloadSelector
用於匹配限流生效的工作負載。本樣本全域限流生效於ingressgateway入口網關,設定為
istio: ingressgateway
。isGateway
是否作用於網關。本樣本中設定為
true
。rateLimitService
限流服務的網域名稱、連接埠和連線逾時設定。根據準備工作中部署的限流服務,配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5
limit
需要生效的限流配置參數。其中
unit
表示限流檢測的時間單位,quota
表示單位時間內允許的請求總量。本樣本配置
unit
為MINUTE
、quota
為1
,表示匹配路由上每分鐘只能發送一個請求,超出的請求將被限流。vhost
限流匹配的網域名稱和路由項配置。其中
name
、port
需要分別和應用於網關的虛擬服務中的網域名稱以及入口網關連接埠匹配。在ASM執行個體對應的KubeConfig環境下,執行以下命令,建立生效於網關上
productpage-route-name1
路由項的全域限流規則。kubectl apply -f global-ratelimit-gw.yaml
執行以下命令,擷取調諧完成的全域限流規則配置內容。
kubectl get asmglobalratelimiter global-test -n istio-system -o yaml
將上一步預期輸出的ASMGlobalRateLimiter資源中
status
欄位的config.yaml
內容,粘貼至ratelimit-config.yaml,產生全域限流服務配置。ASMGlobalRateLimiter中
status
欄位下的config.yaml
欄位中的字串內容,需原樣粘貼至ConfigMap中data
中的同名config.yaml
欄位中。在ACK叢集對應的KubeConfig環境下,執行以下命令,在叢集中更新全域限流服務配置。
kubectl apply -f ratelimit-config.yaml
執行以下命令,連續訪問bookinfo應用兩次。
請將
<ASM網關IP>
替換為實際網關IP。關於如何擷取網關IP,請參見擷取入口網關地址。curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v
第二次訪問bookinfo應用的預期輸出如下:
< HTTP/1.1 429 Too Many Requests < x-envoy-ratelimited: true < x-ratelimit-limit: 1, 1;w=60 < x-ratelimit-remaining: 0 < x-ratelimit-reset: 48 < date: Thu, 26 Oct 2023 04:10:11 GMT < server: istio-envoy < content-length: 0 < * Connection #0 to host 116.62.XXX.XXX left intact
在全域限流配置中,對於
bf2.example.com:80
這一網域名稱連接埠組合,限制1分鐘之內只能有一次請求訪問。當連續兩次訪問該網域名稱連接埠組合時,可以看到第一條請求成功,第二條請求被限流,表明對入口網關網域名稱連接埠組合的全域限流配置成功。
情境三:在入口網關特定虛擬服務路由上,針對包含特定要求標頭和查詢參數的請求配置限流規則
此情境需要ASM執行個體版本為1.19.0及以上。關於升級版本的具體操作,請參見升級ASM執行個體。
對bf2.example.com:80
這個網域名稱和連接埠組合下的productpage-route-name1路由配置限流規則,同時指定限流規則只生效在帶有ratelimit: "true"
要求標頭、且請求路徑上帶有查詢參數ratelimit=enabled
的請求上,該路由上的其他請求不受限流規則影響。匹配請求的/productpage
、/static
、/login
、/logout
等路徑並將匹配的請求轉寄到productpage服務。配置限流規則後,發往上述路徑的請求都將收到流量速率的限制。
使用以下內容,建立global-ratelimit-gw.yaml。
部分欄位說明如下。關於欄位的更多資訊,請參見ASMGlobalRateLimiter CRD說明。
欄位
說明
workloadSelector
用於匹配限流生效的工作負載。本樣本全域限流生效於ingressgateway入口網關,設定為
istio: ingressgateway
。isGateway
是否作用於網關。本樣本中設定為
true
。rateLimitService
限流服務的網域名稱、連接埠和連線逾時設定。根據準備工作中部署的限流服務,配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5
limit
在虛擬服務路由上生效的限流配置參數。其中
unit
表示限流檢測的時間單位,quota
表示單位時間內允許的請求總量。本樣本配置unit
為SECOND
、quota
為100000
,表示匹配路由上每秒允許發送100000個請求。此設定約等於沒有配置限流,只希望滿足指定條件的請求被限流,其餘請求不需要觸發限流。vhost
限流匹配的網域名稱和路由項配置。其中
name
、port
需要分別和應用於網關的虛擬服務中的網域名稱以及入口網關連接埠匹配,route.name_match
中填寫的路由名稱需要與虛擬服務中路由項的名稱一致。limit_overrides
限流閾值覆蓋配置。可通過該欄位針對特定的請求指定單獨的限流閾值。在本樣本中:
limit_overrides
中的request_match
欄位被設定為精確匹配含有ratelimit: "true"
要求標頭、且請求路徑上帶有查詢參數ratelimit=enabled
的請求。limit_overrides
中的limit
欄位配置unit
為MINUTE
、quota
為1
,表示對於滿足request_match
指定的條件的請求,每分鐘只允許發送一個。
在ASM執行個體對應的KubeConfig環境下,執行以下命令,建立生效於網關上
productpage-route-name1
路由項的全域限流規則。kubectl apply -f global-ratelimit-gw.yaml
執行以下命令,擷取調諧完成的全域限流規則配置內容。
kubectl get asmglobalratelimiter global-test -n istio-system -o yaml
將上一步預期輸出的ASMGlobalRateLimiter資源中
status
欄位的config.yaml
內容,粘貼至ratelimit-config.yaml,產生全域限流服務配置。ASMGlobalRateLimiter中
status
欄位下的config.yaml
欄位中的字串內容,需原樣粘貼至ConfigMap中data
中的同名config.yaml
欄位中。在ACK叢集對應的KubeConfig環境下,執行以下命令,在叢集中更新全域限流服務配置。
kubectl apply -f ratelimit-config.yaml
執行以下命令,連續訪問bookinfo應用兩次。
請將
<ASM網關IP>
替換為實際網關IP。關於如何擷取網關IP,請參見擷取入口網關地址。curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v
第二次訪問bookinfo應用的預期輸出如下:
< HTTP/1.1 429 Too Many Requests < x-envoy-ratelimited: true < x-ratelimit-limit: 1, 1;w=60 < x-ratelimit-remaining: 0 < x-ratelimit-reset: 48 < date: Thu, 26 Oct 2023 04:10:11 GMT < server: istio-envoy < content-length: 0 < * Connection #0 to host 116.62.XXX.XXX left intact
在全域限流配置中,限制對於含有
ratelimit: "true"
要求標頭、且請求路徑上帶有查詢參數ratelimit=enabled
的請求,1分鐘之內只能有一次訪問bookinfo應用的請求。當攜帶上述的要求標頭和請求查詢參數連續兩次訪問bookinfo應用時,可以看到第一條請求成功,第二條請求被限流,表明對入口網關的匹配特定請求的全域限流配置成功。執行以下命令,請求中不攜帶
ratelimit: "true"
要求標頭和查詢參數ratelimit=enabled
,再次訪問bookinfo應用。curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v
可以看到bookinfo應用正常訪問,沒有出現429狀態代碼,說明路由上的其他請求沒有受到全域限流影響。
情境四:在入口網關特定虛擬服務路由上,針對特定用戶端的IP地址進行限流
對bf2.example.com:80
這個網域名稱和連接埠組合下的productpage-route-name1虛擬服務路由配置限流規則,同時指定限流規則只生效在來自特定用戶端IP地址的請求上,該路由上的其他請求不受限流規則影響。
使用以下內容,建立global-ratelimit-gw.yaml。
部分欄位說明如下。關於欄位的更多資訊,請參見ASMGlobalRateLimiter CRD說明。
欄位
說明
workloadSelector
用於匹配限流生效的工作負載。本樣本全域限流生效於ingressgateway入口網關,設定為
istio: ingressgateway
。isGateway
是否作用於網關。本樣本中設定為
true
。rateLimitService
限流服務的網域名稱、連接埠和連線逾時設定。根據準備工作中部署的限流服務,配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5
limit
在虛擬服務路由上生效的限流配置參數。其中
unit
表示限流檢測的時間單位,quota
表示單位時間內允許的請求總量。本樣本配置
unit
為SECOND
、quota
為100000
,表示匹配路由上每秒允許發送100000個請求。此設定約等於沒有配置限流,只希望滿足指定條件的請求被限流,其餘請求不需要觸發限流。vhost
限流匹配的網域名稱和路由項配置。其中
name
、port
需要分別和應用於網關的虛擬服務中的網域名稱以及入口網關連接埠匹配,route.name_match
中填寫的路由名稱需要與虛擬服務中路由項的名稱一致。limit_overrides
限流閾值覆蓋配置。可通過該欄位針對特定的請求指定單獨的限流閾值。在本樣本中:
request_match
欄位中,通過remote_address.address
匹配請求的用戶端源IP,通過remote_addess.v4_prefix_mask_len
匹配用戶端源IP的位址範圍子網路遮罩(可選)。limit_overrides
欄位中的limit
欄位配置unit
為MINUTE
、quota
為1
,表示對於滿足request_match
指定的條件的請求,每分鐘只允許發送一個。
在ASM執行個體對應的KubeConfig環境下,執行以下命令,建立生效於網關上
productpage-route-name1
路由項的全域限流規則。kubectl apply -f global-ratelimit-gw.yaml
執行以下命令,擷取調諧完成的全域限流規則配置內容。
kubectl get asmglobalratelimiter global-test -n istio-system -o yaml
將上一步預期輸出的ASMGlobalRateLimiter資源中
status
欄位的config.yaml
內容,粘貼至ratelimit-config.yaml,產生全域限流服務配置。ASMGlobalRateLimiter中
status
欄位下的config.yaml
欄位中的字串內容,需原樣粘貼至ConfigMap中data
中的同名config.yaml
欄位中。在ACK叢集對應的KubeConfig環境下,執行以下命令,在叢集中更新全域限流服務配置。
kubectl apply -f ratelimit-config.yaml
執行以下命令,連續訪問bookinfo應用兩次。
請將
<ASM網關IP>
替換為實際網關IP。關於如何擷取網關IP,請參見擷取入口網關地址。curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v
第二次訪問bookinfo應用的預期輸出如下:
< HTTP/1.1 429 Too Many Requests < x-envoy-ratelimited: true < x-ratelimit-limit: 1, 1;w=60 < x-ratelimit-remaining: 0 < x-ratelimit-reset: 48 < date: Thu, 26 Oct 2023 04:10:11 GMT < server: istio-envoy < content-length: 0 < * Connection #0 to host 116.62.XXX.XXX left intact
在全域限流配置中,限制來自特定IP地址(或位址範圍)的請求,1分鐘之內只能有一次訪問bookinfo應用的請求。當使用特定IP地址的用戶端訪問網關時,可以看到第一條請求成功,第二條請求被限流,表明對入口網關的全域限流配置成功。
執行以下命令,使用不同IP地址的用戶端,再次訪問bookinfo應用。
curl -H 'host: bf2.example.com' http://<ASM網關IP>/productpage -v
可以看到bookinfo應用正常訪問,沒有出現429狀態代碼,說明路由上的其他請求沒有受到全域限流影響。
相關文檔
如果您想要使用不依賴限流服務、資源消耗更低的限流方式,可以使用ASM本地限流。具體操作,請參見在ASM中配置本地限流。
如果您需要對注入Sidecar的應用服務的入口流量進行控制和限制時,可以配置全域限流。具體操作,請參見對應用服務入口流量配置全域限流。