一、实验场景说明

下面部署了一个用于演示多种 Istio 特性的应用,该应用由四个单独的微服务构成:

  • productpage. 这个微服务会调用 detailsreviews 两个微服务,用来生成页面。
  • details. 这个微服务中包含了书籍的信息。
  • reviews. 这个微服务中包含了书籍相关的评论。它还会调用 ratings 微服务。
  • ratings. 这个微服务中包含了由书籍评价组成的评级信息。

其中reviews 微服务有 3 个版本:

  • v1 版本不会调用 ratings 服务。
  • v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息。
  • v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息。

其中应用的端到端架构如下:

部署测试用例-1

Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成,并且 reviews 服务具有多个版本。

以下示例默认已经完成 Bookinfo 应用部署,并可在 bookinfo 命名空间中直接验证故障注入与超时效果。

二、Istio 熔断

Istio熔断官网说明

2.1 什么是 Istio 熔断

Istio 中的熔断是一种服务保护机制,用于在微服务架构中处理故障和不稳定的服务。熔断机制可以防止故障服务的请求在整个系统中造成级联故障,从而提高系统的稳定性和可用性。在 Istio 中,熔断是通过配置和管理代理的方式来实现的。

Istio 中熔断的工作原理:

  • 故障检测: Istio 的代理可以监控每个服务之间的流量。当某个服务的请求失败率或响应时间超过预定阈值时,熔断机制会触发。
  • 熔断开关: 一旦故障检测触发,熔断机制会打开一个熔断开关,暂时停止将请求发送到故障服务。这样可以避免过多的请求集中在故障服务上,进一步恶化问题。
  • 半开状态: 在一段时间后,熔断机制会进入半开状态。在这个状态下,允许一些请求通过到故障服务,以便评估服务是否已经恢复正常。如果这些请求成功,熔断机制会重新关闭,恢复正常的请求流量。

Istio 提供了一些用于配置熔断的参数,包括:

  • 故障阈值: 可以设置失败率或响应时间的阈值,一旦超过这些阈值,就会触发熔断。
  • 熔断窗口: 定义在触发熔断后需要等待多长时间进入半开状态。
  • 最小请求数: 设置在半开状态下,至少需要多少个请求来评估服务的恢复情况。

通过这些参数的配置,可以根据应用特点和需求来定制熔断行为

2.2 Istio 熔断实践

下面针对ratings进行熔断,希望在并发请求数超过3,并且存在1个以上的待处理请求,就触发熔断:

1.配置ratings的DestinationRule

[root@k8s-master01 ~]# vim  ratings-dr.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: ratings
  namespace: bookinfo
spec:
  host: ratings
  trafficPolicy: # trafficPolicy 配置可以配置在 subsets 级别
    connectionPool: # 连接池配置可以单独使用限制程序的并发数
      tcp:
        maxConnections: 3 # 最大并发数为 3
      http:
        http1MaxPendingRequests: 1 # 最大的待处理请求
        maxRequestsPerConnection: 1 # 每个请求最大的链接数
    outlierDetection: # 熔断探测配置
      consecutive5xxErrors: 1 # 如果连续出现的错误超过 1 就会被熔断
      interval: 10s #  10 秒探测一次后端实例
      baseEjectionTime: 3m # 熔断的时间
      maxEjectionPercent: 100 # 被熔断实例最大的百分比
  subsets:
  - labels:
      version: v1
    name: v1

2.创建该dr

[root@k8s-master01 ~]# kubectl apply -f ratings-dr.yaml

3.部署测试工具 fortio,用于对容器业务进行压力测试

[root@k8s-master01 ~]# kubectl apply -f istio-1.16.0/samples/httpbin/sample-client/fortio-deploy.yaml -n bookinfo

4.等待 fortio 容器启动后,获取fortio容器 id

[root@k8s-master01 ~]# FORTIO_POD=$(kubectl get pod -n bookinfo | grep fortio | awk '{ print $1 }')
[root@k8s-master01 ~]# echo $FORTIO_POD
fortio-deploy-7dcd84c469-k5vjx

