【云原生 | 从零开始学istio】六、istio核心功能

在这里插入图片描述

istio 核心功能演示

断路器

断路器是创建弹性微服务应用程序的重要模式。断路器使应用程序可以适应网络故障和延迟等网络不良影响。

测试断路器:
1、在 k8s 集群创建后端服务

[root@k8smaster ~]# cd istio-1.10.1 
[root@k8smaster istio-1.10.1]# cat samples/httpbin/httpbin.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: httpbin
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
    service: 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
#把 httpbin.tar.gz 上传到node1,手动解压: 
[root@k8snode1 ~]# cd istio/
[root@k8snode1 istio]# docker load -i httpbin.tar.gz 
[root@k8smaster istio-1.10.1]# kubectl apply -f samples/httpbin/httpbin.yaml 
#该 httpbin 应用程序充当后端服务。 

2、配置断路器
创建一个目标规则,在调用 httpbin 服务时应用断路器设置:

[root@k8smaster istio-1.10.1]# vim destination.yaml 
apiVersion:  networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: httpbin
spec:
  host: httpbin
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutiveGatewayErrors: 1
      interval: 1s
      baseEjectionTime: 3m
      maxEjectionPercent: 100

连接池(TCP | HTTP)配置,例如:连接数、并发请求等

tcp:
maxConnections: 1
TCP 连接池中的最大连接请求数,当超过这个值,会返回 503 代码。如两个请求过来,就会有一个请求返回 503。

http:
http1MaxPendingRequests: 1
连接到目标主机的最大挂起请求数,也就是待处理请求数。这里的目标指的是 virtualservice 路由规则中配置的 destination。

maxRequestsPerConnection: 1
连接池中每个连接最多处理 1 个请求后就关闭,并根据需要重新创建连接池中的连接

outlierDetection:
异常检测配置,传统意义上的熔断配置,即对规定时间内服务错误数的监测

consecutiveGatewayErrors: 1
#连续错误数 1,即连续返回 502-504 状态码的 Http 请求错误数

interval: 1s
错误异常的扫描间隔 1s,即在 interval(1s)内连续发生 consecutiveGatewayErrors(1)个错误,则触发服务熔断

baseEjectionTime: 3m
基本驱逐时间 3 分钟,实际驱逐时间为 baseEjectionTime*驱逐次数

maxEjectionPercent: 100
最大驱逐百分比 100%

[root@k8smaster istio-1.10.1]# kubectl apply -f destination.yaml 

3、添加客户端访问 httpbin 服务
创建一个客户端以将流量发送给 httpbin 服务。该客户端是一个简单的负载测试客户端,Fortio 可以控制连接数,并发数和 HTTP 调用延迟。使用此客户端来“跳闸”在 DestinationRule 中设置的断路器策略。看看熔断能不能启动。

#通过执行下面的命令部署 fortio 客户端: 
#把 fortio.tar.gz 上传到 node1 节点,手动解压: 
[root@k8snode1 istio]# docker load -i fortio.tar.gz
[root@k8smaster istio-1.10.1]# kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml 

#通过 kubectl 执行下面的命令,使用 fortio 客户端工具调用 httpbin: 
[root@k8smaster istio-1.10.1]# kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
appv1-6f7b58fd99-xb4br            2/2     Running   0          3h55m
appv2-f78cb577-s6d4z              2/2     Running   0          3h55m
details-v1-65bbfd4f58-7w985       2/2     Running   2          5h4m
fortio-deploy-576dbdfbc4-hgfqj    2/2     Running   0          2m29s
httpbin-74fb669cc6-b25f8          2/2     Running   0          15m
productpage-v1-6b746f74dc-hxn89   2/2     Running   2          5h4m
ratings-v1-b45758b-kz668          2/2     Running   2          5h4m
reviews-v1-74894b48c8-g8nv8       2/2     Running   2          5h4m
reviews-v2-f649764d-2lc54         2/2     Running   2          5h4m
reviews-v3-6c675c6774-smbvr       2/2     Running   2          5h4m

#进入fortio然后使用curl请求httpdbin
[root@k8smaster istio-1.10.1]# kubectl exec fortio-deploy-5789d79849-4grn4 -c fortio -- /usr/bin/fortio curl http://httpbin:8000/get 
#显示如下: 
HTTP/1.1 200 OK 
server: envoy 
date: Mon, 08 Aug 2022 12:34:48 GMT
content-type: application/json 
content-length: 622
access-control-allow-origin: * 
access-control-allow-credentials: true 
x-envoy-upstream-service-time: 2 

