故障注入是指将故障注入系统,便于检查系统在存在故障时的行为,以检查系统在可用性方面是否按我们期望的方式运行,测试应用系统的弹性。 本节将基于istio官方文档https://istio.io/latest/zh/docs/tasks/traffic-management/fault-injection/体验istio在流量管理方面的故障注入功能。

基于使用前面已经部署好的bookinfo应用,执行下面的命令初始化bookinfo应用的路由:

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

经过上面的配置,当前的路由情况是: 默认情况下将请求路由到所有服务的v1版本,同时对于jason用户访问reviews服务时,会被路由到reviews服务的v2版本。

istio.jpg

注入HTTP延迟故障

为了测试Bookinfo应用微服务的弹性能力,下面将只对jason用户从reviews:v2服务到ratings服务的请求注入一个7s的延迟。 这个测试主要用于发现Bookinfo的潜在bug。注意reviews:v2在请求ratings服务时作为客户端硬编码设置了10s的超时时间,通过注入7s的HTTP延迟故障,目的是为了测试在这种情况下端到端的流程不会出现错误。

下面创建来自用户"jason"的HTTP延迟故障注入规则:

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

查看samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml:

 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
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      delay:
        percentage:
          value: 100.0
        fixedDelay: 7s
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1

针对来自jason用户的请求对ratings服务注入了7s的延迟故障,此时如果访问/productpage,期望的效果是页面大约7秒多能加载出来且不会有错误发生,因为reviews:v2在请求ratings服务时作为客户端硬编码设置了10s的超时时间。 但是,在productpagereviews服务之间也有一个3秒的硬编码的超时,再加1次重试,一共 6 秒。 结果,productpagereviews的调用在6秒后提前超时并抛出错误了。 这和我们期不符合,通过这个HTTP延迟故障注入,发现了reviews:v2这个版本的服务硬编码10秒的潜在bug的潜在bug,导致端到端的流程出现错误。 在通过故障注入发现此类问题后,要修复这个问题,可以通过提高productpage作为客户端到reviews服务的超时时间,或者降低reviews服务和ratings服务之间请求的超时时间。

bookinfo-fault-inject-find-bug

这种类型的错误可能发生在典型的由不同的团队独立开发不同的微服务的企业应用程序中。 Istio 的故障注入规则可以帮助您识别此类异常,而不会影响最终用户。 注意此次故障注入限制为仅影响用户 jason,而如果以其他用户登录不会遇到任何延迟问题

注入 HTTP abort 故障

对微服务进行弹性测试的另外一种方式是引入HTTP abort故障,下面当jason用户访问ratings服务时加入一个HTTP中断,注入一个HTTP 500错误。

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

查看samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml:

 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
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      abort:
        percentage:
          value: 100.0
        httpStatus: 500
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1

此时以jason用户登录访问/productpage,页面上会立即显示而且Book Reviews区域可以显示内容,但会出现Ratings service is currently unavailable的信息。而如果以其他用户登录,页面所有区域都将显示正常。

bookinfo-abort-fault-inject

在完成了前面的两个实验后,使用kubectl delete -f samples/bookinfo/networking/virtual-service-all-v1.yaml完成清理工作,便于我们后边进一步的实验。

总结

故障注入是一种将错误引入系统以确保系统能够承受并从错误条件中恢复的测试方法。 与其他错误注入机制(如延迟数据包或在网络层杀掉 Pod)不同,Istio 允许在应用层注入错误。这使您可以注入更多相关的故障,例如 HTTP 错误码,以获得更多相关的结果。 本节练习的两种故障注入HTTP延迟注入HTTP终止注入都使用了istio的VirtualService配置。

参考