配置请求超时
1. 准备工作
[root@master ~]# kubectl apply -f istio-1.6.2/samples/bookinfo/networking/virtual-service-all-v1.yaml
//都选择v1服务,刷新浏览器验证
2. 请求超时
针对http的请求超时,可以使用路由规则中的timeout字段。默认timeout是关闭的。但是在此任务中,设置reviews服务的超时时间为1秒。为了查看它的影响,我们还可以在调用ratings服务的时候引进一个2秒的延迟。
- 路由请求到reviews的v2版本。
[root@master ~]# kubectl edit VirtualService reviews
...
subset: v2 //修改后刷新浏览器始终显示V2版本黑色星星
- 路由请求到ratings服务,添加2秒的延迟。
[root@master ~]# kubectl edit VirtualService ratings
apiVersion: networking.istio.io/v1alpha3
...
spec:
hosts:
- ratings
http:
- fault:
delay:
percent: 100
fixedDelay: 2s
route:
- destination:
host: ratings
subset: v1
刷新页面时,它会有2秒的延迟。
4. 现在针对调用reviews服务添加0.5秒的延迟。
[root@master ~]# kubectl edit VirtualService reviews
...
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v2
timeout: 0.5s
现在,您应该看到它在大约1秒(而不是2秒)后返回,并且reviews
不可用
即使超时配置为半秒,响应也需要1秒,这是因为在productpage服务中有一个硬编码的重试,所以它在返回之前会两次调用计时的 reviews服务。
在此任务中,使用istio针对调用reviews微服务的请求超时时间设置为半秒。 但是默认的请求超时是关闭的。 因此当reviews服务去调用ratings服务时,而我们设置的调用超时时间为2秒。这就导致了reviews的微服务超时,因为2秒大于它本身设置的0.5秒。
仔细观察reviews服务页面显示,你就会发现Sorry, product reviews are currently unavailable for this book.这其实就是从reviews服务收到的结果。
如果你要仔细检查故障注入,你会发现productpage微服务去调用reviews微服务也有它相应的应用级别超时。
配置断路器
本小节主要讲解针对连接、请求、和异常点检测如何配置断路器。
断路是创建弹性微服务应用程序的重要模式。断路允许您编写应用程序来限制故障、延迟峰值和网络特性的其他不良影响的影响。
1. 准备工作
- 开启自动sidecar的注入,部署httpbin服务。
[root@master ~]# cat istio-1.6.2/samples/httpbin/httpbin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
[root@master ~]# kubectl apply -f istio-1.6.2/samples/httpbin/httpbin.yaml
2. 配置断路器
- 当调用httpbin服务时,创建destination rules去应用断路器
[warning] 如果您安装/配置了Istio,并且启用了相互TLS身份验证,那么在应用之前,您必须在DestinationRule中添加一个TLS流量策略模式:ISTIO_MUTUAL。否则请求将产生503个错误。
[root@master ~]# kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
outlierDetection:
consecutiveErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
EOF
[root@master ~]# kubectl get DestinationRule httpbin
NAME HOST AGE
httpbin httpbin 8s
3. 添加一个客户端
创建一个向httpbin服务发送流量的客户机。客户机是一个简单的负载测试客户机,名为fortio。Fortio允许您控制发出HTTP调用的连接数、并发性和延迟。您将使用此客户端“测试”您在DestinationRule中设置的断路器策略。
- 向客户机注入Istio sidecar代理,以便网络交互由Istio控制。开启自动注册sidecar,执行
[root@master ~]# kubectl apply -f istio-1.6.2/samples/httpbin/sample-client/fortio-deploy.yaml
- 登陆进客户端Pod,使用fortio工具去调用httpbin,传送-curl去表明你想要调用一次。
[root@master ~]# FORTIO_POD=$(kubectl get pods -lapp=fortio -o 'jsonpath={.items[0].metadata.name}')
[root@master ~]# kubectl exec -it "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -curl http://httpbin:8000/get
HTTP/1.1 200 OK
server: envoy
...
"url": "http://httpbin:8000/get"
}
可以看到请求是成功的,现在终止一些东西。
4. 使用断路器
在目的的规则中,指定了maxConnections: 1和http1MaxPendingRequests: 1,这表明假如你执行超过一个连接和并发请求超过一个的话,那么应该看到一些错误,这是因为istio-proxy为进一步的请求和连接打开断路。
- 调用服务使用两个并发连接(-c 2)和发送20个请求(-n 20):
[root@master ~]# kubectl exec -it "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get
...Ended after 98.489466ms : 20 calls. qps=203.07
Aggregated Function Time : count 20 avg 0.0074911122 +/- 0.01097 min 0.001149681 max 0.047671519 sum 0.149822244
# range, mid point, percentile, count
>= 0.00114968 <= 0.002 , 0.00157484 , 25.00, 5
> 0.002 <= 0.003 , 0.0025 , 35.00, 2
> 0.003 <= 0.004 , 0.0035 , 50.00, 3
> 0.004 <= 0.005 , 0.0045 , 70.00, 4
> 0.005 <= 0.006 , 0.0055 , 75.00, 1
> 0.006 <= 0.007 , 0.0065 , 80.00, 1
> 0.007 <= 0.008 , 0.0075 , 85.00, 1
> 0.012 <= 0.014 , 0.013 , 90.00, 1
> 0.025 <= 0.03 , 0.0275 , 95.00, 1
> 0.045 <= 0.0476715 , 0.0463358 , 100.00, 1
# target 50% 0.004
# target 75% 0.006
# target 90% 0.014
# target 99% 0.0471372
# target 99.9% 0.0476181
Sockets used: 12 (for perfect keepalive, would be 2)
Jitter: false
Code 200 : 9 (45.0 %)
Code 503 : 11 (55.0 %) //大部分请求都通过了. istio-proxy看来做了些均衡。
Response Header Sizes : count 20 avg 103.65 +/- 114.6 min 0 max 231 sum 2073
Response Body/Total Sizes : count 20 avg 516.1 +/- 304.1 min 241 max 853 sum 10322
All done 20 calls (plus 0 warmup) 7.491 ms avg, 203.1 qps
现在把并发连接调整为3:
[root@master ~]# kubectl exec -it "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 30 -loglevel Warning http://httpbin:8000/get
...
Sockets used: 20 (for perfect keepalive, would be 3)
Code 200 : 12 (40.0 %)
Code 503 : 18 (60.0 %)
Response Header Sizes : count 30 avg 92.233333 +/- 113 min 0 max 231 sum 2767
Response Body/Total Sizes : count 30 avg 471.23333 +/- 282 min 241 max 817 sum 14137
All done 30 calls (plus 0 warmup) 8.245 ms avg, 347.2 qps
- 查询 istio-proxy的统计信息:
[root@master ~]# kubectl exec "$FORTIO_POD" -c istio-proxy -- pilot-agent request GET stats | grep httpbin | grep pending
cluster.outbound|8000||httpbin.default.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
cluster.outbound|8000||httpbin.default.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_active: 0
cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_failure_eject: 0
cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_overflow: 29
cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_pending_total: 22
你可以看到upstream_rq_pending_overflow的值为22,意味着到目前为止已经被标记为断路。
//清除本次实验
kubectl delete destinationrule httpbin
kubectl delete deploy httpbin fortio-deploy
kubectl delete svc httpbin fortio