前提条件:
部署服务(deployment、service)并注入sidecar
我这里还是使用官方提供的bookinfo程序,选择productpage作为熔断目标
kubectl apply -f - << EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage
spec:
host: productpage
subsets:
- name: v1
labels:
version: v1
EOF
在之前的文档中,设置了目标路由的subset,使virtual service能够识别版本,本文中流量熔断是基于目标路由配置的设置。
测试工具
这是一个名为 Fortio 的负载测试客户端, 它可以控制连接数、并发数及发送 HTTP 请求的延迟。 通过 Fortio 能够有效的触发前面在 DestinationRule
中设置的熔断策略
注意:Fortio也需要注入sidecar
kubectl apply -f - << EOF
apiVersion: v1
kind: Service
metadata:
name: fortio
labels:
app: fortio
service: fortio
spec:
ports:
- port: 8080
name: http
selector:
app: fortio
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: fortio-deploy
spec:
replicas: 1
selector:
matchLabels:
app: fortio
template:
metadata:
annotations:
# This annotation causes Envoy to serve cluster.outbound statistics via 15000/stats
# in addition to the stats normally served by Istio. The Circuit Breaking example task
# gives an example of inspecting Envoy stats via proxy config.
proxy.istio.io/config: |-
proxyStatsMatcher:
inclusionPrefixes:
- "cluster.outbound"
- "cluster_manager"
- "listener_manager"
- "server"
- "cluster.xds-grpc"
labels:
app: fortio
spec:
containers:
- name: fortio
image: fortio/fortio:latest_release
imagePullPolicy: Always
ports:
- containerPort: 8080
name: http-fortio
- containerPort: 8079
name: grpc-ping
EOF
测试并发数
获取Fortio pod名称
export FORTIO_POD=$(kubectl get pods -l app=fortio -o 'jsonpath={.items[0].metadata.name}')
测试并发
kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 10 -qps 0 -n 1 -loglevel Warning http://productpage:9080/productpage
-c : 每次连接的并发连接数
-n : 发送连接次数
配置Destination Rule
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage
spec:
host: productpage
subsets:
- name: v1
labels:
version: v1
# 以下是新增的流量策略
trafficPolicy:
# 设置连接池
connectionPool:
tcp:
# tcp最大链接数为1
maxConnections: 1
http:
# http最大等待请求数为1
http1MaxPendingRequests: 1
# 每个连接的最大请求数为1
maxRequestsPerConnection: 1
# 异常检测,用于自动检测并排除异常的服务实例
outlierDetection:
# 连续的 5xx 错误计数,当达到这个阈值时,实例会被标记为异常
consecutive5xxErrors: 1
# 检测的时间窗口,这里是每秒检测一次
interval: 1s
# 基础排除时间,当实例被标记为异常后,它会在这段时间内被排除,这里是 3 分钟
baseEjectionTime: 3m
# 允许被排除的最大实例百分比,这里是 100%,意味着所有实例都可能被排除
maxEjectionPercent: 100
EOF
再次测试
获取Fortio pod名称
export FORTIO_POD=$(kubectl get pods -l app=fortio -o 'jsonpath={.items[0].metadata.name}')
测试并发
kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 10 -qps 0 -n 1 -loglevel Warning http://productpage:9080/productpage
istio-proxy 允许存在一些误差,所以偶尔会出现拦截9个请求偶尔拦截8个请求,这与各种因素有关,只需要关心大概范围即可。
查看详细熔断日志
多次并发测试后可以通过日志了解更多熔断详情
kubectl exec "$FORTIO_POD" -c istio-proxy -- pilot-agent request GET stats | grep productpage | grep pending
其中110个被请求标记为熔断,20个请求通过