RL(服务限流)--Istio访问日志ResponseFlag重现与解析14


KubeCon 2023在上海做的一个关于Istio访问日志的演讲《Detailed Parse and Reproduce Response Flags of Istio Access Log Based on Production Use Case》。解析和重现了在当时解决客户问题时碰到的各种应答日志。

第14个关注的Response Flag还是RL,全称是RateLimited,官方定义表示The request was ratelimited locally by the HTTP rate limit filter in addition to 429 response code. 不同于前一个RL的重现了服务端限流,本文将聚焦基于客户端限流重现RL。

含义:

**RL **表示触发服务限流。限流是保障服务韧性的重要手段,防止系统过载,保障服务总体的可用性。在网格中配置了本地限流或者全局限流策略,若在单位时间内请求数超过配置的阈值,则触发限流。访问日志记录RL,一般会伴随返回“429”的HTTP状态码。

RL服务访问

重现环境:

  • 客户端Pod,注入了Sidecar。
  • 目标服务,一个Cluster类型的Kubernetes服务,多个服务实例。服务端Pod注入Siecar。

重现步骤:

第一步: 从注入了网格代理的客户端Pod中通过目标名和服务端口访问目标服务,观察代理的访问日志,得到正常的200响应码。从服务端和客户端的访问日志上都可以看到服务在目标服务的多个实例上负载均衡。正常访问参照本系列的环境部分描述

第二步:上一个限流重现类似,在原有正常访问的环境基础上,通过Envoy Filter配置本地限流策略。不同在于,通过SIDECAR_OUTBOUND表示入流量限流,即作用在客户端的sidecar代理上。配置限流阈值是60秒10次。

 1apiVersion: networking.istio.io/v1alpha3
 2kind: EnvoyFilter
 3metadata:
 4  name: filter-local-ratelimit-client
 5  namespace: accesslog
 6spec:
 7  configPatches:
 8    - applyTo: HTTP_FILTER
 9      match:
10        context: SIDECAR_OUTBOUND
11      ...
12      patch:
13        operation: INSERT_BEFORE
14        value:
15          name: envoy.filters.http.local_ratelimit
16          ...
17            value:
18              stat_prefix: http_local_rate_limiter
19              token_bucket:
20                max_tokens: 10
21                tokens_per_fill: 10
22                fill_interval: 60s
23                 ...

第三步: 在客户端连续curl 超过10次,得到429的响应码,表示触发了限流。

RL客户端访问

第四步: 不同于上一个限流重现在服务端日志中记录了限流RL的Response Flag,这个重现中在客户端访问日志中记录了RL。在客户端代理日志记录中前面若干条请求记录200,后面若干请求记录429 RL表示触发了限流。这里摘取了临近的几条日志,可以看到请求ID是8b99d2e9-d8b2-4724-bafc-8eb59d5dabd1之前的都是200,从dc9e2396-c2c8-4f87-8994-ff4a7f8c8061开始的请求都触发了限流,输出429。

1[2023-08-21T09:38:59.826Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 1 0 "-" "curl/7.52.1" "8b99d2e9-d8b2-4724-bafc-8eb59d5dabd1" "nginx.accesslog" "10.66.0.28:80" outbound|80|v1|nginx.accesslog.svc.cluster.local 10.66.0.24:47792 10.246.91.131:80 10.66.0.24:57562 - -
2[2023-08-21T09:39:00.237Z] "GET / HTTP/1.1" 429 - local_rate_limited - "-" 0 18 0 - "-" "curl/7.52.1" "dc9e2396-c2c8-4f87-8994-ff4a7f8c8061" "nginx.accesslog" "-" outbound|80|v1|nginx.accesslog.svc.cluster.local - 10.246.91.131:80 10.66.0.24:57578 - -

第五步:上一个限流重现很不同的是服务端只有前面200的正常请求,没有429的请求,因为被客户端限流了,请求不会再发到服务端。和服务端的请求完全对应,请求ID是8b99d2e9-d8b2-4724-bafc-8eb59d5dabd1之前的都是200,从dc9e2396-c2c8-4f87-8994-ff4a7f8c8061开始的请求在服务端就没有记录了。

1[2023-08-21T09:38:59.826Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 0 0 "-" "curl/7.52.1" "8b99d2e9-d8b2-4724-bafc-8eb59d5dabd1" "nginx.accesslog" "10.66.0.28:80" inbound|80|| 127.0.0.6:35687 10.66.0.28:80 10.66.0.24:47792 outbound_.80_.v1_.nginx.accesslog.svc.cluster.local default
2-----
3NO further Logs

应对建议

用户主动配置限流策略保护目标服务,无需特殊处理。