为了提高服务的稳定性,我们可以通过让服务调用失败或者增加服务的响应时间等方式,来主动模拟服务故障的场景,这种给服务注入故障来测试服务稳定性的行为称为故障注入(Fault Injection),也称为混沌工程(Chaos Engineering)。我们可以随机地给服务注入故障,观察服务的表现,检测服务的稳定性;故障的范围可大可小,小到给部分服务增加错误或者时延,大到给整个机房断电,来检测整个应用的稳定性。
虽然Istio的Envoy代理已经提供了许多的服务故障恢复机制,但是端到端地检测整个应用的故障恢复能力仍然很有必要。配置不当的失败恢复策略(例如,在整个服务调用链中设置了不合适的服务调用超时)可能会导致应用的核心服务持续不可用,给用户带来糟糕的体验。
Istio选择了支持协议相关的故障注入,而不是杀死Pod或者延时、破坏TCP层的包,因为不管是软件的故障还是硬件的故障,对于应用层来说,故障的表现都是一样的。我们可以选择更有意义的故障来注入应用层,以此来检测并提高应用的弹性。例如:对于HTTP协议来说,HTTP错误响应码注入是个不错的选择。
在Istio中,可以给满足特定条件的请求注入故障,也可以进一步地控制故障出现的比例。有两种可以选择的故障:服务延时和服务请求出错,服务延时是响应时间相关的故障,用来模拟增加网络的延迟或者一个过载的服务。服务请求出错是崩溃故障,用来模拟服务失败的故障,服务请求出错一般以HTTP错误响应码或者TCP连接故障居多。
【实验前的准备】
进行本章实验前,需要先执行如下的前置步骤。
1)下载实验时用到的源码仓库:
$ sudo yum install -y git $ git clone https://github.com/mgxian/istio-lab Cloning into 'istio-lab'... remote: Enumerating objects: 247, done. remote: Counting objects: 100% (247/247), done. remote: Compressing objects: 100% (173/173), done. remote: Total 774 (delta 153), reused 164 (delta 73), pack-reused 527 Receiving objects: 100% (774/774), 283.00 KiB | 229.00 KiB/s, done. Resolving deltas: 100% (447/447), done. $ cd istio-lab
2)开启default命名空间的自动注入功能:
$ kubectl label namespace default istio-injection=enabled namespace/default labeled
3)部署用于测试的服务:
$ kubectl apply -f service/go/service-go.yaml $ kubectl apply -f service/node/service-node.yaml $ kubectl apply -f service/lua/service-lua.yaml $ kubectl apply -f service/python/service-python.yaml $ kubectl apply -f service/js/service-js.yaml $ kubectl get pod NAME READY STATUS RESTARTS AGE service-go-v1-7cc5c6f574-svn5c 2/2 Running 0 3m38s service-go-v2-7656dcc478-lrp2h 2/2 Running 0 3m38s service-js-v1-55756d577-674p5 2/2 Running 0 3m33s service-js-v2-86bdfc86d9-5v9xw 2/2 Running 0 3m33s service-lua-v1-5c9bcb7778-7g9d5 2/2 Running 0 3m36s service-lua-v2-75cb5cdf8-t79dh 2/2 Running 0 3m36s service-node-v1-d44b9bf7b-ppn26 2/2 Running 0 3m37s service-node-v2-86545d9796-rgmb7 2/2 Running 0 3m37s service-python-v1-79fc5849fd-5bx5w 2/2 Running 0 3m35s service-python-v2-7b6864b96b-7jnt6 2/2 Running 0 3m34s