Rate Limits主要功能是防止request過量打爆服務,當同一來源的request到達特定頻率時,就會直接從Istio Envoy這邊直接return http status 429 Too Many Requests,後面的服務不會持續被request到。
安裝好Istio跟Gateway與Virtual Service後,繼續進行Rate Limit的設定,Rate Limit的設定會分成二個part。
1.Istio :部署EnvoyFilter,讓Request走到external service
2.Rate Limit Service:需要部署一個external service讓Istio把流量導過去進行限流行為判斷
這部的yaml檔來自官方文檔中,基本上只需要調整external service就好了
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: filter-ratelimit
namespace: istio-system
spec:
workloadSelector:
# select by label in the same namespace
labels:
istio: ingressgateway #這邊的gateway名稱為填入你部署的gateway名稱
configPatches:
# The Envoy config you want to modify
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
# Adds the Envoy Rate Limit Filter in HTTP filter chain.
value:
name: envoy.filters.http.ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
# domain can be anything! Match it to the ratelimter service config
domain: productpage-ratelimit # damain 可以自填,但是domain要跟config檔的一致才行
failure_mode_deny: true # 如果external service壞掉了,是否要一律擋掉流量,預設false
timeout: 10s
rate_limit_service:
grpc_service: # 除了使用grpc_service外,也有http,但是一般都是預設gRPC
envoy_grpc:
cluster_name: rate_limit_cluster # 跟下面的設定的cluster_name要一樣
transport_api_version: V3
- applyTo: CLUSTER
match:
cluster:
service: ratelimit.default.svc.cluster.local #你的external service路徑
patch:
operation: ADD
# Adds the rate limit service cluster for rate limit service defined in step 1.
value:
name: rate_limit_cluster # 與上面的cluster_name設定一致
type: STRICT_DNS
connect_timeout: 10s
lb_policy: ROUND_ROBIN
http2_protocol_options: {}
load_assignment:
cluster_name: rate_limit_cluster # 與上面的cluster_name設定一致
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: ratelimit.default.svc.cluster.local #你的external service路徑
port_value: 8081 # gRPC port
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: filter-ratelimit-svc
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway #這邊的gateway名稱為填入你部署的gateway名稱
configPatches:
- applyTo: VIRTUAL_HOST #針對Virtual Service
match:
context: GATEWAY
routeConfiguration:
vhost:
name: "*:80" #ingress設定的host,*表示全部,後面為80port
route:
name: your_service 對應原本virtual service的service name
action: ANY
patch:
operation: MERGE
# Applies the rate limit rules.
value:
rate_limits: #Rate limit的設定
- actions: # any actions in here
- request_headers: #用header的auth_token進行ratelimit
header_name: "auth_token"
descriptor_key: "auth_token" #config裡面的value一致
這邊可以使用 ratelimit進行部署,記得要設定config,
或是直接在k8s上面設定configMap
apiVersion: v1
kind: ConfigMap
metadata:
name: ratelimit-config
data:
config.yaml: |
domain: productpage-ratelimit # 這邊的domain要跟前面的一致才行
descriptors:
- key: generic_key
value: auth_token # 跟上面envoyfilter定義的descriptor_key一致
descriptors:
- key: remote_address #來源ip
rate_limit:
requests_per_unit: 60 # 60 / 時間單位
unit: minute #時間單位
- key: PATH
value: "/productpage" 針對path
rate_limit:
unit: minute
requests_per_unit: 1
- key: PATH
rate_limit:
unit: minute
requests_per_unit: 100
以上部署完成就可以看到external service的access log啦,順帶一提,上面的external service是採用每時間單位就會重置的作法,像上面有設定60/min的設定,就是每分鐘會重置次數的意思啦