不懂envoyfilter也敢说精通istio系列-ratelimit-istio ratelimit完全手册
欢迎关注我的公众号:
目前刚开始写一个月,一共写了18篇原创文章,文章目录如下:
istio多集群探秘,部署了50次多集群后我得出的结论
istio多集群链路追踪,附实操视频
istio防故障利器,你知道几个,istio新手不要读,太难!
istio业务权限控制,原来可以这么玩
istio实现非侵入压缩,微服务之间如何实现压缩
不懂envoyfilter也敢说精通istio系列-http-rbac-不要只会用AuthorizationPolicy配置权限
不懂envoyfilter也敢说精通istio系列-02-http-corsFilter-不要只会vs
不懂envoyfilter也敢说精通istio系列-03-http-csrf filter-再也不用再代码里写csrf逻辑了
不懂envoyfilter也敢说精通istio系列http-jwt_authn-不要只会RequestAuthorization
不懂envoyfilter也敢说精通istio系列-05-fault-filter-故障注入不止是vs
不懂envoyfilter也敢说精通istio系列-06-http-match-配置路由不只是vs
不懂envoyfilter也敢说精通istio系列-07-负载均衡配置不止是dr
不懂envoyfilter也敢说精通istio系列-08-连接池和断路器
不懂envoyfilter也敢说精通istio系列-09-http-route filter
不懂envoyfilter也敢说精通istio系列-network filter-redis proxy
不懂envoyfilter也敢说精通istio系列-network filter-HttpConnectionManager
不懂envoyfilter也敢说精通istio系列-ratelimit-istio ratelimit完全手册
1什么是ratelimit
ratelimit是限速的意思,主要作用是限值流量,防止因系统过载而崩溃。istio限速有两大类,一个是本地限速,另一个是全局限速。本地限速是在envoy内部提供一种令牌桶限速得功能,全局限速需要访问外部限速服务。按生效位置分可分为virtualhost级别的限速和route级别的限速。按协议分可分为http的限速和tcp的限速。按服务位置分可分为mesh内部限速和对外部请求的限速。按集群分可分为单集群限速和多集群限速。
2配置
extensions.filters.http.ratelimit.v3.RateLimit:
{"domain": "...",对应ratelimit配置文件中的域名"stage": "...",stage配置和action中的stage必须匹配,默认0"request_type": "...", internal, external or both默认both"timeout": "{...}",ratelimit服务请求的超时时间,默认20ms"failure_mode_deny": "...",如果ratelimit服务请求失败,则返回错误"rate_limited_as_resource_exhausted": "...",RESOURCE_EXHAUSTED code代替UNAVAILABLE code"rate_limit_service": "{...}",指定外部限速服务"enable_x_ratelimit_headers": "...",定义ratelimit头版本"disable_x_envoy_ratelimited_header": "..."禁用x-envoy-ratelimited头
}
rate_limit_service:
{"grpc_service": "{...}",配置ratelimit服务"transport_api_version": "..."版本
}
grpc_service:
{"envoy_grpc": "{...}",envoy grpc客户端"google_grpc": "{...}",google grpc客户端"timeout": "{...}",grpc请求超时时间"initial_metadata": []额外的元数据信息
}
envoy_grpc:
{"cluster_name": "...",集群名称"authority": "..." :authority头的值,默认cluster_name
}
google_grpc:
{"target_uri": "...",目标uri"channel_credentials": "{...}",秘钥"call_credentials": [],调用秘钥"stat_prefix": "...",stat前缀"credentials_factory_name": "...",秘钥工厂名称"config": "{...}",额外配置"per_stream_buffer_limit_bytes": "{...}",每个流的缓存限值,默认1MiB"channel_args": "{...}"通道参数
}
transport_api_version:
xDS API and non-xDS services version. This is used to describe both resource and transport protocol versions (in distinct configuration fields).
AUTO
(DEFAULT) When not specified, we assume v2, to ease migration to Envoy’s stable API versioning. If a client does not support v2 (e.g. due to deprecation), this is an invalid value.
V2
Use xDS v2 API.
V3
Use xDS v3 API.
enable_x_ratelimit_headers:
Defines the version of the standard to use for X-RateLimit headers.
OFF
(DEFAULT) X-RateLimit headers disabled.
DRAFT_VERSION_03
Use draft RFC Version 03.
extensions.filters.network.local_ratelimit.v3.LocalRateLimit
{"stat_prefix": "...",stat前缀"token_bucket": "{...}",令牌桶规则"runtime_enabled": "{...}"启用百分比
}
token_bucket:
{"max_tokens": "...",最大令牌数"tokens_per_fill": "{...}",每次填充的令牌数"fill_interval": "{...}"填充间隔
}
runtime_enabled:
{"default_value": "{...}",百分比"runtime_key": "..."运行时key
}
config.route.v3.RateLimit
{"stage": "{...}",阶段号,必须和ratelimit过滤器匹配"disable_key": "...",禁用的key"actions": [],动作"limit": "{...}"动态元数据
}
actions:
{"source_cluster": "{...}",源集群动作"destination_cluster": "{...}",目标集群动作"request_headers": "{...}",请求头动作"remote_address": "{...}",远程地址动作"generic_key": "{...}",通用key动作"header_value_match": "{...}",头匹配动作"dynamic_metadata": "{...}",动态元数据动作"metadata": "{...}",元数据动作"extension": "{...}"扩展动作
}
limit:
{"dynamic_metadata": "{...}"动态元数据
}
extensions.filters.network.ratelimit.v3.RateLimit
{"stat_prefix": "...","domain": "...","descriptors": [],"timeout": "{...}","failure_mode_deny": "...","rate_limit_service": "{...}"
}
3实战
3.1.1http
3.1.1.1单集群
3.1.1.1.1集群内服务限流
3.1.1.1.1.1本地限流
cat <<EOF > envoyfilter-local-rate-limit.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-local-ratelimit-svc
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: HTTP_FILTERmatch:listener:filterChain:filter:name: "envoy.filters.network.http_connection_manager"patch:operation: INSERT_BEFOREvalue:name: envoy.filters.http.local_ratelimittyped_config:"@type": type.googleapis.com/udpa.type.v1.TypedStructtype_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimitvalue:stat_prefix: http_local_rate_limitertoken_bucket:max_tokens: 10tokens_per_fill: 10fill_interval: 60sfilter_enabled:runtime_key: local_rate_limit_enableddefault_value:numerator: 100denominator: HUNDREDfilter_enforced:runtime_key: local_rate_limit_enforceddefault_value:numerator: 100denominator: HUNDREDresponse_headers_to_add:- append: falseheader:key: x-local-rate-limitvalue: 'true'
EOFkubectl apply -f envoyfilter-local-rate-limit.yaml -n istio
说明:本地限流需要通过EnvoyFilter来实现,他不会请求外部服务,在envoy内部实现支持,是一个令牌桶的算法。http filter的名称必须是envoy.filters.http.local_ratelimit,type和typeurl是固定的,stat_prefix可以随便改,表示生成stat的指标前缀。token_bucket配置令牌桶,max_tokens表示最大令牌数量,tokens_per_fill表示每次填充的令牌数量,fill_interval表示填充令牌的间隔。filter_enabled表示启用但不是强制,filter_enforced表示强制,可以配置百分比。response_headers_to_add修改响应头信息,append为false表示修改,true表示添加。runtime_key 运行时的key,具体有啥用不清楚。
执行压测:
[root@node01 45]# go-stress-testing -c 10 -n 10000 -u http://192.168.229.134:30945/productpage开始启动 并发数:10 请求数:10000 请求参数:
request:form:http url:http://192.168.229.134:30945/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 7│ 2│ 761│ 2.94│ 124.68│ 1.98│ 3406.97│ 21,476│ 21,470│200:2;429:7612s│ 10│ 5│ 1636│ 2.55│ 1788.46│ 1.98│ 3928.11│ 52,771│ 26,383│200:5;429:16363s│ 10│ 5│ 2962│ 1.70│ 1788.46│ 1.04│ 5871.68│ 76,639│ 25,545│200:5;429:29624s│ 10│ 5│ 4459│ 1.28│ 1788.46│ 1.04│ 7810.78│ 103,585│ 25,896│200:5;429:4459
429 Too Many Requests (太多请求)
当你需要限制客户端请求某个服务的数量,也就是限制请求速度时,该状态码就会非常有用
清理:
kubectl delete envoyfilter filter-local-ratelimit-svc -n istio
3.1.1.1.1.2全局限流
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: PATHvalue: "/productpage"rate_limit:unit: minuterequests_per_unit: 1- key: PATHrate_limit:unit: minuterequests_per_unit: 100
EOFkubectl apply -f ratelimit-config.yaml -n istio
说明: 这个configmap是限速服务用到的配置文件,他是envoy v3版本的限速格式。domain是域名,他会在envoyfilter中被引用,descriptors的PATH,表示请求的路径可以有多个值,rate_limit配置限速配额,这里productpage配了1分钟1个请求,其他url是1分钟100个请求
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
创建了redis,和官方的一个ratelimit服务。
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio-system
spec:workloadSelector:# select by label in the same namespacelabels:istio: ingressgatewayconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: GATEWAYlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio-system
这个envoyfilter作用在网关上面,配置了一个http过滤器envoy.filters.http.ratelimit,和一个cluster。http 过滤器的cluster地址指向cluster配置的地址,这里就是我们的ratelimit service所在的地址。domain是上面configmap的值一样,failure_mode_deny表示超过请求限值就拒绝,rate_limit_service配置ratelimit服务的地址(cluster),这里可以配置grpc类型的也可以配置http类型的。
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio-system
spec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: GATEWAYrouteConfiguration:vhost:name: "*:80"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: # any actions in here- request_headers:header_name: ":path"descriptor_key: "PATH"
EOFkubectl apply -f envoyfilter-action.yaml -n istio-system
这个envoyfilter作用在入口网关处,给80端口的虚拟主机配置了一个rate_limits 动作,descriptor_key用于选择在configmap里配置的key。
压测:
[root@node01 ~]# go-stress-testing -c 10 -n 10000 -u http://192.168.229.134:30945/productpage开始启动 并发数:10 请求数:10000 请求参数:
request:form:http url:http://192.168.229.134:30945/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 1│ 1051│ 1.01│ 55.51│ 3.70│ 9914.38│ 4,183│ 4,176│200:1;429:10512s│ 10│ 1│ 1629│ 0.50│ 55.51│ 3.70│19807.86│ 4,183│ 2,090│200:1;429:16293s│ 10│ 1│ 2154│ 0.34│ 55.51│ 3.70│29829.63│ 4,183│ 1,393│200:1;429:21544s│ 10│ 1│ 2662│ 0.25│ 55.51│ 3.70│39823.69│ 4,183│ 1,045│200:1;429:26625s│ 10│ 1│ 3166│ 0.20│ 58.63│ 3.70│49865.16│ 4,183│ 836│200:1;429:3166
清理:
kubectl delete cm ratelimit-config -n istio
kubectl delete -f ratelimit-deploy.yaml -n istio
kubectl delete envoyfilter filter-ratelimit -n istio-system
kubectl delete envoyfilter filter-ratelimit-svc -n istio-system
3.1.1.1.2集群外服务限流
3.1.1.1.2.1本地限流
cat << EOF > se-baidu.yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:name: baidu
spec:hosts:- www.baidu.comports:- number: 80name: http-portprotocol: HTTPresolution: DNS
EOFkubectl apply -f se-baidu.yaml -n istio
说明,创建了访问百度的service entry
cat <<EOF > envoyfilter-local-rate-limit-http-outside.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-local-ratelimit-svc
spec:workloadSelector:labels:app: ratingsconfigPatches:- applyTo: HTTP_FILTERmatch:context: SIDECAR_OUTBOUNDlistener:filterChain:filter:name: "envoy.filters.network.http_connection_manager"subFilter:name: "envoy.filters.http.router"patch:operation: INSERT_BEFOREvalue:name: envoy.filters.http.local_ratelimittyped_config:"@type": type.googleapis.com/udpa.type.v1.TypedStructtype_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimitvalue:stat_prefix: http_local_rate_limitertoken_bucket:max_tokens: 1tokens_per_fill: 1fill_interval: 60sfilter_enabled:runtime_key: local_rate_limit_enableddefault_value:numerator: 100denominator: HUNDREDfilter_enforced:runtime_key: local_rate_limit_enforceddefault_value:numerator: 100denominator: HUNDREDresponse_headers_to_add:- append: falseheader:key: x-local-rate-limitvalue: 'true'
EOFkubectl apply -f envoyfilter-local-rate-limit-http-outside.yaml -n istio
说明:SIDECAR_OUTBOUND表示对外发出请求起作用。本地限流需要通过EnvoyFilter来实现,他不会请求外部服务,在envoy内部实现支持,是一个令牌桶的算法。http filter的名称必须是envoy.filters.http.local_ratelimit,type和typeurl是固定的,stat_prefix可以随便改,表示生成stat的指标前缀。token_bucket配置令牌桶,max_tokens表示最大令牌数量,tokens_per_fill表示每次填充的令牌数量,fill_interval表示填充令牌的间隔。filter_enabled表示启用但不是强制,filter_enforced表示强制,可以配置百分比。response_headers_to_add修改响应头信息,append为false表示修改,true表示添加。runtime_key 运行时的key,具体有啥用不清楚。
kubectl exec -it -n istio ratings-v2-mysql-vm-66dc56449d-lk6gv /bin/bashlocal_rate_limitednode@ratings-v2-mysql-vm-66dc56449d-lk6gv:/opt/microservices$ curl www.baidu.com -I
HTTP/1.1 429 Too Many Requests
x-local-rate-limit: true
content-length: 18
content-type: text/plain
date: Fri, 17 Sep 2021 23:20:13 GMT
server: envoy
进入ratings容器,对百度发请求,409错误,说明限流生效
清理:
kubectl delete se baidu -n istio
kubectl delete envoyfilter filter-local-ratelimit-svc -n istio
3.1.1.1.2.2全局限流
部署ratelimit
1创建cm
cat << EOF > ratelimit-config-outside-http.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: PATHvalue: "/"rate_limit:unit: minuterequests_per_unit: 1- key: PATHvalue: "/aa"rate_limit:unit: minuterequests_per_unit: 1- key: PATHrate_limit:unit: minuterequests_per_unit: 100
EOFkubectl apply -f ratelimit-config-outside-http.yaml -n istio
说明: 这个configmap是限速服务用到的配置文件,他是envoy v3版本的限速格式。domain是域名,他会在envoyfilter中被引用,descriptors的PATH,表示请求的路径可以有多个值,rate_limit配置限速配额,这里productpage配了1分钟1个请求,/aa一分钟1个请求,其他url是1分钟100个请求
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
创建了redis,和官方的一个ratelimit服务。
cat << EOF > se-baidu.yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:name: baidu
spec:hosts:- www.baidu.comports:- number: 80name: http-portprotocol: HTTPresolution: DNS
EOFkubectl apply -f se-baidu.yaml -n istio
创建访问百度的serviceentry
创建envoy-filter
cat << EOF > envoyfilter-filter-outside-http.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: ratingsconfigPatches:- applyTo: HTTP_FILTERmatch:context: SIDECAR_OUTBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter-outside-http.yaml -n istio
这个envoyfilter作用在ratings上面,SIDECAR_OUTBOUND作用的对外流量上面,配置了一个http过滤器envoy.filters.http.ratelimit,和一个cluster。http 过滤器的cluster地址指向cluster配置的地址,这里就是我们的ratelimit service所在的地址。domain是上面configmap的值一样,failure_mode_deny表示超过请求限值就拒绝,rate_limit_service配置ratelimit服务的地址(cluster),这里可以配置grpc类型的也可以配置http类型的。
4创建action envoyfilter
cat << EOF > envoyfilter-action-outside-http.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: ratingsconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_OUTBOUNDrouteConfiguration:vhost:name: "www.baidu.com:80"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: # any actions in here- request_headers:header_name: ":path"descriptor_key: "PATH"
EOFkubectl apply -f envoyfilter-action-outside-http.yaml -n istio
host是我们配置的百度的地址(www.baidu.com:80),这个envoyfilter作用在ratings处,给80端口的虚拟主机配置了一个rate_limits 动作,descriptor_key用于选择在configmap里配置的key。
kubectl exec -it -n istio ratings-v2-mysql-vm-66dc56449d-lk6gv /bin/bashnode@ratings-v2-mysql-vm-66dc56449d-lk6gv:/opt/microservices$ curl www.baidu.com/ -I
HTTP/1.1 429 Too Many Requests
x-envoy-ratelimited: true
date: Fri, 17 Sep 2021 23:51:33 GMT
server: envoy
transfer-encoding: chunked
进入rating容器,向百度发请求,409错误,说明限流成功
清理:
kubectl delete cm ratelimit-config -n istio
kubectl delete -f ratelimit-deploy.yaml -n istio
kubectl delete envoyfilter filter-ratelimit -n istio
kubectl delete envoyfilter filter-ratelimit-svc -n istio
3.1.1.2多集群
3.1.1.2.1准备集群
这里多集群安装我们不在展开,不懂得可以看我之前的文章。
集群1
128,129,130
集群2
131,132,133两个网络联通
128。129.130
route add -net 172.21.1.0 netmask 255.255.255.0 gw 192.168.229.131
route add -net 172.21.2.0 netmask 255.255.255.0 gw 192.168.229.133
route add -net 172.21.0.0 netmask 255.255.255.0 gw 192.168.229.132
route add -net 10.69.0.0 netmask 255.255.0.0 gw 192.168.229.131131,132,133
route add -net 172.20.0.0 netmask 255.255.255.0 gw 192.168.229.128
route add -net 172.20.1.0 netmask 255.255.255.0 gw 192.168.229.129
route add -net 172.20.2.0 netmask 255.255.255.0 gw 192.168.229.130
route add -net 10.68.0.0 netmask 255.255.0.0 gw 192.168.229.128cluster1:
生成istio安装operator文件
cat <<EOF > cluster1.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:profile: demovalues:global:meshID: mesh1multiCluster:clusterName: cluster1network: network1meshConfig:accessLogFile: /dev/stdoutenableTracing: truecomponents:egressGateways:- name: istio-egressgatewayenabled: true
EOF生成istio安装operator文件
cat <<EOF > cluster2.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:profile: demovalues:global:meshID: mesh1multiCluster:clusterName: cluster2network: network1meshConfig:accessLogFile: /dev/stdoutenableTracing: truecomponents:egressGateways:- name: istio-egressgatewayenabled: true
EOF把部署文件传到cluster2
scp cluster2.yaml root@192.168.229.131:/rootcluster1:
生成访问apiserver secretistioctl x create-remote-secret --name=cluster1 --server=https://192.168.229.128:6443 > remote-secret-cluster1.yaml传输secret到cluster2
scp remote-secret-cluster1.yaml root@192.168.229.131:/rootcluster2
生成访问apiserver secretistioctl x create-remote-secret --name=cluster2 --server=https://192.168.229.131:6443 > remote-secret-cluster2.yaml传输secret到cluster2scp remote-secret-cluster2.yaml root@192.168.229.128:/rootcluster1应用secretkubectl apply -f remote-secret-cluster2.yaml部署集群istioctl install -f cluster1.yamlcluster2:应用secretkubectl apply -f remote-secret-cluster1.yaml部署集群
istioctl install -f cluster2.yamlcluster1: 重启podkubectl rollout restart deploy -n istiokubectl rollout restart deploy -n istio-systemcluster2:重启podkubectl rollout restart deploy -n istiokubectl rollout restart deploy -n istio-system
清理:
cluster1:kubectl delete secret istio-remote-secret-cluster2 -n istio-system
istioctl x uninstall -f cluster1.yamlrebootcluster2:kubectl delete secret istio-remote-secret-cluster1 -n istio-system
istioctl x uninstall -f cluster2.yamlreboot
3.1.1.2.2集群内本地限流
多集群只演示集群内本地限流其他是一样的
cat <<EOF > envoyfilter-local-rate-limit-multi-http.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-local-ratelimit-svc
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: HTTP_FILTERmatch:listener:filterChain:filter:name: "envoy.filters.network.http_connection_manager"patch:operation: INSERT_BEFOREvalue:name: envoy.filters.http.local_ratelimittyped_config:"@type": type.googleapis.com/udpa.type.v1.TypedStructtype_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimitvalue:stat_prefix: http_local_rate_limitertoken_bucket:max_tokens: 10tokens_per_fill: 10fill_interval: 60sfilter_enabled:runtime_key: local_rate_limit_enableddefault_value:numerator: 100denominator: HUNDREDfilter_enforced:runtime_key: local_rate_limit_enforceddefault_value:numerator: 100denominator: HUNDREDresponse_headers_to_add:- append: falseheader:key: x-local-rate-limitvalue: 'true'
EOFkubectl apply -f envoyfilter-local-rate-limit-multi-http.yaml -n istio
说明:本地限流需要通过EnvoyFilter来实现,他不会请求外部服务,在envoy内部实现支持,是一个令牌桶的算法。http filter的名称必须是envoy.filters.http.local_ratelimit,type和typeurl是固定的,stat_prefix可以随便改,表示生成stat的指标前缀。token_bucket配置令牌桶,max_tokens表示最大令牌数量,tokens_per_fill表示每次填充的令牌数量,fill_interval表示填充令牌的间隔。filter_enabled表示启用但不是强制,filter_enforced表示强制,可以配置百分比。response_headers_to_add修改响应头信息,append为false表示修改,true表示添加。runtime_key 运行时的key,具体有啥用不清楚。
开启压测:
[root@node01 45]# go-stress-testing -c 10 -n 10000 -u http://192.168.229.128:30363/productpage开始启动 并发数:10 请求数:10000 请求参数:
request:form:http url:http://192.168.229.128:30363/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 0│ 0│ 0│ 0.00│ 0.00│ 0.00│ 0.00│ │ │2s│ 7│ 16│ 6│ 15.25│ 1453.38│ 4.56│ 655.73│ 71,950│ 35,974│200:16;429:63s│ 7│ 17│ 6│ 14.30│ 1453.38│ 4.56│ 699.44│ 76,133│ 25,376│200:17;429:64s│ 10│ 34│ 24│ 14.30│ 3207.96│ 2.71│ 699.46│ 154,262│ 38,559│200:34;429:245s│ 10│ 78│ 68│ 16.03│ 3207.96│ 2.71│ 623.67│ 370,054│ 74,009│200:78;429:686s│ 10│ 160│ 150│ 26.98│ 3207.96│ 2.71│ 370.66│ 770,420│ 128,402│200:160;429:1507s│ 10│ 238│ 228│ 34.53│ 3207.96│ 2.71│ 289.60│1,148,994│ 164,131│200:238;429:228
发现多集群和单集群的配置是一样,同样生效
3.2.2tcp
3.2.2.1单集群
3.2.2.1.1集群内服务限流
3.2.2.1.1.1本地限流
部署mysql
cat << EOF > mysql.yaml
apiVersion: v1
kind: Secret
metadata:name: mysql-credentials
type: Opaque
data:rootpasswd: cGFzc3dvcmQ=
---
apiVersion: v1
kind: Service
metadata:name: mysqldblabels:app: mysqldbservice: mysqldb
spec:ports:- port: 3306name: tcpselector:app: mysqldb
---
apiVersion: apps/v1
kind: Deployment
metadata:name: mysqldb-v1labels:app: mysqldbversion: v1
spec:replicas: 1selector:matchLabels:app: mysqldbversion: v1template:metadata:labels:app: mysqldbversion: v1spec:containers:- name: mysqldbimage: docker.io/istio/examples-bookinfo-mysqldb:1.16.2imagePullPolicy: IfNotPresentports:- containerPort: 3306env:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-credentialskey: rootpasswdargs: ["--default-authentication-plugin","mysql_native_password"]volumeMounts:- name: var-lib-mysqlmountPath: /var/lib/mysqlvolumes:- name: var-lib-mysqlemptyDir: {}
EOFkubectl apply -f mysql.yaml -n istio
说明:部署了mysql服务,ratings获取数据时会请求这个服务
部署mysql版ratings
cat << EOF > ratings-mysql.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: ratings-v2-mysqllabels:app: ratingsversion: v2-mysql
spec:replicas: 1selector:matchLabels:app: ratingsversion: v2-mysqltemplate:metadata:labels:app: ratingsversion: v2-mysqlspec:containers:- name: ratingsimage: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2imagePullPolicy: IfNotPresentenv:# ratings-v2 will use mongodb as the default db backend.# if you would like to use mysqldb then you can use this file# which sets DB_TYPE = 'mysql' and the rest of the parameters shown# here and also create the # mysqldb service using bookinfo-mysql.yaml# NOTE: This file is mutually exclusive to bookinfo-ratings-v2.yaml- name: DB_TYPEvalue: "mysql"- name: MYSQL_DB_HOSTvalue: mysqldb- name: MYSQL_DB_PORTvalue: "3306"- name: MYSQL_DB_USERvalue: root- name: MYSQL_DB_PASSWORDvalue: passwordports:- containerPort: 9080securityContext:runAsUser: 1000
EOFkubectl apply -f ratings-mysql.yaml -n istio
部署了mysql版的ratings,是指了env变量。
cat <<EOF > envoyfilter-local-rate-limit-mysql-inside.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-local-ratelimit-svc
spec:workloadSelector:labels:app: mysqldbversion: v1configPatches:- applyTo: NETWORK_FILTERmatch:listener:portNumber: 3306filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: INSERT_BEFOREvalue:name: envoy.filters.network.local_ratelimittyped_config:"@type": type.googleapis.com/udpa.type.v1.TypedStructtype_url: type.googleapis.com/envoy.extensions.filters.network.local_ratelimit.v3.LocalRateLimitvalue:stat_prefix: tcp_local_rate_limitertoken_bucket:max_tokens: 1tokens_per_fill: 1fill_interval: 60sruntime_enabled:runtime_key: tcp_rate_limit_enableddefault_value: true
EOFkubectl apply -f envoyfilter-local-rate-limit-mysql-inside.yaml -n istio
注意这里applyTo的是NETWORK_FILTER,因为mysql是tcp服务,不是http服务,filter的名字是envoy.filters.network.local_ratelimit,type_url也是固定的不要写错。token_bucket配置了访问限速的令牌数量及其填充速度。我们设置的filter在envoy.filters.network.tcp_proxy前面,所以是INSERT_BEFORE。
清理:
kubectl delete -f mysql.yaml -n istio
kubectl delete -f ratings-mysql.yaml -n istio
kubectl delete envoyfilter filter-local-ratelimit-svc -n istio
3.2.2.1.1.2全局限流
部署mysql
wechat/envoyfilter/ratelimit/tcp/inner/global/mysql.yaml
cat << EOF > mysql.yaml
apiVersion: v1
kind: Secret
metadata:name: mysql-credentials
type: Opaque
data:rootpasswd: cGFzc3dvcmQ=
---
apiVersion: v1
kind: Service
metadata:name: mysqldblabels:app: mysqldbservice: mysqldb
spec:ports:- port: 3306name: tcpselector:app: mysqldb
---
apiVersion: apps/v1
kind: Deployment
metadata:name: mysqldb-v1labels:app: mysqldbversion: v1
spec:replicas: 1selector:matchLabels:app: mysqldbversion: v1template:metadata:labels:app: mysqldbversion: v1spec:containers:- name: mysqldbimage: docker.io/istio/examples-bookinfo-mysqldb:1.16.2imagePullPolicy: IfNotPresentports:- containerPort: 3306env:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-credentialskey: rootpasswdargs: ["--default-authentication-plugin","mysql_native_password"]volumeMounts:- name: var-lib-mysqlmountPath: /var/lib/mysqlvolumes:- name: var-lib-mysqlemptyDir: {}
EOFkubectl apply -f mysql.yaml -n istio
部署mysql版ratings
cat << EOF > ratings-mysql.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: ratings-v2-mysqllabels:app: ratingsversion: v2-mysql
spec:replicas: 1selector:matchLabels:app: ratingsversion: v2-mysqltemplate:metadata:labels:app: ratingsversion: v2-mysqlspec:containers:- name: ratingsimage: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2imagePullPolicy: IfNotPresentenv:# ratings-v2 will use mongodb as the default db backend.# if you would like to use mysqldb then you can use this file# which sets DB_TYPE = 'mysql' and the rest of the parameters shown# here and also create the # mysqldb service using bookinfo-mysql.yaml# NOTE: This file is mutually exclusive to bookinfo-ratings-v2.yaml- name: DB_TYPEvalue: "mysql"- name: MYSQL_DB_HOSTvalue: mysqldb- name: MYSQL_DB_PORTvalue: "3306"- name: MYSQL_DB_USERvalue: root- name: MYSQL_DB_PASSWORDvalue: passwordports:- containerPort: 9080securityContext:runAsUser: 1000
EOFkubectl apply -f ratings-mysql.yaml -n istio
部署ratelimit
1创建cm
cat << EOF > ratelimit-config-mysql-inside.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: mysql-ratelimitdescriptors:- key: testvalue: "test"rate_limit:unit: minuterequests_per_unit: 1- key: testrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config-mysql-inside.yaml -n istio
说明: 这个configmap是限速服务用到的配置文件,他是envoy v3版本的限速格式。domain是域名,他会在envoyfilter中被引用,descriptors的PATH,表示请求的路径可以有多个值,rate_limit配置限速配额,这里productpage配了1分钟1个请求,其他url是1分钟100个请求
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
创建了redis,和官方的一个ratelimit服务。
3创建envoy-filter
cat << EOF > envoyfilter-filter-mysql-inside.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:labels:app: mysqldbversion: v1configPatches:- applyTo: NETWORK_FILTERmatch:listener:portNumber: 3306filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: INSERT_BEFOREvalue:name: envoy.filters.network.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.ratelimit.v3.RateLimitdomain: mysql-ratelimitfailure_mode_deny: truestat_prefix: mysql_ratelimitdescriptors:- entries:- key: testvalue: testlimit: requests_per_unit: 2unit: MINUTErate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADDvalue:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter-mysql-inside.yaml -n istio
node@ratings-v2-mysql-565f8fd887-8hp9s:/opt/microservices$ curl ratings.istio.svc:9080/ratings/0
{"id":0,"ratings":{"Reviewer1":5,"Reviewer2":4}}node@ratings-v2-mysql-565f8fd887-8hp9s:/opt/microservices$ curl ratings.istio.svc:9080/ratings/0
{"error":"could not connect to ratings database"}node@ratings-v2-mysql-565f8fd887-8hp9s:/opt/microservices$ curl ratings.istio.svc:9080/ratings/0
{"error":"could not connect to ratings database"}node@ratings-v2-mysql-565f8fd887-8hp9s:/opt/microservices$
清理:
kubectl delete -f mysql.yaml -n istio
kubectl delete -f ratings-mysql.yaml -n istio
kubectl delete -f envoyfilter-filter-mysql-inside.yaml -n istio
kubectl delete -f ratelimit-deploy.yaml -n istio
kubectl delete -f ratelimit-config-mysql-inside.yaml -n istio
3.2.2.1.2集群外服务限流
3.2.2.1.2.1本地限流
部署rating-v2
cat << EOF > bookinfo-ratings-v2-mysql-vm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: ratings-v2-mysql-vmlabels:app: ratingsversion: v2-mysql-vm
spec:replicas: 1selector:matchLabels:app: ratingsversion: v2-mysql-vmtemplate:metadata:labels:app: ratingsversion: v2-mysql-vmspec:containers:- name: ratingsimage: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2imagePullPolicy: IfNotPresentenv:# This assumes you registered your mysql vm as# istioctl register -n vm mysqldb 1.2.3.4 3306- name: DB_TYPEvalue: "mysql"- name: MYSQL_DB_HOSTvalue: mysql.vm.demo- name: MYSQL_DB_PORTvalue: "3306"- name: MYSQL_DB_USERvalue: root- name: MYSQL_DB_PASSWORDvalue: rootports:- containerPort: 9080securityContext:runAsUser: 1000
EOFkubectl apply -f bookinfo-ratings-v2-mysql-vm.yaml -n istio
在vm上部署mysql,这个略过,有需要文档的同学,可以加我微信,因为有点复杂
创建serviceentry
cat << EOF > se-mysql.yaml
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:name: mysql-se
spec:hosts:- mysql.vm.demoaddresses:- 192.168.229.12location: MESH_INTERNALports:- number: 3306name: mysqlprotocol: TCPtargetPort: 3306resolution: STATICworkloadSelector:labels:app: mysqltype: vm
EOFkubectl apply -f se-mysql.yaml -n vm
这里创建了一个访问我们部署的虚拟机服务mysql的serviceentry
coredns配置加上解析记录
apiVersion: v1
data:Corefile: |.:53 {errorshealth {lameduck 5s}hosts {192.168.229.11 httpd.vm.demo192.168.229.12 mysql.vm.demofallthrough}readykubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {max_concurrent 1000}cache 30reloadloadbalance}
kind: ConfigMap
添加192.168.229.12 mysql.vm.demo这一段
重启coredns
kubectl rollout restart -n kube-system deployment coredns
执行压测
go-stress-testing -c 1 -n 10000 -u http://192.168.229.134:32688/productpage
[root@node01 ~]# go-stress-testing -c 1 -n 10000 -u http://192.168.229.134:32688/productpage开始启动 并发数:1 请求数:10000 请求参数:
request:form:http url:http://192.168.229.134:32688/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 1│ 18│ 0│ 18.20│ 91.36│ 17.66│ 54.94│ 87,270│ 87,264│200:182s│ 1│ 37│ 0│ 19.11│ 91.40│ 13.13│ 52.34│ 178,723│ 89,351│200:373s│ 1│ 54│ 0│ 18.42│ 97.80│ 13.13│ 54.30│ 260,814│ 86,928│200:544s│ 1│ 72│ 0│ 18.22│ 97.80│ 13.13│ 54.88│ 349,080│ 87,258│200:725s│ 1│ 90│ 0│ 18.17│ 103.04│ 12.98│ 55.04│ 436,350│ 87,264│200:906s│ 1│ 111│ 0│ 18.59│ 103.04│ 12.98│ 53.80│ 538,165│ 89,686│200:1117s│ 1│ 132│ 0│ 18.91│ 103.04│ 12.98│ 52.89│ 638,984│ 91,279│200:1328s│ 1│ 150│ 0│ 18.88│ 103.04│ 12.30│ 52.95│ 727,250│ 90,905│200:150
没有限流之前压测都是200的返回结果
cat <<EOF > envoyfilter-local-rate-limit-mysql-vm-outside.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-local-ratelimit-svc
spec:workloadSelector:labels:app: ratingsconfigPatches:- applyTo: NETWORK_FILTERmatch:context: SIDECAR_OUTBOUNDlistener:portNumber: 3306filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: INSERT_BEFOREvalue:name: envoy.filters.network.local_ratelimittyped_config:"@type": type.googleapis.com/udpa.type.v1.TypedStructtype_url: type.googleapis.com/envoy.extensions.filters.network.local_ratelimit.v3.LocalRateLimitvalue:stat_prefix: tcp_local_rate_limitertoken_bucket:max_tokens: 10tokens_per_fill: 10fill_interval: 60sruntime_enabled:runtime_key: tcp_rate_limit_enableddefault_value: true
EOFkubectl apply -f envoyfilter-local-rate-limit-mysql-vm-outside.yaml -n istio
部署envoyfilter使限流生效,作用在ratings服务上面,而且是出口流量SIDECAR_OUTBOUND,network filter名称必须事envoy.filters.network.local_ratelimit,type _url也是固定的。token_bucket设置令牌桶。
这里无法连接数据库,说明数据库被限流了,ratings无法连接vm mysql服务。
清理:
kubectl delete envoyfilter filter-local-ratelimit-svc -n istio
kubectl delete se mysql-se -n vm
3.2.2.1.2.2全局限流
部署rating-v2
cat << EOF > bookinfo-ratings-v2-mysql-vm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: ratings-v2-mysql-vmlabels:app: ratingsversion: v2-mysql-vm
spec:replicas: 1selector:matchLabels:app: ratingsversion: v2-mysql-vmtemplate:metadata:labels:app: ratingsversion: v2-mysql-vmspec:containers:- name: ratingsimage: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2imagePullPolicy: IfNotPresentenv:# This assumes you registered your mysql vm as# istioctl register -n vm mysqldb 1.2.3.4 3306- name: DB_TYPEvalue: "mysql"- name: MYSQL_DB_HOSTvalue: mysql.vm.demo- name: MYSQL_DB_PORTvalue: "3306"- name: MYSQL_DB_USERvalue: root- name: MYSQL_DB_PASSWORDvalue: rootports:- containerPort: 9080securityContext:runAsUser: 1000
EOFkubectl apply -f bookinfo-ratings-v2-mysql-vm.yaml -n istio
在vm上部署mysql,这个略过,有需要文档的同学,可以加我微信,因为有点复杂
创建serviceentry
cat << EOF > se-mysql.yaml
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:name: mysql-se
spec:hosts:- mysql.vm.demoaddresses:- 192.168.229.12location: MESH_INTERNALports:- number: 3306name: mysqlprotocol: TCPtargetPort: 3306resolution: STATICworkloadSelector:labels:app: mysqltype: vm
EOFkubectl apply -f se-mysql.yaml -n vm
这里创建了一个访问我们部署的虚拟机服务mysql的serviceentry
coredns配置加上解析记录
apiVersion: v1
data:Corefile: |.:53 {errorshealth {lameduck 5s}hosts {192.168.229.11 httpd.vm.demo192.168.229.12 mysql.vm.demofallthrough}readykubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpattl 30}prometheus :9153forward . /etc/resolv.conf {max_concurrent 1000}cache 30reloadloadbalance}
kind: ConfigMap
添加192.168.229.12 mysql.vm.demo这一段
重启coredns
kubectl rollout restart -n kube-system deployment coredns
执行压测
go-stress-testing -c 1 -n 10000 -u http://192.168.229.134:32688/productpage
[root@node01 ~]# go-stress-testing -c 1 -n 10000 -u http://192.168.229.134:32688/productpage开始启动 并发数:1 请求数:10000 请求参数:
request:form:http url:http://192.168.229.134:32688/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 1│ 18│ 0│ 18.20│ 91.36│ 17.66│ 54.94│ 87,270│ 87,264│200:182s│ 1│ 37│ 0│ 19.11│ 91.40│ 13.13│ 52.34│ 178,723│ 89,351│200:373s│ 1│ 54│ 0│ 18.42│ 97.80│ 13.13│ 54.30│ 260,814│ 86,928│200:544s│ 1│ 72│ 0│ 18.22│ 97.80│ 13.13│ 54.88│ 349,080│ 87,258│200:725s│ 1│ 90│ 0│ 18.17│ 103.04│ 12.98│ 55.04│ 436,350│ 87,264│200:906s│ 1│ 111│ 0│ 18.59│ 103.04│ 12.98│ 53.80│ 538,165│ 89,686│200:1117s│ 1│ 132│ 0│ 18.91│ 103.04│ 12.98│ 52.89│ 638,984│ 91,279│200:1328s│ 1│ 150│ 0│ 18.88│ 103.04│ 12.30│ 52.95│ 727,250│ 90,905│200:150
没有限流之前压测都是200的返回结果
cat << EOF > envoyfilter-filter-mysql-outside.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:labels:app: ratingsconfigPatches:- applyTo: NETWORK_FILTERmatch:context: SIDECAR_OUTBOUNDlistener:portNumber: 3306filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: INSERT_BEFOREvalue:name: envoy.filters.network.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.ratelimit.v3.RateLimitdomain: mysql-ratelimitfailure_mode_deny: truestat_prefix: mysql_ratelimitdescriptors:- entries:- key: testvalue: testlimit: requests_per_unit: 2unit: MINUTErate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADDvalue:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter-mysql-outside.yaml -n istio
清理
kubectl delete envoyfilter filter-local-ratelimit-svc -n istio
kubectl delete se mysql-se -n vm
3.2.2.2多集群
3.2.2.2.1集群准备
同上
3.2.2.2.2集群内本地限流
cluster1,cluster2部署mysql
cat << EOF > mysql.yaml
apiVersion: v1
kind: Secret
metadata:name: mysql-credentials
type: Opaque
data:rootpasswd: cGFzc3dvcmQ=
---
apiVersion: v1
kind: Service
metadata:name: mysqldblabels:app: mysqldbservice: mysqldb
spec:ports:- port: 3306name: tcpselector:app: mysqldb
---
apiVersion: apps/v1
kind: Deployment
metadata:name: mysqldb-v1labels:app: mysqldbversion: v1
spec:replicas: 1selector:matchLabels:app: mysqldbversion: v1template:metadata:labels:app: mysqldbversion: v1spec:containers:- name: mysqldbimage: docker.io/istio/examples-bookinfo-mysqldb:1.16.2imagePullPolicy: IfNotPresentports:- containerPort: 3306env:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-credentialskey: rootpasswdargs: ["--default-authentication-plugin","mysql_native_password"]volumeMounts:- name: var-lib-mysqlmountPath: /var/lib/mysqlvolumes:- name: var-lib-mysqlemptyDir: {}
EOFkubectl apply -f mysql.yaml -n istio
说明:部署了mysql服务,ratings获取数据时会请求这个服务
cluster1,cluster2部署mysql版ratings
cat << EOF > ratings-mysql.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: ratings-v2-mysqllabels:app: ratingsversion: v2-mysql
spec:replicas: 1selector:matchLabels:app: ratingsversion: v2-mysqltemplate:metadata:labels:app: ratingsversion: v2-mysqlspec:containers:- name: ratingsimage: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2imagePullPolicy: IfNotPresentenv:# ratings-v2 will use mongodb as the default db backend.# if you would like to use mysqldb then you can use this file# which sets DB_TYPE = 'mysql' and the rest of the parameters shown# here and also create the # mysqldb service using bookinfo-mysql.yaml# NOTE: This file is mutually exclusive to bookinfo-ratings-v2.yaml- name: DB_TYPEvalue: "mysql"- name: MYSQL_DB_HOSTvalue: mysqldb- name: MYSQL_DB_PORTvalue: "3306"- name: MYSQL_DB_USERvalue: root- name: MYSQL_DB_PASSWORDvalue: passwordports:- containerPort: 9080securityContext:runAsUser: 1000
EOFkubectl apply -f ratings-mysql.yaml -n istio
部署了mysql版的ratings,是指了env变量。
cat <<EOF > envoyfilter-local-rate-limit-mysql-inside.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-local-ratelimit-svc
spec:workloadSelector:labels:app: mysqldbversion: v1configPatches:- applyTo: NETWORK_FILTERmatch:listener:portNumber: 3306filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: INSERT_BEFOREvalue:name: envoy.filters.network.local_ratelimittyped_config:"@type": type.googleapis.com/udpa.type.v1.TypedStructtype_url: type.googleapis.com/envoy.extensions.filters.network.local_ratelimit.v3.LocalRateLimitvalue:stat_prefix: tcp_local_rate_limitertoken_bucket:max_tokens: 1tokens_per_fill: 1fill_interval: 60sruntime_enabled:runtime_key: tcp_rate_limit_enableddefault_value: true
EOFcluster1,cluster2:
kubectl apply -f envoyfilter-local-rate-limit-mysql-inside.yaml -n istio
注意这里applyTo的是NETWORK_FILTER,因为mysql是tcp服务,不是http服务,filter的名字是envoy.filters.network.local_ratelimit,type_url也是固定的不要写错。token_bucket配置了访问限速的令牌数量及其填充速度。我们设置的filter在envoy.filters.network.tcp_proxy前面,所以是INSERT_BEFORE。
多集群集群内本地限流,需要在每个istiod里面增加ratelimit配置
清理:
kubectl delete envoyfilter filter-local-ratelimit-svc -n istio
3.3不同限流动作
3.3.1source_cluster
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: source_clustervalue: "outbound|80||istio-ingressgateway.istio-system.svc.cluster.local"rate_limit:unit: minuterequests_per_unit: 1- key: source_clusterrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - source_cluster: {}
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 10│ 741│ 10.06│ 164.41│ 5.07│ 994.21│ 48,814│ 48,793│200:10;429:739;500:22s│ 10│ 10│ 1644│ 5.02│ 164.41│ 5.07│ 1992.68│ 48,814│ 24,403│200:10;429:1642;500:23s│ 10│ 10│ 2486│ 3.34│ 164.41│ 4.99│ 2989.70│ 48,814│ 16,268│200:10;429:2484;500:24s│ 10│ 10│ 3332│ 2.51│ 164.41│ 4.94│ 3989.95│ 48,814│ 12,203│200:10;429:3330;500:25s│ 10│ 10│ 4213│ 2.00│ 164.41│ 4.61│ 4988.90│ 48,814│ 9,762│200:10;429:4207;500:6
3.3.2destination_cluster
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: destination_clustervalue: "inbound|9080||"rate_limit:unit: minuterequests_per_unit: 1- key: destination_clusterrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - destination_cluster: {}
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 1│ 799│ 1.01│ 38.49│ 5.84│ 9904.46│ 4,183│ 4,182│200:1;429:7992s│ 10│ 1│ 1703│ 0.50│ 38.49│ 5.31│19918.49│ 4,183│ 2,090│200:1;429:17033s│ 10│ 1│ 2553│ 0.33│ 38.49│ 4.88│29894.78│ 4,183│ 1,394│200:1;429:25534s│ 10│ 1│ 3452│ 0.25│ 38.49│ 4.88│39907.66│ 4,183│ 1,045│200:1;429:34525s│ 10│ 1│ 4339│ 0.20│ 38.49│ 4.26│49863.27│ 4,183│ 836│200:1;429:43396s│ 10│ 1│ 5130│ 0.17│ 38.49│ 4.26│59819.79│ 4,183│ 697│200:1;429:51307s│ 10│ 1│ 5945│ 0.14│ 38.49│ 4.26│69888.47│ 4,183│ 597│200:1;429:59458s│ 10│ 1│ 6773│ 0.13│ 38.49│ 4.26│79848.79│ 4,183│ 522│200:1;429:6772;500:1
3.3.3request_headers
略
3.3.4remote_address
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: remote_addressvalue: "172.20.1.0"rate_limit:unit: minuterequests_per_unit: 1- key: remote_addressrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - remote_address: {}
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 1│ 825│ 1.01│ 58.24│ 4.89│ 9914.57│ 4,183│ 4,181│200:1;429:8252s│ 10│ 1│ 1652│ 0.50│ 58.24│ 4.89│19930.21│ 4,183│ 2,091│200:1;429:16523s│ 10│ 1│ 2565│ 0.33│ 58.24│ 4.89│29894.37│ 4,183│ 1,394│200:1;429:25654s│ 10│ 1│ 3433│ 0.25│ 58.24│ 4.76│39857.25│ 4,183│ 1,045│200:1;429:34335s│ 10│ 1│ 4176│ 0.20│ 58.24│ 4.76│49888.21│ 4,183│ 836│200:1;429:4176
3.3.5generic_key
{"descriptor_value": "...","descriptor_key": "..."
}
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: testvalue: "test"rate_limit:unit: minuterequests_per_unit: 2- key: testrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - generic_key:descriptor_key: testdescriptor_value: test
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 0│ 789│ 0.00│ 27.99│ 5.37│ 0.00│ │ │429:7892s│ 10│ 0│ 1624│ 0.00│ 27.99│ 4.61│ 0.00│ │ │429:16243s│ 10│ 0│ 2492│ 0.00│ 27.99│ 4.61│ 0.00│ │ │429:24924s│ 10│ 0│ 3335│ 0.00│ 27.99│ 4.21│ 0.00│ │ │429:33355s│ 10│ 0│ 4181│ 0.00│ 27.99│ 4.21│ 0.00│ │ │429:41816s│ 10│ 0│ 5026│ 0.00│ 27.99│ 4.21│ 0.00│ │ │429:50267s│ 10│ 0│ 5842│ 0.00│ 27.99│ 4.21│ 0.00│ │ │429:58428s│ 10│ 0│ 6721│ 0.00│ 27.99│ 4.21│ 0.00│ │ │429:67219s│ 10│ 2│ 7586│ 0.22│ 95.85│ 4.21│44910.75│ 10,362│ 1,151│200:2;429:758610s│ 10│ 2│ 8444│ 0.20│ 95.85│ 4.21│49900.13│ 10,362│ 1,036│200:2;429:8441;500:311s│ 10│ 2│ 9295│ 0.18│ 95.85│ 4.21│54893.06│ 10,362│ 941│200:2;429:9292;500:312s│ 10│ 2│ 10083│ 0.17│ 95.85│ 4.21│59903.03│ 10,362│ 863│200:2;429:10080;500:313s│ 10│ 2│ 10889│ 0.15│ 95.85│ 4.21│64892.42│ 10,362│ 797│200:2;429:10886;500:314s│ 10│ 2│ 11383│ 0.14│ 95.85│ 4.21│69829.26│ 10,362│ 740│200:2;429:11380;500:3
3.3.6header_value_match
{"descriptor_value": "...","expect_match": "{...}","headers": []
}
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: header_matchvalue: "test"rate_limit:unit: minuterequests_per_unit: 3- key: header_matchrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - header_value_match:descriptor_value: testexpect_match: trueheaders:- name: testexact_match: test
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage -H "test:test"开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[test:test] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 0│ 551│ 0.00│ 46.14│ 4.79│ 0.00│ │ │429:5512s│ 10│ 0│ 1058│ 0.00│ 46.14│ 4.79│ 0.00│ │ │429:10583s│ 10│ 3│ 1505│ 1.01│ 93.00│ 4.79│ 9918.12│ 14,545│ 4,847│200:3;429:15054s│ 10│ 3│ 1996│ 0.75│ 93.00│ 4.79│13286.69│ 14,545│ 3,635│200:3;429:19965s│ 10│ 3│ 2491│ 0.60│ 93.00│ 4.79│16616.88│ 14,545│ 2,908│200:3;429:24916s│ 10│ 3│ 2962│ 0.50│ 93.00│ 4.79│19942.64│ 14,545│ 2,423│200:3;429:29627s│ 10│ 3│ 3481│ 0.43│ 93.00│ 4.79│23293.64│ 14,545│ 2,077│200:3;429:3481
3.3.7dynamic_metadata
已废弃
3.3.8metadata
{"descriptor_key": "...","metadata_key": "{...}","default_value": "...","source": "..."
}
source:
DYNAMIC
(DEFAULT) Query dynamic metadata
ROUTE_ENTRY
Query route entry metadata
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: testvalue: "test"rate_limit:unit: minuterequests_per_unit: 4- key: testrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - metadata:descriptor_key: testmetadata_key:key: envoy.xxxpath:- key: prop- key: foodefault_value: testsource: DYNAMIC
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 0│ 852│ 0.00│ 26.01│ 4.44│ 0.00│ │ │429:8522s│ 10│ 0│ 1766│ 0.00│ 26.04│ 4.44│ 0.00│ │ │429:17663s│ 10│ 4│ 2634│ 1.34│ 88.00│ 4.44│ 7470.19│ 18,732│ 6,243│200:4;429:26344s│ 10│ 4│ 3507│ 1.00│ 88.00│ 4.44│ 9973.41│ 18,732│ 4,682│200:4;429:35075s│ 10│ 4│ 4005│ 0.80│ 88.00│ 4.44│12454.99│ 18,732│ 3,745│200:4;429:40056s│ 10│ 4│ 4496│ 0.67│ 88.00│ 4.44│14932.15│ 18,732│ 3,121│200:4;429:4496
3.3.9extension
extensions.rate_limit_descriptors.expr.v3.Descriptor
{"descriptor_key": "...","skip_if_error": "...","text": "...","parsed": "{...}"
}
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: testvalue: "outbound_.9080_._.productpage.istio.svc.cluster.local"rate_limit:unit: minuterequests_per_unit: 4- key: testrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - extension:name: envoy.rate_limit_descriptors.exprtyped_config:"@type": type.googleapis.com/envoy.extensions.rate_limit_descriptors.expr.v3.Descriptordescriptor_key: testskip_if_error: truetext: "connection.requested_server_name"
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 0│ 850│ 0.00│ 28.69│ 3.87│ 0.00│ │ │429:8502s│ 10│ 0│ 1688│ 0.00│ 32.26│ 3.87│ 0.00│ │ │429:16883s│ 10│ 0│ 2593│ 0.00│ 32.26│ 3.87│ 0.00│ │ │429:25934s│ 10│ 4│ 3443│ 1.00│ 97.18│ 3.87│ 9975.97│ 19,724│ 4,930│200:4;429:3440;500:35s│ 10│ 4│ 4005│ 0.80│ 97.18│ 3.87│12431.83│ 19,724│ 3,944│200:4;429:4002;500:36s│ 10│ 4│ 4464│ 0.67│ 97.18│ 3.87│14930.66│ 19,724│ 3,287│200:4;429:4461;500:37s│ 10│ 4│ 4962│ 0.57│ 97.18│ 3.87│17428.69│ 19,724│ 2,817│200:4;429:4959;500:38s│ 10│ 4│ 5477│ 0.50│ 97.18│ 3.87│19941.18│ 19,724│ 2,464│200:4;429:5474;500:3
3.4按请求类型限流
3.4.1internal
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: header_matchvalue: "test"rate_limit:unit: minuterequests_per_unit: 3- key: header_matchrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerequest_type: internaltimeout: 20msrate_limited_as_resource_exhausted: trueenable_x_ratelimit_headers: DRAFT_VERSION_03disable_x_envoy_ratelimited_header: falserate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - header_value_match:descriptor_value: testexpect_match: trueheaders:- name: testexact_match: test
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage -H "test:test"开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[test:test] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 0│ 402│ 0.00│ 58.08│ 8.42│ 0.00│ │ │429:4022s│ 10│ 0│ 838│ 0.00│ 58.21│ 7.16│ 0.00│ │ │429:8383s│ 10│ 0│ 1345│ 0.00│ 58.21│ 7.16│ 0.00│ │ │429:13454s│ 10│ 0│ 1813│ 0.00│ 58.21│ 6.42│ 0.00│ │ │429:18135s│ 10│ 3│ 2284│ 0.60│ 94.15│ 6.42│16583.06│ 14,545│ 2,908│200:3;429:22846s│ 10│ 3│ 2750│ 0.50│ 94.15│ 6.42│19914.90│ 14,545│ 2,424│200:3;429:27507s│ 10│ 3│ 3189│ 0.43│ 94.15│ 6.42│23246.60│ 14,545│ 2,077│200:3;429:31898s│ 10│ 3│ 3616│ 0.38│ 94.15│ 6.42│26548.82│ 14,545│ 1,817│200:3;429:3616
3.4.2external
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: header_matchvalue: "test"rate_limit:unit: minuterequests_per_unit: 3- key: header_matchrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerequest_type: externaltimeout: 20msrate_limited_as_resource_exhausted: trueenable_x_ratelimit_headers: DRAFT_VERSION_03disable_x_envoy_ratelimited_header: falserate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - header_value_match:descriptor_value: testexpect_match: trueheaders:- name: testexact_match: test
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage -H "test:test"开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[test:test] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 94│ 0│ 98.74│ 150.75│ 32.92│ 101.27│ 455,078│ 454,974│200:942s│ 10│ 191│ 0│ 97.52│ 189.63│ 32.92│ 102.55│ 925,701│ 462,829│200:1913s│ 10│ 288│ 0│ 98.58│ 189.63│ 32.92│ 101.44│1,396,320│ 465,432│200:2884s│ 10│ 390│ 0│ 99.04│ 189.63│ 32.92│ 100.97│1,890,850│ 472,669│200:390
因为请求是内部的,所以这里没有ratelimit
3.4.3both
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: header_matchvalue: "test"rate_limit:unit: minuterequests_per_unit: 3- key: header_matchrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitfailure_mode_deny: truerequest_type: bothtimeout: 20msrate_limited_as_resource_exhausted: trueenable_x_ratelimit_headers: DRAFT_VERSION_03disable_x_envoy_ratelimited_header: falserate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - header_value_match:descriptor_value: testexpect_match: trueheaders:- name: testexact_match: test
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage -H "test:test"开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[test:test] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 0│ 832│ 0.00│ 30.45│ 4.18│ 0.00│ │ │429:8322s│ 10│ 0│ 1621│ 0.00│ 30.45│ 4.18│ 0.00│ │ │429:16213s│ 10│ 0│ 2398│ 0.00│ 30.45│ 4.18│ 0.00│ │ │429:23984s│ 10│ 0│ 3188│ 0.00│ 30.45│ 3.86│ 0.00│ │ │429:3179;500:95s│ 10│ 0│ 4087│ 0.00│ 30.45│ 3.86│ 0.00│ │ │429:4078;500:96s│ 10│ 3│ 4961│ 0.50│ 87.15│ 3.86│19948.44│ 14,545│ 2,424│200:3;429:4952;500:97s│ 10│ 3│ 5843│ 0.43│ 87.15│ 3.86│23253.71│ 14,545│ 2,077│200:3;429:5834;500:98s│ 10│ 3│ 6673│ 0.38│ 87.15│ 3.86│26606.37│ 14,545│ 1,818│200:3;429:6664;500:9
3.5stage
部署ratelimit
1创建cm
cat << EOF > ratelimit-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: ratelimit-config
data:config.yaml: |domain: productpage-ratelimitdescriptors:- key: remote_addressvalue: "172.20.1.0"rate_limit:unit: minuterequests_per_unit: 1- key: remote_addressrate_limit:unit: minuterequests_per_unit: 10
EOFkubectl apply -f ratelimit-config.yaml -n istio
2创建限速服务deployment
cat << EOF > ratelimit-deploy.yaml
apiVersion: v1
kind: Service
metadata:name: redislabels:app: redis
spec:ports:- name: redisport: 6379selector:app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- image: redis:alpineimagePullPolicy: Alwaysname: redisports:- name: rediscontainerPort: 6379restartPolicy: AlwaysserviceAccountName: ""
---
apiVersion: v1
kind: Service
metadata:name: ratelimitlabels:app: ratelimit
spec:ports:- name: http-portport: 8080targetPort: 8080protocol: TCP- name: grpc-portport: 8081targetPort: 8081protocol: TCP- name: http-debugport: 6070targetPort: 6070protocol: TCPselector:app: ratelimit
---
apiVersion: apps/v1
kind: Deployment
metadata:name: ratelimit
spec:replicas: 1selector:matchLabels:app: ratelimitstrategy:type: Recreatetemplate:metadata:labels:app: ratelimitspec:containers:- image: envoyproxy/ratelimit:6f5de117 # 2021/01/08imagePullPolicy: Alwaysname: ratelimitcommand: ["/bin/ratelimit"]env:- name: LOG_LEVELvalue: debug- name: REDIS_SOCKET_TYPEvalue: tcp- name: REDIS_URLvalue: redis:6379- name: USE_STATSDvalue: "false"- name: RUNTIME_ROOTvalue: /data- name: RUNTIME_SUBDIRECTORYvalue: ratelimitports:- containerPort: 8080- containerPort: 8081- containerPort: 6070volumeMounts:- name: config-volumemountPath: /data/ratelimit/config/config.yamlsubPath: config.yamlvolumes:- name: config-volumeconfigMap:name: ratelimit-config
EOFkubectl apply -f ratelimit-deploy.yaml -n istio
3创建envoy-filter
cat << EOF > envoyfilter-filter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimitnamespace: istio
spec:workloadSelector:# select by label in the same namespacelabels:app: productpageconfigPatches:# The Envoy config you want to modify- applyTo: HTTP_FILTERmatch:context: SIDECAR_INBOUNDlistener: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.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit# domain can be anything! Match it to the ratelimter service configdomain: productpage-ratelimitstage: 1failure_mode_deny: truerate_limit_service:grpc_service:envoy_grpc:cluster_name: rate_limit_clustertimeout: 10stransport_api_version: V3- applyTo: CLUSTERmatch:cluster:service: ratelimit.istio.svc.cluster.localpatch:operation: ADD# Adds the rate limit service cluster for rate limit service defined in step 1.value:name: rate_limit_clustertype: STRICT_DNSconnect_timeout: 10slb_policy: ROUND_ROBINhttp2_protocol_options: {}load_assignment:cluster_name: rate_limit_clusterendpoints:- lb_endpoints:- endpoint:address:socket_address:address: ratelimit.istio.svc.cluster.localport_value: 8081
EOFkubectl apply -f envoyfilter-filter.yaml -n istio
4创建action envoyfilter
cat << EOF > envoyfilter-action.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: filter-ratelimit-svcnamespace: istio
spec:workloadSelector:labels:app: productpageconfigPatches:- applyTo: VIRTUAL_HOSTmatch:context: SIDECAR_INBOUNDrouteConfiguration:vhost:name: "inbound|http|9080"route:action: ANYpatch:operation: MERGE# Applies the rate limit rules.value:rate_limits:- actions: - remote_address: {}stage: 1disable_key: testlimit:dynamic_metadata: metadata_key:key: envoy.xxxpath:- key: prop- key: foo
EOFkubectl apply -f envoyfilter-action.yaml -n istio
[root@node01 ~]# go-stress-testing -n 1000000 -c 10 -u http://192.168.229.135:32688/productpage开始启动 并发数:10 请求数:1000000 请求参数:
request:form:http url:http://192.168.229.135:32688/productpage method:GET headers:map[] data: verify:statusCode timeout:30s debug:false ─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────┬────────┬────────耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时│最短耗时│平均耗时│下载字节│字节每秒│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────┼────────┼────────1s│ 10│ 1│ 835│ 1.01│ 44.86│ 5.45│ 9941.10│ 4,183│ 4,182│200:1;429:815;500:202s│ 10│ 1│ 1711│ 0.50│ 44.86│ 4.96│19839.11│ 4,183│ 2,091│200:1;429:1688;500:233s│ 10│ 1│ 2465│ 0.33│ 44.86│ 4.96│29876.69│ 4,183│ 1,393│200:1;429:2442;500:234s│ 10│ 1│ 3007│ 0.25│ 66.38│ 4.96│39852.79│ 4,183│ 1,045│200:1;429:2984;500:235s│ 10│ 1│ 3852│ 0.20│ 66.38│ 4.55│49888.50│ 4,183│ 836│200:1;429:3829;500:236s│ 10│ 1│ 4733│ 0.17│ 66.38│ 4.55│59809.06│ 4,183│ 696│200:1;429:4710;500:237s│ 10│ 1│ 5581│ 0.14│ 66.38│ 4.55│69770.80│ 4,183│ 597│200:1;429:5558;500:238s│ 10│ 1│ 6497│ 0.13│ 66.38│ 4.55│79826.00│ 4,183│ 522│200:1;429:6474;500:239s│ 10│ 1│ 7407│ 0.11│ 66.38│ 4.55│89840.05│ 4,183│ 464│200:1;429:7384;500:2310s│ 10│ 1│ 8271│ 0.10│ 66.38│ 4.55│99801.86│ 4,183│ 418│200:1;429:8248;500:23
4清理
kubectl delete cm ratelimit-config -n istio
kubectl delete -f ratelimit-deploy.yaml -n istio
kubectl delete envoyfilter filter-ratelimit -n istio
kubectl delete envoyfilter filter-ratelimit-svc -n istio
不懂envoyfilter也敢说精通istio系列-ratelimit-istio ratelimit完全手册相关推荐
- 精通Zookeeper系列开篇:进大厂不得不学的分布式协同利器!
最近,有很多小伙伴让我更新一些Zookeeper的文章,正好也趁着清明假期把之前自己工作过程当中总结的Zookeeper知识点梳理了一番,打算写一个[精通Zookeeper系列],希望能够帮助小伙伴们 ...
- .ne中的控制器循环出来的数据如何显示在视图上_让不懂编程的人爱上iPhone开发系列2 iOS12+Swift4.2版-Checklists-16...
让不懂编程的人爱上iPhone开发系列2 iOS12+Swift4.2版-Checklists-16 添加导航栏按钮 说明: 本系列教程改编自raywenderlich.com中的iOS Appren ...
- 深度解析Istio系列之策略与遥测篇
注:以下讲述的案例环境场景是基于Kubernetes环境基础上部署的istio环境. 涉及到的Pilot和Envoy的了解请参考深度解析Istio系列之流量控制篇,本文重点在于介绍Mixer. Mix ...
- 火云开发课堂 - 《Shader从入门到精通》系列 第九节:在Shader中实现马赛克滤镜
<Shader从入门到精通>系列在线课程 第九节:在Shader中实现马赛克滤镜 视频地址: http://edu.csdn.net/course/detail/1441/22673?au ...
- gawk linux,精通awk系列(1):安装新版本的gawk
本文将要为您介绍的是精通awk系列(1):安装新版本的gawk,教程操作方法: 回到: Linux系列文章 Shell系列文章 Awk系列文章 安装新版本gawk awk有很多种版本,例如nawk.g ...
- linux条件语句awk,精通awk系列(18):awk流程控制之if、while、switch、for语句
回到: Linux系列文章 Shell系列文章 Awk系列文章 流程控制语句 注:awk中语句块没有作用域,都是全局变量. if (condition) statement [ else statem ...
- 火云开发课堂 - 《Shader从入门到精通》系列 第六节:在Shader中使用纹理动画
<Shader从入门到精通>系列在线课程 第六节:在Shader中使用纹理动画 视频地址:http://edu.csdn.net/course/detail/1441/22670?auto ...
- 火云开发课堂 - 《Shader从入门到精通》系列 第十六节:在Shader中对3D模型使用纹理
<Shader从入门到精通>系列在线课程 优惠链接:http://edu.csdn.net/combo/detail/90 第十一节:在Shader中对3D模型使用纹理 视频地址: htt ...
- 火云开发课堂 - 《Shader从入门到精通》系列 第二十节:在Shader中对3D模型进行多纹理混合
<Shader从入门到精通>系列在线课程 优惠链接:http://edu.csdn.net/combo/detail/90 第二十节:在Shader中对3D模型进行多纹理混合 视频地址: ...
最新文章
- nuget打包文件丢失如何使用powershell脚本解决
- Java继承的概念与实现
- java 策略模式会员_七:策略模式(不同等级会员打折算法)
- Linux下mysql主从配置
- 请简单解释一下ARP协议和ARP攻击
- HTML+CSS实现旋转太极图动态效果
- L3-002 堆栈 树状数组+二分答案
- 推文科技:AI解决方案助力内容出海
- 怎么把ppt弄成链接的形式_视频引流的方法,教你怎么用视频引流日引500
- 物理内存充足,但是为什么用代码总申请不到内存呢?
- 加密设备攻防(二)- 智能设备篇
- Corona Enterprise 引入第三方 jar 包
- 【eoeAndroid社区索引】Android控件知识汇总
- java font 字体 隶书_font-style字体设置
- 获取Android设备的序列号(SN号)
- 大秦帝国-《治秦九论》
- 《阿特拉斯耸耸肩》节选:互害与甩锅的反敏捷组织
- 手把手QQ机器人制作教程,根据官方接口进行开发,基于Python语言制作的详细教程(更新中)
- 简单 sql 语句 实用大全
- 基于STM32的ESP8266模块控制多路继电器