為入口網(wǎng)關(guān)配置全局限流
在面臨高流量沖擊、服務(wù)過載、資源耗盡或惡意攻擊的情況下,通過對入口網(wǎng)關(guān)的特定路由配置全局限流,可以實現(xiàn)對流量的精準(zhǔn)控制,從而保護(hù)后端服務(wù)的穩(wěn)定性,降低成本并提升用戶體驗。
前提條件
已添加Kubernetes托管版集群到ASM實例,且ASM實例為1.18.0.131及以上。具體操作,請參見添加集群到ASM實例。
已為Kubernetes集群中的default命名空間開啟自動注入。具體操作,請參見啟用自動注入。
已創(chuàng)建名為ingressgateway的入口網(wǎng)關(guān),并開啟80端口。具體操作,請參見創(chuàng)建入口網(wǎng)關(guān)。
準(zhǔn)備工作
一、部署限流服務(wù)
使用以下內(nèi)容,創(chuàng)建ratelimit-svc.yaml。
apiVersion: v1 kind: ServiceAccount metadata: name: redis --- apiVersion: v1 kind: Service metadata: name: redis labels: app: redis spec: ports: - name: redis port: 6379 selector: app: redis --- apiVersion: apps/v1 kind: Deployment metadata: name: redis spec: replicas: 1 selector: matchLabels: app: redis template: metadata: labels: app: redis sidecar.istio.io/inject: "false" spec: containers: - image: redis:alpine imagePullPolicy: Always name: redis ports: - name: redis containerPort: 6379 restartPolicy: Always serviceAccountName: redis --- apiVersion: v1 kind: ConfigMap metadata: name: ratelimit-config data: config.yaml: | {} --- apiVersion: v1 kind: Service metadata: name: ratelimit labels: app: ratelimit spec: ports: - name: http-port port: 8080 targetPort: 8080 protocol: TCP - name: grpc-port port: 8081 targetPort: 8081 protocol: TCP - name: http-debug port: 6070 targetPort: 6070 protocol: TCP selector: app: ratelimit --- apiVersion: apps/v1 kind: Deployment metadata: name: ratelimit spec: replicas: 1 selector: matchLabels: app: ratelimit strategy: type: Recreate template: metadata: labels: app: ratelimit sidecar.istio.io/inject: "false" spec: containers: # Latest image from https://hub.docker.com/r/envoyproxy/ratelimit/tags - image: envoyproxy/ratelimit:e059638d imagePullPolicy: Always name: ratelimit command: ["/bin/ratelimit"] env: - name: LOG_LEVEL value: debug - name: REDIS_SOCKET_TYPE value: tcp - name: REDIS_URL value: redis.default.svc.cluster.local:6379 - name: USE_STATSD value: "false" - name: RUNTIME_ROOT value: /data - name: RUNTIME_SUBDIRECTORY value: ratelimit - name: RUNTIME_WATCH_ROOT value: "false" - name: RUNTIME_IGNOREDOTFILES value: "true" ports: - containerPort: 8080 - containerPort: 8081 - containerPort: 6070 volumeMounts: - name: config-volume # $RUNTIME_ROOT/$RUNTIME_SUBDIRECTORY/$RUNTIME_APPDIRECTORY/config.yaml mountPath: /data/ratelimit/config volumes: - name: config-volume configMap: name: ratelimit-config
在ACK集群對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,在集群中創(chuàng)建限流服務(wù)和限流服務(wù)依賴的Redis服務(wù)。
關(guān)于如何通過kubectl連接集群,請參考獲取集群KubeConfig并通過kubectl工具連接集群。
kubectl apply -f ratelimit-svc.yaml
二、部署bookinfo示例應(yīng)用
從Github的Istio項目庫中下載bookinfo應(yīng)用的YAML文件bookinfo.yaml。
在ACK集群對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,將bookinfo應(yīng)用部署到ASM實例的集群中。
kubectl apply -f bookinfo.yaml
使用以下內(nèi)容,創(chuàng)建bookinfo-gateway.yaml。
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: bookinfo-gateway namespace: default spec: selector: istio: ingressgateway servers: - hosts: - bf2.example.com port: name: http number: 80 protocol: http --- apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: bookinfo namespace: default spec: gateways: - bookinfo-gateway hosts: - bf2.example.com http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products name: productpage-route-name1 route: - destination: host: productpage port: number: 9080
在ASM實例對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,創(chuàng)建入口網(wǎng)關(guān)ingressgateway對bookinfo應(yīng)用的路由規(guī)則。
該路由規(guī)則的名稱
為productpage-route-name1
,匹配請求域名bf2.example.com
。關(guān)于如何通過kubectl連接ASM實例,請參考通過控制面kubectl訪問Istio資源。kubectl apply -f bookinfo-gateway.yaml
場景一:對入口網(wǎng)關(guān)的特定路由配置全局限流
對bf2.example.com:80
這個域名和端口組合下的productpage-route-name1路由配置限流規(guī)則。productpage-route-name1是準(zhǔn)備工作中創(chuàng)建的虛擬服務(wù)booinfo中的一條路由項,匹配了請求的/productpage
、/static
、/login
、/logout
等路徑并將匹配的請求轉(zhuǎn)發(fā)到productpage服務(wù)。配置限流規(guī)則后,發(fā)往上述路徑的請求都將收到流量速率的限制。
使用以下內(nèi)容,創(chuàng)建global-ratelimit-gw.yaml。
apiVersion: istio.alibabacloud.com/v1beta1 kind: ASMGlobalRateLimiter metadata: name: global-test namespace: istio-system spec: workloadSelector: labels: istio: ingressgateway rateLimitService: # 準(zhǔn)備工作中部署的限流服務(wù)的配置。 host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5 isGateway: true configs: - name: productpage limit: unit: MINUTE quota: 1 match: vhost: name: bf2.example.com # 該名稱需要和VirtualService下的域名一致。 port: 80 # 該端口號需要和ASM網(wǎng)關(guān)端口匹配。 route: name_match: productpage-route-name1 # 該名稱需要和VirtualService下的路由規(guī)則一致。
部分字段說明如下。關(guān)于字段的更多信息,請參見ASMGlobalRateLimiter CRD說明。
字段
說明
workloadSelector
用于匹配限流生效的工作負(fù)載。本示例全局限流生效于ingressgateway入口網(wǎng)關(guān),設(shè)置為
istio: ingressgateway
。isGateway
是否作用于網(wǎng)關(guān)。本示例中設(shè)定為
true
。rateLimitService
限流服務(wù)的域名、端口和連接超時設(shè)置。根據(jù)準(zhǔn)備工作中部署的限流服務(wù),配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5
limit
需要生效的限流配置參數(shù)。其中
unit
表示限流檢測的時間單位,quota
表示單位時間內(nèi)允許的請求總量。本示例配置
unit
為MINUTE
、quota
為1
,表示匹配路由上每分鐘只能發(fā)送一個請求,超出的請求將被限流。vhost
限流匹配的域名和路由項配置。其中
name
、port
需要分別和應(yīng)用于網(wǎng)關(guān)的虛擬服務(wù)中的域名以及入口網(wǎng)關(guān)端口匹配,route.name_match
中填寫的路由名稱需要與虛擬服務(wù)中路由項的名稱一致。在ASM實例對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,創(chuàng)建生效于網(wǎng)關(guān)上
productpage-route-name1
路由項的全局限流規(guī)則。kubectl apply -f global-ratelimit-gw.yaml
執(zhí)行以下命令,獲取調(diào)諧完成的全局限流規(guī)則配置內(nèi)容。
kubectl get asmglobalratelimiter global-test -n istio-system -o yaml
apiVersion: istio.alibabacloud.com/v1beta1 kind: ASMGlobalRateLimiter metadata: name: global-test namespace: istio-system spec: configs: - limit: quota: 1 unit: MINUTE match: vhost: name: bf2.example.com port: 80 route: name_match: productpage-route-name1 name: productpage isGateway: true rateLimitService: host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5 workloadSelector: labels: app: istio-ingressgateway status: config.yaml: | descriptors: - key: generic_key rate_limit: requests_per_unit: 1 unit: MINUTE value: RateLimit[global-test.istio-system]-Id[597770312] domain: ratelimit.default.svc.cluster.local message: ok status: successful
將上一步預(yù)期輸出的ASMGlobalRateLimiter資源中
status
字段的config.yaml
內(nèi)容,粘貼至ratelimit-config.yaml,生成全局限流服務(wù)配置。ASMGlobalRateLimiter中
status
字段下的config.yaml
字段中的字符串內(nèi)容,需原樣粘貼至ConfigMap中data
中的同名config.yaml
字段中。apiVersion: v1 kind: ConfigMap metadata: name: ratelimit-config data: config.yaml: | descriptors: - key: generic_key rate_limit: requests_per_unit: 1 unit: MINUTE value: RateLimit[global-test.istio-system]-Id[597770312] domain: ratelimit.default.svc.cluster.local
在ACK集群對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,在集群中更新全局限流服務(wù)配置。
kubectl apply -f ratelimit-config.yaml
執(zhí)行以下命令,連續(xù)訪問bookinfo應(yīng)用兩次。
請將
<ASM網(wǎng)關(guān)IP>
替換為實際網(wǎng)關(guān)IP。關(guān)于如何獲取網(wǎng)關(guān)IP,請參見獲取入口網(wǎng)關(guān)地址。curl -H 'host: bf2.example.com' http://<ASM網(wǎng)關(guān)IP>/productpage -v curl -H 'host: bf2.example.com' http://<ASM網(wǎng)關(guān)IP>/productpage -v
第二次訪問bookinfo應(yīng)用的預(yù)期輸出如下:
< 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分鐘之內(nèi)只能有一次訪問bookinfo應(yīng)用的請求。當(dāng)連續(xù)兩次訪問bookinfo應(yīng)用時,可以看到第一條請求成功,第二條請求被限流,表明對入口網(wǎng)關(guān)的特定路由配置全局限流成功。
場景二:對入口網(wǎng)關(guān)的域名和端口組合配置全局限流
對bf2.example.com:80
這個域名和端口組合配置全局限流規(guī)則。配置限流規(guī)則后,發(fā)往該域名和端口組合的請求都將受到流量速率的限制。
使用以下內(nèi)容,創(chuàng)建global-ratelimit-gw.yaml。
apiVersion: istio.alibabacloud.com/v1beta1 kind: ASMGlobalRateLimiter metadata: name: global-test namespace: istio-system spec: workloadSelector: labels: istio: ingressgateway rateLimitService: # 準(zhǔn)備工作中部署的限流服務(wù)的配置。 host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5 isGateway: true configs: - name: productpage limit: unit: MINUTE quota: 1 match: vhost: name: bf2.example.com # 該名稱需要和VirtualService下的域名一致。 port: 80 # 該端口號需要和ASM網(wǎng)關(guān)端口匹配。
部分字段說明如下。關(guān)于字段的更多信息,請參見ASMGlobalRateLimiter CRD說明。
字段
說明
workloadSelector
用于匹配限流生效的工作負(fù)載。本示例全局限流生效于ingressgateway入口網(wǎng)關(guān),設(shè)置為
istio: ingressgateway
。isGateway
是否作用于網(wǎng)關(guān)。本示例中設(shè)定為
true
。rateLimitService
限流服務(wù)的域名、端口和連接超時設(shè)置。根據(jù)準(zhǔn)備工作中部署的限流服務(wù),配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5
limit
需要生效的限流配置參數(shù)。其中
unit
表示限流檢測的時間單位,quota
表示單位時間內(nèi)允許的請求總量。本示例配置
unit
為MINUTE
、quota
為1
,表示匹配路由上每分鐘只能發(fā)送一個請求,超出的請求將被限流。vhost
限流匹配的域名和路由項配置。其中
name
、port
需要分別和應(yīng)用于網(wǎng)關(guān)的虛擬服務(wù)中的域名以及入口網(wǎng)關(guān)端口匹配。在ASM實例對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,創(chuàng)建生效于網(wǎng)關(guān)上
productpage-route-name1
路由項的全局限流規(guī)則。kubectl apply -f global-ratelimit-gw.yaml
執(zhí)行以下命令,獲取調(diào)諧完成的全局限流規(guī)則配置內(nèi)容。
kubectl get asmglobalratelimiter global-test -n istio-system -o yaml
apiVersion: istio.alibabacloud.com/v1 kind: ASMGlobalRateLimiter metadata: name: global-test namespace: istio-system spec: configs: - limit: quota: 1 unit: MINUTE match: vhost: name: bf2.example.com port: 80 name: productpage isGateway: true rateLimitService: host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5 workloadSelector: labels: istio: ingressgateway status: config.yaml: | descriptors: - key: generic_key rate_limit: requests_per_unit: 1 unit: MINUTE value: RateLimit[global-test.istio-system]-Id[2100900480] domain: ratelimit.default.svc.cluster.local message: ok status: successful
將上一步預(yù)期輸出的ASMGlobalRateLimiter資源中
status
字段的config.yaml
內(nèi)容,粘貼至ratelimit-config.yaml,生成全局限流服務(wù)配置。ASMGlobalRateLimiter中
status
字段下的config.yaml
字段中的字符串內(nèi)容,需原樣粘貼至ConfigMap中data
中的同名config.yaml
字段中。apiVersion: v1 kind: ConfigMap metadata: name: ratelimit-config data: config.yaml: | descriptors: - key: generic_key rate_limit: requests_per_unit: 1 unit: MINUTE value: RateLimit[global-test.istio-system]-Id[2100900480] domain: ratelimit.default.svc.cluster.local
在ACK集群對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,在集群中更新全局限流服務(wù)配置。
kubectl apply -f ratelimit-config.yaml
執(zhí)行以下命令,連續(xù)訪問bookinfo應(yīng)用兩次。
請將
<ASM網(wǎng)關(guān)IP>
替換為實際網(wǎng)關(guān)IP。關(guān)于如何獲取網(wǎng)關(guān)IP,請參見獲取入口網(wǎng)關(guān)地址。curl -H 'host: bf2.example.com' http://<ASM網(wǎng)關(guān)IP>/productpage -v curl -H 'host: bf2.example.com' http://<ASM網(wǎng)關(guān)IP>/productpage -v
第二次訪問bookinfo應(yīng)用的預(yù)期輸出如下:
< 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分鐘之內(nèi)只能有一次請求訪問。當(dāng)連續(xù)兩次訪問該域名端口組合時,可以看到第一條請求成功,第二條請求被限流,表明對入口網(wǎng)關(guān)域名端口組合的全局限流配置成功。
場景三:在入口網(wǎng)關(guān)特定虛擬服務(wù)路由上,針對包含特定請求頭和查詢參數(shù)的請求配置限流規(guī)則
此場景需要ASM實例版本為1.19.0及以上。關(guān)于升級版本的具體操作,請參見升級ASM實例。
對bf2.example.com:80
這個域名和端口組合下的productpage-route-name1路由配置限流規(guī)則,同時指定限流規(guī)則只生效在帶有ratelimit: "true"
請求頭、且請求路徑上帶有查詢參數(shù)ratelimit=enabled
的請求上,該路由上的其他請求不受限流規(guī)則影響。匹配請求的/productpage
、/static
、/login
、/logout
等路徑并將匹配的請求轉(zhuǎn)發(fā)到productpage服務(wù)。配置限流規(guī)則后,發(fā)往上述路徑的請求都將收到流量速率的限制。
使用以下內(nèi)容,創(chuàng)建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 match: vhost: name: bf2.example.com port: 80 route: name_match: productpage-route-name1 # 該名稱需要和virtualservice下的route name一致。 limit_overrides: - request_match: header_match: - name: ratelimit exact_match: "true" query_match: - name: ratelimit exact_match: "enabled" limit: unit: MINUTE quota: 1
部分字段說明如下。關(guān)于字段的更多信息,請參見ASMGlobalRateLimiter CRD說明。
字段
說明
workloadSelector
用于匹配限流生效的工作負(fù)載。本示例全局限流生效于ingressgateway入口網(wǎng)關(guān),設(shè)置為
istio: ingressgateway
。isGateway
是否作用于網(wǎng)關(guān)。本示例中設(shè)定為
true
。rateLimitService
限流服務(wù)的域名、端口和連接超時設(shè)置。根據(jù)準(zhǔn)備工作中部署的限流服務(wù),配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5
limit
在虛擬服務(wù)路由上生效的限流配置參數(shù)。其中
unit
表示限流檢測的時間單位,quota
表示單位時間內(nèi)允許的請求總量。本示例配置unit
為SECOND
、quota
為100000
,表示匹配路由上每秒允許發(fā)送100000個請求。此設(shè)定約等于沒有配置限流,只希望滿足指定條件的請求被限流,其余請求不需要觸發(fā)限流。vhost
限流匹配的域名和路由項配置。其中
name
、port
需要分別和應(yīng)用于網(wǎng)關(guān)的虛擬服務(wù)中的域名以及入口網(wǎng)關(guān)端口匹配,route.name_match
中填寫的路由名稱需要與虛擬服務(wù)中路由項的名稱一致。limit_overrides
限流閾值覆蓋配置。可通過該字段針對特定的請求指定單獨的限流閾值。在本示例中:
limit_overrides
中的request_match
字段被設(shè)定為精確匹配含有ratelimit: "true"
請求頭、且請求路徑上帶有查詢參數(shù)ratelimit=enabled
的請求。limit_overrides
中的limit
字段配置unit
為MINUTE
、quota
為1
,表示對于滿足request_match
指定的條件的請求,每分鐘只允許發(fā)送一個。
在ASM實例對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,創(chuàng)建生效于網(wǎng)關(guān)上
productpage-route-name1
路由項的全局限流規(guī)則。kubectl apply -f global-ratelimit-gw.yaml
執(zhí)行以下命令,獲取調(diào)諧完成的全局限流規(guī)則配置內(nèi)容。
kubectl get asmglobalratelimiter global-test -n istio-system -o yaml
apiVersion: istio.alibabacloud.com/v1 kind: ASMGlobalRateLimiter metadata: name: global-test namespace: istio-system spec: configs: - limit: quota: 100000 unit: SECOND limit_overrides: - limit: quota: 1 unit: MINUTE request_match: header_match: - exact_match: "true" name: ratelimit query_match: - exact_match: enabled name: ratelimit match: vhost: name: bf2.example.com port: 80 route: name_match: productpage-route-name1 name: productpage isGateway: true rateLimitService: host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5 workloadSelector: labels: app: istio-ingressgateway status: config.yaml: | descriptors: - descriptors: - descriptors: - key: query_match rate_limit: requests_per_unit: 1 unit: MINUTE value: RateLimit[global-test.istio-system]-Id[1102463266] key: header_match value: RateLimit[global-test.istio-system]-Id[1102463266] key: generic_key rate_limit: requests_per_unit: 100000 unit: SECOND value: RateLimit[global-test.istio-system]-Id[1102463266] domain: ratelimit.default.svc.cluster.local message: ok status: successful
將上一步預(yù)期輸出的ASMGlobalRateLimiter資源中
status
字段的config.yaml
內(nèi)容,粘貼至ratelimit-config.yaml,生成全局限流服務(wù)配置。ASMGlobalRateLimiter中
status
字段下的config.yaml
字段中的字符串內(nèi)容,需原樣粘貼至ConfigMap中data
中的同名config.yaml
字段中。apiVersion: v1 kind: ConfigMap metadata: name: ratelimit-config data: config.yaml: | descriptors: - descriptors: - descriptors: - key: query_match rate_limit: requests_per_unit: 1 unit: MINUTE value: RateLimit[global-test.istio-system]-Id[1102463266] key: header_match value: RateLimit[global-test.istio-system]-Id[1102463266] key: generic_key rate_limit: requests_per_unit: 100000 unit: SECOND value: RateLimit[global-test.istio-system]-Id[1102463266] domain: ratelimit.default.svc.cluster.local
在ACK集群對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,在集群中更新全局限流服務(wù)配置。
kubectl apply -f ratelimit-config.yaml
執(zhí)行以下命令,連續(xù)訪問bookinfo應(yīng)用兩次。
請將
<ASM網(wǎng)關(guān)IP>
替換為實際網(wǎng)關(guān)IP。關(guān)于如何獲取網(wǎng)關(guān)IP,請參見獲取入口網(wǎng)關(guān)地址。curl -H 'host: bf2.example.com' http://<ASM網(wǎng)關(guān)IP>/productpage -v curl -H 'host: bf2.example.com' http://<ASM網(wǎng)關(guān)IP>/productpage -v
第二次訪問bookinfo應(yīng)用的預(yù)期輸出如下:
< 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"
請求頭、且請求路徑上帶有查詢參數(shù)ratelimit=enabled
的請求,1分鐘之內(nèi)只能有一次訪問bookinfo應(yīng)用的請求。當(dāng)攜帶上述的請求頭和請求查詢參數(shù)連續(xù)兩次訪問bookinfo應(yīng)用時,可以看到第一條請求成功,第二條請求被限流,表明對入口網(wǎng)關(guān)的匹配特定請求的全局限流配置成功。執(zhí)行以下命令,請求中不攜帶
ratelimit: "true"
請求頭和查詢參數(shù)ratelimit=enabled
,再次訪問bookinfo應(yīng)用。curl -H 'host: bf2.example.com' http://<ASM網(wǎng)關(guān)IP>/productpage -v
可以看到bookinfo應(yīng)用正常訪問,沒有出現(xiàn)429狀態(tài)碼,說明路由上的其他請求沒有受到全局限流影響。
場景四:在入口網(wǎng)關(guān)特定虛擬服務(wù)路由上,針對特定客戶端的IP地址進(jìn)行限流
此場景需要ASM實例版本為1.19.0及以上。關(guān)于升級版本的具體操作,請參見升級ASM實例。
要在ASM入口網(wǎng)關(guān)上配置針對特定客戶端IP地址進(jìn)行限流,需要首先保證ASM入口網(wǎng)關(guān)的外部流量策略設(shè)定為Local。關(guān)于創(chuàng)建入口網(wǎng)關(guān)的具體操作和配置項說明,請參見創(chuàng)建入口網(wǎng)關(guān)。
您可以在網(wǎng)關(guān)的訪問日志中,通過
downstream_remote_address
字段獲取發(fā)往網(wǎng)關(guān)的請求的客戶端IP地址。在此示例中,請根據(jù)您需要限流的實際客戶端IP地址進(jìn)行配置。
對bf2.example.com:80
這個域名和端口組合下的productpage-route-name1虛擬服務(wù)路由配置限流規(guī)則,同時指定限流規(guī)則只生效在來自特定客戶端IP地址的請求上,該路由上的其他請求不受限流規(guī)則影響。
使用以下內(nèi)容,創(chuàng)建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 match: vhost: name: bf2.example.com port: 80 route: name_match: productpage-route-name1 # 該名稱需要和virtualservice下的route name一致。 limit_overrides: - request_match: remote_address: address: xxx.xxx.xxx.xxx #客戶端IP地址。 v4_prefix_mask_len: xx #客戶端IP范圍子網(wǎng)掩碼。 limit: unit: MINUTE quota: 1
部分字段說明如下。關(guān)于字段的更多信息,請參見ASMGlobalRateLimiter CRD說明。
字段
說明
workloadSelector
用于匹配限流生效的工作負(fù)載。本示例全局限流生效于ingressgateway入口網(wǎng)關(guān),設(shè)置為
istio: ingressgateway
。isGateway
是否作用于網(wǎng)關(guān)。本示例中設(shè)定為
true
。rateLimitService
限流服務(wù)的域名、端口和連接超時設(shè)置。根據(jù)準(zhǔn)備工作中部署的限流服務(wù),配置如下:
host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5
limit
在虛擬服務(wù)路由上生效的限流配置參數(shù)。其中
unit
表示限流檢測的時間單位,quota
表示單位時間內(nèi)允許的請求總量。本示例配置
unit
為SECOND
、quota
為100000
,表示匹配路由上每秒允許發(fā)送100000個請求。此設(shè)定約等于沒有配置限流,只希望滿足指定條件的請求被限流,其余請求不需要觸發(fā)限流。vhost
限流匹配的域名和路由項配置。其中
name
、port
需要分別和應(yīng)用于網(wǎng)關(guān)的虛擬服務(wù)中的域名以及入口網(wǎng)關(guān)端口匹配,route.name_match
中填寫的路由名稱需要與虛擬服務(wù)中路由項的名稱一致。limit_overrides
限流閾值覆蓋配置。可通過該字段針對特定的請求指定單獨的限流閾值。在本示例中:
request_match
字段中,通過remote_address.address
匹配請求的客戶端源IP,通過remote_addess.v4_prefix_mask_len
匹配客戶端源IP的地址范圍子網(wǎng)掩碼(可選)。limit_overrides
字段中的limit
字段配置unit
為MINUTE
、quota
為1
,表示對于滿足request_match
指定的條件的請求,每分鐘只允許發(fā)送一個。
在ASM實例對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,創(chuàng)建生效于網(wǎng)關(guān)上
productpage-route-name1
路由項的全局限流規(guī)則。kubectl apply -f global-ratelimit-gw.yaml
執(zhí)行以下命令,獲取調(diào)諧完成的全局限流規(guī)則配置內(nèi)容。
kubectl get asmglobalratelimiter global-test -n istio-system -o yaml
apiVersion: istio.alibabacloud.com/v1 kind: ASMGlobalRateLimiter metadata: name: global-test namespace: istio-system spec: configs: - limit: quota: 100000 unit: SECOND limit_overrides: - limit: quota: 1 unit: MINUTE request_match: remote_address: address: 106.11.XX.XX v4_prefix_mask_len: 24 match: vhost: name: bf2.example.com port: 80 route: name_match: productpage-route-name1 name: productpage isGateway: true rateLimitService: host: ratelimit.default.svc.cluster.local port: 8081 timeout: seconds: 5 workloadSelector: labels: app: istio-ingressgateway status: config.yaml: | descriptors: - descriptors: - key: masked_remote_address rate_limit: requests_per_unit: 1 unit: MINUTE value: xxxxxx key: generic_key rate_limit: requests_per_unit: 100000 unit: SECOND value: RateLimit[global-test.istio-system]-Id[1102463266] domain: ratelimit.default.svc.cluster.local message: ok status: successful
將上一步預(yù)期輸出的ASMGlobalRateLimiter資源中
status
字段的config.yaml
內(nèi)容,粘貼至ratelimit-config.yaml,生成全局限流服務(wù)配置。ASMGlobalRateLimiter中
status
字段下的config.yaml
字段中的字符串內(nèi)容,需原樣粘貼至ConfigMap中data
中的同名config.yaml
字段中。apiVersion: v1 kind: ConfigMap metadata: name: ratelimit-config data: config.yaml: | descriptors: - descriptors: - key: masked_remote_address rate_limit: requests_per_unit: 1 unit: MINUTE value: xxxxxx key: generic_key rate_limit: requests_per_unit: 100000 unit: SECOND value: RateLimit[global-test.istio-system]-Id[1102463266] domain: ratelimit.default.svc.cluster.local
在ACK集群對應(yīng)的KubeConfig環(huán)境下,執(zhí)行以下命令,在集群中更新全局限流服務(wù)配置。
kubectl apply -f ratelimit-config.yaml
執(zhí)行以下命令,連續(xù)訪問bookinfo應(yīng)用兩次。
請將
<ASM網(wǎng)關(guān)IP>
替換為實際網(wǎng)關(guān)IP。關(guān)于如何獲取網(wǎng)關(guān)IP,請參見獲取入口網(wǎng)關(guān)地址。curl -H 'host: bf2.example.com' http://<ASM網(wǎng)關(guān)IP>/productpage -v curl -H 'host: bf2.example.com' http://<ASM網(wǎng)關(guān)IP>/productpage -v
第二次訪問bookinfo應(yīng)用的預(yù)期輸出如下:
< 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分鐘之內(nèi)只能有一次訪問bookinfo應(yīng)用的請求。當(dāng)使用特定IP地址的客戶端訪問網(wǎng)關(guān)時,可以看到第一條請求成功,第二條請求被限流,表明對入口網(wǎng)關(guān)的全局限流配置成功。
執(zhí)行以下命令,使用不同IP地址的客戶端,再次訪問bookinfo應(yīng)用。
curl -H 'host: bf2.example.com' http://<ASM網(wǎng)關(guān)IP>/productpage -v
可以看到bookinfo應(yīng)用正常訪問,沒有出現(xiàn)429狀態(tài)碼,說明路由上的其他請求沒有受到全局限流影響。
相關(guān)文檔
如果您想要使用不依賴限流服務(wù)、資源消耗更低的限流方式,可以使用ASM本地限流。具體操作,請參見在ASM中配置本地限流。
如果您需要對注入Sidecar的應(yīng)用服務(wù)的入口流量進(jìn)行控制和限制時,可以配置全局限流。具體操作,請參見對應(yīng)用服務(wù)入口流量配置全局限流。