5.在 Kubernetes 集群中的 bookinfo 命名空间内的一个 Pod 中执行 Fortio 负载测试。命令循环执行了100次,每次发送并发数为20、总请求数为50的请求到 http://ratings:9080/ratings/0 地址,并查找并输出请求状态码信息。

[root@k8s-master01 ~]# for i in `seq 1 100`;do kubectl exec -ti $FORTIO_POD -n bookinfo -- fortio load -c 20 -qps 0 -n 50 -loglevel Warning http://ratings:9080/ratings/0 | grep Code;done

上面参数说明:

  • -c 20: 设置并发数为20

  • -qps 0: 设置每秒查询数为0,意味着尽可能快地发送请求

  • -n 50: 设置总请求数为50

  • -loglevel Warning: 设置日志级别为警告级别,减少输出信息

  • http://ratings:9080/ratings/0: 要测试的目标 URL 地址

输出结果如下,观察到后面直接503,出现了熔断 Istio 熔断实践-1

当然,你也可以打开kiali界面查看ratings,观察出现熔断

Istio 熔断实践-2

6.等待3分钟后再进行压力测试,观察到又可以处理访问请求

[root@k8s-master01 ~]# kubectl exec -ti $FORTIO_POD -n bookinfo -- fortio load -c 20 -qps 0 -n 50 -loglevel Warning http://ratings:9080/ratings/0 | grep Code
Code 200 : 13 (26.0 %)
Code 503 : 37 (74.0 %)

我们也可以以查看 fortio 请求记录(upstream_rq_pending_overflow 表示熔断的次数)

[root@k8s-master01 ~]#  kubectl -n bookinfo exec -it $FORTIO_POD -c istio-proxy -- sh -c 'curl localhost:15000/stats' | grep ratings | grep pending_overflow
cluster.outbound|9080|v1|ratings.bookinfo.svc.cluster.local.upstream_rq_pending_overflow: 0
cluster.outbound|9080||ratings.bookinfo.svc.cluster.local.upstream_rq_pending_overflow: 849

2.3 清理环境

1.清理ratings的DestinationRule

[root@k8s-master01 ~]# kubectl delete -f ratings-dr.yaml

2.清理测试工具fortio

[root@k8s-master01 ~]# kubectl delete -f istio-1.16.0/samples/httpbin/sample-client/fortio-deploy.yaml -n bookinfo

三、Istio 注入延迟故障

Istio注入延迟故障官网说明

在微服务架构中,为了确保系统的稳定性、容错性以及适应性,进行故障测试和模拟是非常重要的。Istio提供了一种故障注入的功能,允许开发人员模拟不同类型的故障,其中包括注入延迟故障。通过注入延迟故障,你可以更好地了解你的应用程序在不同故障情况下的行为,从而提高系统的稳定性、可用性和性能。

3.1 后台注入延迟故障

1.创建一个用于测试的工具后,并进行details服务访问,观察到不添加任何故障延迟时,0.015 秒左右就会返回结果

[root@k8s-master01 ~]# kubectl run -ti -n bookinfo debug-tools --image=registry.cn-hangzhou.aliyuncs.com/zq-demo/debug-tools
(14:28 debug-tools:/)  time curl -I -s details:9080

HTTP/1.1 404 Not Found
content-type: text/html; charset=ISO-8859-1
server: envoy
date: Sat, 12 Aug 2023 14:33:36 GMT
content-length: 268
x-envoy-upstream-service-time: 7

real    0m0.015s
user    0m0.001s
sys     0m0.002s

2.注入一个 5s 的延迟

[root@k8s-master01 ~]# vim details-delay.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: details
spec:
  hosts:
  - details
  http:
  - fault: # 添加一个错误
      delay: # 添加类型为 delay 的故障
        percentage: # 故障注入的百分比
          value: 100 # 对所有请求注入故障
        fixedDelay: 5s # 注入的延迟时间
    route:
    - destination:
        host: details

[root@k8s-master01 ~]# kubectl create -f details-delay.yaml -n bookinfo

再次进行details服务访问,观察此时5.020s秒左右才会返回结果

