欢迎关注我的公众号:

目前刚开始写一个月,一共写了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完全手册相关推荐

  1. 精通Zookeeper系列开篇:进大厂不得不学的分布式协同利器!

    最近,有很多小伙伴让我更新一些Zookeeper的文章,正好也趁着清明假期把之前自己工作过程当中总结的Zookeeper知识点梳理了一番,打算写一个[精通Zookeeper系列],希望能够帮助小伙伴们 ...

  2. .ne中的控制器循环出来的数据如何显示在视图上_让不懂编程的人爱上iPhone开发系列2 iOS12+Swift4.2版-Checklists-16...

    让不懂编程的人爱上iPhone开发系列2 iOS12+Swift4.2版-Checklists-16 添加导航栏按钮 说明: 本系列教程改编自raywenderlich.com中的iOS Appren ...

  3. 深度解析Istio系列之策略与遥测篇

    注:以下讲述的案例环境场景是基于Kubernetes环境基础上部署的istio环境. 涉及到的Pilot和Envoy的了解请参考深度解析Istio系列之流量控制篇,本文重点在于介绍Mixer. Mix ...

  4. 火云开发课堂 - 《Shader从入门到精通》系列 第九节:在Shader中实现马赛克滤镜

    <Shader从入门到精通>系列在线课程 第九节:在Shader中实现马赛克滤镜 视频地址: http://edu.csdn.net/course/detail/1441/22673?au ...

  5. gawk linux,精通awk系列(1):安装新版本的gawk

    本文将要为您介绍的是精通awk系列(1):安装新版本的gawk,教程操作方法: 回到: Linux系列文章 Shell系列文章 Awk系列文章 安装新版本gawk awk有很多种版本,例如nawk.g ...

  6. linux条件语句awk,精通awk系列(18):awk流程控制之if、while、switch、for语句

    回到: Linux系列文章 Shell系列文章 Awk系列文章 流程控制语句 注:awk中语句块没有作用域,都是全局变量. if (condition) statement [ else statem ...

  7. 火云开发课堂 - 《Shader从入门到精通》系列 第六节:在Shader中使用纹理动画

    <Shader从入门到精通>系列在线课程 第六节:在Shader中使用纹理动画 视频地址:http://edu.csdn.net/course/detail/1441/22670?auto ...

  8. 火云开发课堂 - 《Shader从入门到精通》系列 第十六节:在Shader中对3D模型使用纹理

    <Shader从入门到精通>系列在线课程 优惠链接:http://edu.csdn.net/combo/detail/90 第十一节:在Shader中对3D模型使用纹理 视频地址: htt ...

  9. 火云开发课堂 - 《Shader从入门到精通》系列 第二十节:在Shader中对3D模型进行多纹理混合

    <Shader从入门到精通>系列在线课程 优惠链接:http://edu.csdn.net/combo/detail/90 第二十节:在Shader中对3D模型进行多纹理混合 视频地址:  ...

最新文章

  1. nuget打包文件丢失如何使用powershell脚本解决
  2. Java继承的概念与实现
  3. java 策略模式会员_七:策略模式(不同等级会员打折算法)
  4. Linux下mysql主从配置
  5. 请简单解释一下ARP协议和ARP攻击
  6. HTML+CSS实现旋转太极图动态效果
  7. L3-002 堆栈 树状数组+二分答案
  8. 推文科技:AI解决方案助力内容出海
  9. 怎么把ppt弄成链接的形式_视频引流的方法,教你怎么用视频引流日引500
  10. 物理内存充足,但是为什么用代码总申请不到内存呢?
  11. 加密设备攻防(二)- 智能设备篇
  12. Corona Enterprise 引入第三方 jar 包
  13. 【eoeAndroid社区索引】Android控件知识汇总
  14. java font 字体 隶书_font-style字体设置
  15. 获取Android设备的序列号(SN号)
  16. 大秦帝国-《治秦九论》
  17. 《阿特拉斯耸耸肩》节选:互害与甩锅的反敏捷组织
  18. 手把手QQ机器人制作教程,根据官方接口进行开发,基于Python语言制作的详细教程(更新中)
  19. 简单 sql 语句 实用大全
  20. 基于STM32的ESP8266模块控制多路继电器

热门文章

  1. getsockopt、setsocketopt、ioctlsocket和WSAIoctl 详解
  2. 关于Alphago zero,是的,我来跟风了
  3. 家用计算机的普及英语作文,优秀高二英语作文:计算机
  4. python制作图像数据集_详细图像数据集增强原理的python代码
  5. Java实验之接口与实现、内部类与异常类
  6. 计算机OSI七层参考模型
  7. matlab 产生每次都一样的随机数
  8. chart.js 参数说明
  9. Flink 检测一段时间内的温度连续上升输出报警
  10. STM32H7 CANFD