4、触发断路器

在 DestinationRule 设置中,指定了 maxConnections: 1 和 http1MaxPendingRequests: 1。这些规则表明,如果超过一个以上的连接并发请求,则 istio-proxy 在为进一步的请求和连接打开路由时,应该会看到下面的情况。
模拟多个客户端发送请求,以两个并发连接(-c 2)和发送 20 个请求(-n 20)调用服务:

[root@k8smaster istio-1.10.1]# kubectl exec -it fortio-deploy-576dbdfbc4-z28m7 -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get 
 
#显示如下: 
一大堆503
Jitter: false 
Code 200 : 4 (20.0 %) 
Code 503 : 16 (80.0 %) 
#只有20%成功了,其余的都断开了,每次请求都不一样,断路器触发了。

超时

在生产环境中经常会碰到由于调用方等待下游的响应过长,堆积大量的请求阻塞了自身服务,造成雪崩的情况,通过通过超时处理来避免由于无限期等待造成的故障,进而增强服务的可用性,Istio 使用虚拟服务来优雅实现超时处理。
下面例子模拟客户端调用 nginx,nginx 将请求转发给 tomcat。nginx 服务设置了超时时间为 2 秒,如果超出这个时间就不在等待,返回超时错误。tomcat 服务设置了响应时间延迟 10 秒,任何请求都需要等待 10 秒后才能返回。client 通过访问 nginx 服务去反向代理 tomcat 服务,由于 tomcat 服务需要 10 秒后才能返回,但 nginx 服务只等待 2 秒,所以客户端会提示超时错误。

node1解压tomcat,nginx,busybox
[root@k8snode1 ~]# docker load -i nginx
[root@k8snode1 ~]# docker load -i busybox:1.2.8
[root@k8snode1 ~]# docker load -i tomcat
[root@k8smaster ~]# mkdir /root/timeout 
[root@k8smaster ~]# cd /root/timeout/ 
[root@k8smaster timeout~]# vim nginx-deployment.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-tomcat
  labels:
    server: nginx
    app: web
spec:
  replicas: 1
  selector:
    matchLabels:
      server: nginx
      app: web
  template:
    metadata:
      name: nginx
      labels: 
        server: nginx
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat
  labels:
    server: tomcat
    app: web
spec:
  replicas: 1
  selector:
    matchLabels:
      server: tomcat
      app: web
  template:
    metadata:
      name: tomcat
      labels: 
        server: tomcat
        app: web
    spec:
      containers:
      - name: tomcat
        image: docker.io/kubeguide/tomcat-app:v1 
        imagePullPolicy: IfNotPresent
[root@k8smaster timeout]# vim nginx-tomcat-svc.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    server: nginx
  ports:
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
spec:
  selector:
    server: tomcat
  ports:
  - name: http
    port: 8080
    targetPort: 8080
    protocol: TCP
[root@k8smaster timeout]# vim virtual-tomcat.yaml 
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: nginx-vs
spec:
  hosts:
  - nginx-svc
  http:
  - route:
    - destination: 
        host: nginx-svc
    timeout: 2s
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: tomcat-vs
spec:
  hosts:
  - tomcat-svc
  http:
  - fault:
      delay:
        percentage:
          value: 100
        fixedDelay: 10s
    route:
    - destination:
        host: tomcat-svc

#virtual-tomcat.yaml 资源清单重点知识讲解 
第一:故障注入
http: 
- fault: 
 delay: 
 percentage: 
 value: 100 
 fixedDelay: 10s 
该设置说明每次调用 tomcat-svc 的 k8s service,都会延迟 10s 才会调用。 

第二:调用超时
hosts: 
- nginx-svc 
 http: 
 - route: 
 - destination: 
 host: nginx-svc 
 timeout: 2s 
该设置说明调用 nginx-svc 的 k8s service,请求超时时间是 2s。 

#部署 tomcat、nginx 服务 
需要对 nginx-deployment.yaml 资源文件进行 Istio 注入,将 nginx、tomcat 都放入到网格中,可以采用手工注入 Istio 方式。 
[root@k8smaster timeout]# kubectl apply -f nginx-deployment.yaml 
执行成功后,通过 kubectl get pods 查看 Istio 注入情况: 
[root@k8smaster timeout]# kubectl get pods 
NAME                              READY   STATUS    RESTARTS   AGE
nginx-tomcat-7dd6f74846-48g9f     2/2     Running   0          5h15m
tomcat-86ddb8f5c9-h6jdl           2/2     Running   0          5h15m

