在面臨高流量衝擊、服務過載、資源耗盡或惡意攻擊的情況下,通過對入口網關的特定路由配置全域限流,可以實現對流量的精準控制,從而保護後端服務的穩定性,降低成本並提升使用者體驗。
前提條件
已添加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: 5limit需要生效的限流配置參數。其中
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: 5limit需要生效的限流配置參數。其中
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: 5limit在虛擬服務路由上生效的限流配置參數。其中
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: 5limit在虛擬服務路由上生效的限流配置參數。其中
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狀態代碼,說明路由上的其他請求沒有受到全域限流影響。
情境五:在入口網關特定虛擬服務路由上,針對不同的用戶端IP地址分別限流
本情境將對bf2.example.com:80這個網域名稱和連接埠組合下的productpage-route-name1虛擬服務路由配置限流規則,指定限流規則對每個不同的用戶端IP地址分別進行限流,每個用戶端IP每分鐘只能請求一次。
建立global-ratelimit-gw.yaml。
apiVersion: istio.alibabacloud.com/v1beta1 kind: ASMGlobalRateLimiter metadata: name: global-test namespace: istio-system spec: workloadSelector: labels: app: istio-ingressgateway rateLimitService: host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5 isGateway: true configs: - name: productpage limit: unit: SECOND quota: 100000 target_services: - name: bookinfo namespace: default kind: VirtualService port: 80 section_name: productpage-route-name1 limit_overrides: - request_match: remote_address: distinct: true # 指定針對用戶端IP地址分別進行限流 limit: unit: MINUTE quota: 1部分欄位說明如下。關於欄位的更多資訊,請參見ASMGlobalRateLimiter CRD說明。
欄位
說明
workloadSelector用於匹配限流生效的工作負載。本樣本全域限流生效於ingressgateway入口網關,設定為
istio: ingressgateway。isGateway是否作用於網關。本樣本中設定為
true。rateLimitService限流服務的網域名稱、連接埠和連線逾時設定。根據準備工作中部署的限流服務,配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5limit在虛擬服務路由上生效的限流配置參數。其中:
unit表示限流檢測的時間單位。quota表示單位時間內允許的請求總量。
本樣本配置
unit為SECOND、quota為100000,表示匹配路由上每秒允許發送100000個請求。此設定約等於沒有配置限流,只希望滿足指定條件的請求被限流,其餘請求不需要觸發限流。limit_overrides限流閾值覆蓋配置。可通過該欄位針對特定的請求指定單獨的限流閾值。在本樣本中:
request_match欄位中:remote_address.address用於匹配請求的用戶端源IP。remote_address.address.disinct設定為true表示開啟針對不同用戶端IP分別進行限流。remote_addess.v4_prefix_mask_len匹配用戶端源IP的位址範圍子網路遮罩(可選)。
limit_overrides欄位中的limit欄位配置unit為MINUTE、quota為1,表示對於滿足request_match指定的條件的請求,每分鐘只允許發送一個。
target_services限流項匹配的虛擬服務路由配置。其中:
kind指定了限流規則生效目標為虛擬服務路由。namespace和name指定了虛擬服務的命名空間和名稱。port指定了限流規則僅在80連接埠的流量路由上生效。section_name指定了限流規則在虛擬服務的名為productpage-route-name1的路由項上生效。
部署全域限流規則。
kubectl apply -f global-ratelimit-gw.yaml擷取調諧完成的全域限流規則配置內容。
kubectl get asmglobalratelimiter global-test -n istio-system -o yaml |grep status: -A 50預期輸出:
status: config.yaml: | descriptors: - descriptors: - key: remote_address rate_limit: requests_per_unit: 1 unit: MINUTE key: generic_key rate_limit: requests_per_unit: 100000 unit: SECOND value: RateLimit[global-test.istio-system]-Id[537612397] domain: ratelimit.default.svc.cluster.local message: ok status: successful將上一步輸出的內容更新到準備工作的ConfigMap中
data中的同名config.yaml欄位中。kubectl edit ConfigMap ratelimit-config更新後內容:
apiVersion: v1 kind: ConfigMap metadata: name: ratelimit-config data: config.yaml: | descriptors: - descriptors: - key: remote_address rate_limit: requests_per_unit: 1 unit: MINUTE key: generic_key rate_limit: requests_per_unit: 100000 unit: SECOND value: RateLimit[global-test.istio-system]-Id[537612397] domain: ratelimit.default.svc.cluster.local分別從不同的用戶端連續訪問bookinfo應用兩次。
export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') curl -H 'host: bf2.example.com' http://$GATEWAY_URL:80/productpage -v curl -H 'host: bf2.example.com' http://$GATEWAY_URL:80/productpage -v第二次訪問的預期輸出:
< 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 Jul 2025 04:10:11 GMT < server: istio-envoy < content-length: 0 < * Connection #0 to host 116.62.XXX.XXX left intact可以看到,第二條請求被限流,表明對入口網關的全域限流配置成功。
相關文檔
如果您想要使用不依賴限流服務、資源消耗更低的限流方式,可以使用ASM本地限流。具體操作,請參見在ASM中配置本地限流。
如果您需要對注入Sidecar的應用服務的入口流量進行控制和限制時,可以配置全域限流。具體操作,請參見對應用服務入口流量配置全域限流。