Istio 故障注入

1、介绍

​ Istio 故障注入与其他在网络层引入错误(例如延迟数据包或者直接杀死 Pod)的机制不同,Istio 允许在应用程序层注入故障。这使得可以注入更多相关的故障,比如 HTTP 错误代码等。

​ Istio 可以注入两种类型的故障,而这两种故障都是使用虚拟服务来配置的:

1
2
3
延迟:模拟增加网络延迟或上游服务过载。

中止:模拟服务故障而导致调用服务不可用。中止通常以 HTTP 错误代码或 TCP 连接失败表示

2、使用系统配置

1)注入HTTP延迟故障

1
2
3
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

经过上面的配置,下面是请求的流程:

  • productpagereviews:v2ratings (针对 jason 用户)
  • productpagereviews:v1 (其他用户)

为了测试微服务应用程序 Bookinfo 的弹性,将为用户 jasonreviews:v2ratings 服务之间注入一个 7 秒的延迟。

1
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml

2)测试延迟配置

  1. 通过浏览器打开Bookinfo应用

  2. 使用用户Jason登录到/prodectpage页面,会发现大约7秒钟加载完成并没有错误,但Reviews部分显示了错误消息

    image-20210517111211879

  3. 查看页面的相应时间大约6s

    image-20210517111330802

3)造成原理

按照预期,引入的 7 秒延迟不会影响到 reviews 服务,因为 reviewsratings 服务间的超时被硬编码为 10 秒。 但是,在 productpagereviews 服务之间也有一个 3 秒的硬编码的超时,再加 1 次重试,一共 6 秒。 结果,productpagereviews 的调用在 6 秒后提前超时并抛出错误了。Istio 的故障注入规则可以帮助您识别此类异常,而不会影响最终用户。

4)修复错误

  1. 增加 productpagereviews 服务之间的超时或降低 reviewsratings 的超时
  2. 终止并重启修复后的微服务
  3. 确认 /productpage 页面正常响应且没有任何错误

将所有流量转移到 reviews:v3, 您可以尝试修改延迟规则为任何低于 2.5 秒的数值,例如 2 秒,然后确认端到端的流程没有任何错误。

image-20210517112024272

5)注入HTTP abort故障

将给 ratings 微服务为测试用户 jason 引入一个 HTTP abort。在这种情况下,希望页面能够立即加载,同时显示 Ratings service is currently unavailable 这样的消息。为用户 jason 创建一个发送 HTTP abort 的故障注入规则:

1
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml

6)测试终止配置

  1. 用浏览器打开 Bookinfo 应用。
  2. 使用用户 jason 登陆到 /productpage 页面。如果规则成功传播到所有的 pod,能立即看到页面加载并看到 Ratings service is currently unavailable 消息。
  3. 如果您注销用户 jason 或在匿名窗口(或其他浏览器)中打开 Bookinfo 应用程序, 将看到 /productpage 为除 jason 以外的其他用户调用了 reviews:v1(完全不调用 ratings)。 因此,您不会看到任何错误消息。

3、自定义配置

1. 故障延迟

1.1 客户端资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: client
spec:
replicas: 1
selector:
matchLabels:
app: client
template:
metadata:
labels:
app: client
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "sleep 3600" ]

部署并使用istio注入,最终得到以下

image-20200529112054698

1.2 服务端资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
server: nginx
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
server: nginx
spec:
replicas: 1
selector:
matchLabels:
server: nginx
template:
metadata:
labels:
server: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent

1.3 虚拟服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-vs
spec:
hosts:
- nginx-svc
http:
- fault:
delay:
percentage:
value: 100
fixedDelay: 10s
route:
- destination:
host: nginx-svc

2. 验证故障注入

进入客户端容器中,访问nginx服务

1
2
kubectl exec -it client-8496866cdf-vkmcw /bin/sh
wget -q -O - http://nginx-svc

image-20200529113929500

可以看出时间延迟在十多秒,加上操作时间,和上面设置的时间是吻合的。

3. 故障中止

修改虚拟服务文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-vs
spec:
hosts:
- nginx-svc
http:
- fault:
abort:
percentage:
value: 100
httpStatus: 503
route:
- destination:
host: nginx-svc

4. 再次进入客户端验证

1
2
kubectl exec -it client-8496866cdf-vkmcw /bin/sh
wget -q -O - http://nginx-svc

image-20200529114513795