#部署 nginx 和 tomcat 的 service 
[root@k8smaster timeout]# kubectl apply -f nginx-tomcat-svc.yaml 
#部署虚拟服务 
[root@k8smaster timeout]# kubectl apply -f virtual-tomcat.yaml 

#设置超时时间 
[root@k8smaster timeout]# kubectl exec -it nginx-tomcat-7dd6f74846-48g9f -- sh 
# apt-get update 
# apt-get install vim -y 
# vim /etc/nginx/conf.d/default.conf
在location里把root和index注释掉,然后加下面两行反向代理的
proxy_pass http://tomcat-svc:8080; 
proxy_http_version 1.1; 
编辑完后,再执行如下语句验证配置和让配置生效: 
/ # nginx -t 
/ # nginx -s reload 
这样,整个样例配置和部署都完成了。 
 
#验证超时 
登录 client,执行如下语句: 
[root@k8smaster timeout]# kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh 
/ # time wget -q -O - http://nginx-svc 
#网关超时了
wget: server returned error: HTTP/1.1 408 Request Timeout 
Command exited with non-zero status 1 
real 0m 2.02s 
user 0m 0.00s 
sys 0m 0.00s
/ # while true; do wget -q -O - http://nginx-svc; done 
wget: server returned error: HTTP/1.1 504 Gateway Timeout 
wget: server returned error: HTTP/1.1 504 Gateway Timeout 
wget: server returned error: HTTP/1.1 504 Gateway Timeout 
wget: server returned error: HTTP/1.1 504 Gateway Timeout 
wget: server returned error: HTTP/1.1 408 Request Timeout 
每隔 2 秒,由于 nginx 服务的超时时间到了而 tomcat 未有响应,则提示返回超时错误。 

验证故障注入效果,执行如下语句: 
/ # time wget -q -O - http://tomcat-svc 
wget: server returned error: HTTP/1.1 503 Service Unavailable 
Command exited with non-zero status 1 
real 0m 10.02s 
user 0m 0.00s 
sys 0m 0.01s 
执行之后 10s 才会有结果 

故障注入和重试

Istio 重试机制就是如果调用服务失败,Envoy 代理尝试连接服务的最大次数。而默认情况下,Envoy 代理在失败后并不会尝试重新连接服务,除非我们启动 Istio 重试机制。

下面例子模拟客户端调用 nginx,nginx 将请求转发给 tomcat。tomcat 通过故障注入而中止对外服务,nginx 设置如果访问 tomcat 失败则会重试 3 次。

[root@k8smaster timeout]# kubectl delete -f . 
[root@k8smaster timeout]# kubectl apply -f nginx-deployment.yaml 
[root@k8smaster timeout]# kubectl apply -f nginx-tomcat-svc.yaml 
[root@k8smaster timeout]# vim virtual-attempt.yaml 
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: nginx-vs
spec:
  hosts:
  - nginx-svc
  http:
  - route:
    - destination: 
        host: nginx-svc
    retries:
      attempts: 3
      perTryTimeout: 2s
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: tomcat-vs
spec:
  hosts:
  - tomcat-svc
  http:
  - fault:
      abort:
        percentage:
          value: 100
        httpStatus: 503
    route:
    - destination:
        host: tomcat-svc
[root@k8smaster timeout]# kubectl apply -f virtual-attempt.yaml 
 
虚拟服务资源清单解读: 
第一:故障注入。该虚拟服务的作用对象就是 tomcat-svc。使用此故障注入后,在网格中该 tomcat 就是不可用的。 
abort: 
 percentage: 
 value: 100 
 httpStatus: 503 
abort 是模拟 tomcat 服务始终不可用,该设置说明每次调用 tomcat-svc 的 k8s service,100%都会返回错误状态码 503。 

第二:调用超时: 
hosts: 
- nginx-svc 
 http: 
 - route: 
- destination: 
 host: nginx-svc 
 reties: 
 attempts: 3 
 perTryTimeout: 2s 
该设置说明调用 nginx-svc 的 k8s service,在初始调用失败后最多重试 3 次来连接到服务子集,每个重试都有 2 秒的超时。 
 