[root@k8s-master01 ~]# kubectl exec -it  -n  bookinfo debug-tools bash
(14:41 debug-tools:/) time curl -I -s details:9080
HTTP/1.1 404 Not Found
content-type: text/html; charset=ISO-8859-1
server: envoy
date: Sat, 12 Aug 2023 14:41:52 GMT
content-length: 268
x-envoy-upstream-service-time: 3

real    0m5.020s
user    0m0.000s
sys     0m0.004s

3.2 前台注入延迟故障

在进行前台注入延迟故障之前,需要把上面创建的vs删除,否则前台选项勾选不上。

[root@k8s-master01 ~]# kubectl delete -f details-delay.yaml -n bookinfo

1.打开kiali界面,依次点击【Services】-【details】

前台注入延迟故障-1

2.依次点击【Actions】-【Fault Injection】

前台注入延迟故障-2

3.打开【Add HTTP Delay】,填写故障注入的百分比为100%,注入的延迟时间为5s,点击【Preview】

前台注入延迟故障-3

4.依次点击【Create】-【Create】

前台注入延迟故障-4

前台注入延迟故障-5

5.进行details服务访问,观察此时5.009秒左右才会返回结果。说明此时产生效果

[root@k8s-master01 ~]# kubectl exec -it  -n  bookinfo debug-tools bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
(14:58 debug-tools:/) time curl -I -s details:9080
HTTP/1.1 404 Not Found
content-type: text/html; charset=ISO-8859-1
server: envoy
date: Sat, 12 Aug 2023 14:58:49 GMT
content-length: 268
x-envoy-upstream-service-time: 4

real    0m5.009s
user    0m0.000s
sys     0m0.004s

3.3 环境清理

清除dr和vs

[root@k8s-master01 ~]# kubectl delete dr,vs details -n bookinfo

四、Istio 注入中断故障

在微服务架构中,为了确保系统的稳定性、容错性以及适应性,进行故障测试和模拟是非常重要的。Istio提供了一种故障注入的功能,允许开发人员模拟不同类型的故障,其中包括注入中断故障。通过注入中断故障,你可以更好地了解你的应用程序在不同故障情况下的行为,从而提高系统的稳定性、可用性和性能。

4.1 后台注入中断故障

1.Istio注入中断故障和Istio注入延迟故障差别不大,先修改vs

[root@k8s-master01 ~]# vim details-abort.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: details
spec:
  hosts:
  - details
  http:
  - fault: # 添加一个错误
      abort: # 添加类型为 delay 的故障
        percentage: # 故障注入的百分比
          value: 100 # 对所有请求注入故障
        httpStatus: 400 # 故障状态码
    route:
    - destination:
        host: details

2.更新vs

[root@k8s-master01 ~]# kubectl replace -f details-abort.yaml -n bookinfo

3.对details服务访问,观察到已返回400

[root@k8s-master01 ~]# kubectl exec -it  -n  bookinfo debug-tools bash
(15:12 debug-tools:/) curl details:9080 -I
HTTP/1.1 400 Bad Request
content-length: 18
content-type: text/plain
date: Sat, 12 Aug 2023 15:12:15 GMT
server: envoy
connection: close

4.打开kiali界面,点击【Graph】后,观察到注入中断成功

image-20230812231720911

4.2 前台注入中断故障

在进行前台注入延迟故障之前,需要把上面创建的vs和dr删除,否则前台选项勾选不上。

[root@k8s-master01 ~]# kubectl delete -f details-abort.yaml -n bookinfo
[root@k8s-master01 ~]# kubectl delete dr details -n bookinfo

1.打开kiali界面,依次点击【Services】-【details】

前台注入中断故障-1

2.依次点击【Actions】-【Fault Injection】

前台注入中断故障-2

3.打开【Add HTTP Abort】,填写故障注入的百分比为100%,状态码为400,点击【Preview】

前台注入中断故障-3

4.依次点击【Create】-【Create】

前台注入中断故障-4

前台注入中断故障-5

5.对details服务访问,观察到已返回400