[root@k8smaster timeout]# kubectl exec -it nginx-tomcat-3da6f82051-rdqqf -- /bin/sh 
# apt-get update 
# apt-get install vim -y 
/ # vim /etc/nginx/conf.d/default.conf
在location里把root和index注释掉,然后加下面两行反向代理的
proxy_pass http://tomcat-svc:8080; 
proxy_http_version 1.1; 
/ # nginx -t 
/ # nginx -s reload 

#验证重试是否生效 
[root@k8smaster timeout]# kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh 
/ # wget -q -O - http://nginx-svc
[root@xianchaomaster1 timeout]# kubectl logs -f nginx-tomcat-3da6f82051-rdqqf -c istio-proxy 
可以看到重试三次

分布式追踪系统-jaeger

1.什么是分布式追踪?

分布式追踪最早由谷歌的 Dapper 普及开来,它本质上是具有在微服务的整个生命周期中追踪请求的能力。分布式追踪(Distributed Tracing)主要用于记录整个请求链的信息。

2.为什么要分布式追踪?

当业务微服务化后,一次业务请求,可能会涉及到多个微服务,分布式跟踪可以对跨多个分布式服务网格的 1 个请求进行追踪分析,并通过可视化的方式深入地了解请求的延迟,序列化和并发,充分地了解服务流量实况,从而快速地排查和定位问题。在微服务应用中,一个完整的业务往往需要调用多个服务才能完成,服务之间就产生了交互。当出现故障时,如何找到问题的根源非常重要。追踪系统可以清晰地展示出请求的整个调用链以及每一步的耗时,方便查找问题所在。

3.分布式追踪系统-jaeger

Jaeger 是一个开源的分布式追踪系统,它可以在复杂的分布式系统中进行监控和故障排查。Jaeger的主要功能包括分布式请求监控、性能调优、故障分析和服务依赖分析等。

Jaeger 组件介绍:

jaeger-agent:
负责发送的进程,对 spans 进行处理并发送给 collector,监听 spans 的 UDP 发送。这层作为基础组件部署在主机上,Agent 将 Client Library 和 Collector 解耦,为 ClientLibrary 屏蔽了路由和发现 Collector 的细节。

jaeger-collector:
收集追踪 spans,并通过管道对追踪数据进行处理。当前的管道支持追踪的验证、索引、转换,最后存储数据。

jaeger-query:
从存储中检索追踪信息并通过 UI 展示

data store:
追踪信息的存储

4.使用 jaeger

kubectl get svc -n istio-system | grep jaeger 
显示如下:
jaeger-agent ClusterIP None <none> 5775/UDP,6831/UDP,6832/UDP 55d
jaeger-collector ClusterIP 10.99.194.57 <none> 14267/TCP,14268/TCP,14250/TCP 55d
jaeger-collector-headless ClusterIP None <none> 14250/TCP 55d
jaeger-query ClusterIP 10.107.192.115 <none> 16686/TCP

修改 jaeger-query 的 type 类型为 nodePort
kubectl edit svc jaeger-query -n istio-system
把 type: ClusterIP 变成 type: NodePort
kubectl get svc -n istio-system | grep jaeger-query
显示如下:
jaeger-query NodePort 10.107.192.115 <none> 16686:31450/TCP 

在浏览器访问:
192.168.11.129:31450

5.追踪上下文传递

Istio 利用 Envoy 的分布式追踪功能提供了开箱即用的追踪集成。确切地说,Istio 提供了安装各种追踪后端服务的选项,并且通过配置代理来自动发送追踪 span 到追踪后端服务。尽管 Istio 代理能够自动发送 span,但是他们需要一些附加线索才能将整个追踪链路关联到一起。所以当代理发送 span 信息的时候,应用需要附加适当的 HTTP 请求头信息,这样才能够把多个 span 正确的关联到同一个追踪上。
要做到这一点,应用程序从传入请求到任何传出的请求中需要包含以下请求头参数:
x-request-id
x-b3-traceid
x-b3-spanid
x-b3-parentspanid
x-b3-sampled
x-b3-flags
x-ot-span-context

写在最后

创作不易,如果觉得内容对你有帮助,麻烦给个三连关注支持一下我!如果有错误,请在评论区指出,我会及时更改!istio系列也算完结了,后面会补充一些k8s篇的遗漏知识点。

感谢各位的观看,文章掺杂个人理解,如有错误请联系我指出~

猜你喜欢

转载自blog.csdn.net/qq_45400861/article/details/127879313