[root@k8s-master01 ~]# kubectl exec -it  -n  bookinfo debug-tools bash

(15:23 debug-tools:/) curl details:9080 -I
HTTP/1.1 400 Bad Request
content-length: 18
content-type: text/plain
date: Sat, 12 Aug 2023 15:23:47 GMT
server: envoy
connection: close

4.3 环境清理

清除dr和vs

[root@k8s-master01 ~]# kubectl delete dr,vs details -n bookinfo

五、Istio 快速超时配置

快速超时策略是指将请求设置为在预定的时间内超时,以避免长时间的等待和资源浪费。适合使用Istio快速超时配置的应用场景:

  • 外部依赖的超时控制: 当你的微服务需要调用外部依赖时(例如数据库、第三方API等),这些外部依赖可能会出现故障或延迟。通过配置快速超时,你可以限制等待外部依赖的时间,避免长时间的等待,从而减少对系统资源的占用,以及防止请求被无限期阻塞。
  • 避免资源浪费: 有时候,某些请求可能会占用大量资源,例如内存或连接。如果这些请求一直处于等待状态,可能会导致资源浪费。通过配置快速超时,可以在一定时间内终止这些请求,以释放资源并保护系统免受资源耗尽的影响。
  • 快速失败: 在某些情况下,长时间的等待可能不是最佳的解决方案,特别是当外部依赖出现故障时。通过配置快速超时,可以快速失败这些请求,从而允许应用程序在出现问题时更快地进行故障恢复。
  • 提高用户体验: 对于用户来说,长时间的等待可能会导致糟糕的用户体验。通过在适当的情况下配置快速超时,可以确保用户得到更快的响应,提高用户满意度。
  • 限制资源占用: 对于一些特定的请求类型,可能需要限制其执行时间,以确保它们不会占用过多的资源,从而影响其他请求的处理。

注意:在配置快速超时时,需要根据具体的应用需求和情况来决定超时的时间设置

下面演示Istio 快速超时配置实践:

1.向Ratings 服务注入一个 5 秒的延迟用来模拟 Ratings 服务响应比较慢

[root@k8s-master01 ~]# vim ratints-delay.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings-delay
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:
        percentage:
          value: 100
        fixedDelay: 5s
    route:
    - destination:
        host: ratings

[root@k8s-master01 ~]# kubectl create -f ratints-delay.yaml -n bookinfo

测试访问Ratings 服务,观察响应时间为5.028s

[root@k8s-master01 ~]#  kubectl exec -ti debug-tools -n bookinfo -- bash
(15:43 debug-tools:/)  time curl ratings:9080

real    0m5.028s
user    0m0.002s
sys     0m0.000s

2.查看productpage

[root@k8s-master01 ~]# kubectl get po -n bookinfo | grep productpage
NAME                             READY   STATUS    RESTARTS      AGE
productpage-v1-bf4b489d8-xrbs9   2/2     Running   2 (16h ago)   5d10h

[root@k8s-master01 ~]# kubectl logs -f -n bookinfo productpage-v1-bf4b489d8-xrbs9 --tail=10

刷新kiali界面,在后台查看日志,观察到调用reply服务正常

Istio 快速超时配置-1

3.因为Ratings 服务是被 reviews 服务调用,所以需要向reviews服务配置一个1秒超时

[root@k8s-master01 ~]# vim reviews-timeout.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
    timeout: 1s # 添加超时时间为 1 

[root@k8s-master01 ~]# kubectl create -f reviews-timeout.yaml -n bookinfo

Istio 快速超时配置-2

4.再次查看productpage

[root@k8s-master01 ~]# kubectl get po -n bookinfo | grep productpage
NAME                             READY   STATUS    RESTARTS      AGE
productpage-v1-bf4b489d8-xrbs9   2/2     Running   2 (16h ago)   5d10h

[root@k8s-master01 ~]# kubectl logs -f -n bookinfo productpage-v1-bf4b489d8-xrbs9 --tail=10

刷新kiali界面,在后台查看日志,观察到调用reply服务显示超时,说明上面配置生效

Istio 快速超时配置-3