云原生服务网格Istio实战

基础介绍

1、Istio的定义

Istio 是一个开源服务网格,它透明地分层到现有的分布式应用程序上。 Istio 强大的特性提供了一种统一和更有效的方式来保护、连接和监视服务。 Istio 是实现负载平衡、服务到服务身份验证和监视的路径——只需要很少或不需要更改服务代码。它强大的控制平面带来了重要的特点,包括:

  • 使用 TLS 加密、强身份认证和授权的集群内服务到服务的安全通信

  • 自动负载均衡的 HTTP, gRPC, WebSocket,和 TCP 流量

  • 通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制

  • 一个可插入的策略层和配置 API,支持访问控制、速率限制和配额

  • 对集群内的所有流量(包括集群入口和出口)进行自动度量、日志和跟踪

官网地址:https://istio.io/latest/zh/about/service-mesh/

使用 Istio 前:

在这里插入图片描述

使用 Istio 后:

在这里插入图片描述

2、架构
Istio 服务网格从逻辑上分为数据平面和控制平面。

  • 数据平面 由一组智能代理(Envoy)组成,被部署为 Sidecar。这些代理负责协调和控制微服务之间的所有网络通信。 它们还收集和报告所有网格流量的遥测数据。

  • 控制平面 管理并配置代理来进行流量路由。

https://istio.io/latest/zh/docs/ops/deployment/architecture/

下图展示了组成每个平面的不同组件:

在这里插入图片描述

3、Istio安装
3.1 下载Istio
1)下载指定版本

https://istio.io/latest/zh/docs/setup/getting-started/#download

# 指定版本下载  
# 要为 x86_64 架构下载 Istio 1.20.0,请运行
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.20.0 TARGET_ARCH=x86_64 sh -

如果下载不了,去https://github.com/istio/istio/releases/tag/1.20.0下载

wget https://github.com/istio/istio/releases/download/1.20.0/istio-1.20.0-linux-amd64.tar.gz

2)解压后进入安装目录

tar -zxvf istio-1.20.0-linux-amd64.tar.gz

安装目录包含:

  • bin: 存放istioctl二进制文件
  • manifests: istio 的内置chart目录,默认使用这些内置 chart 生成安装清单,安装过程也可以自行设置–manifests=other_manifests/参数来指定外部 chart
  • samples: istio 提供的一些示例应用程序
  • tools: 一些工具,如certs用于生成证书

3)为了方便使用istioctl,将bin目录添加到我们的环境变量中:

export PATH=$PWD/bin:$PATH

加入/etc/profile永久生效

[root@k8s-master01 istio-1.20.0]# vim /etc/profile
export PATH=/root/istio-1.20.0/bin:$PATH
[root@k8s-master01 istio-1.20.0]# source /etc/profile

3.2 执行安装

## istio提供的几种内置配置,这些配置文件提供了对 Istio 控制平面和 Istio 数据平面 Sidecar 的定制内容。
[root@master istio-1.15.3]# istioctl profile list
Istio configuration profiles:defaultdemoemptyexternalminimalopenshiftpreview

1、default:根据IstioOperatorAPI 的默认设置启动组件。 建议用于生产部署和
Multicluster Mesh中的 Primary Cluster。您可以运行istioctl profile dump命令来查看默认设置。
2、demo:这一配置具有适度的资源需求,旨在展示 Istio 的功能。 它适合运行
Bookinfo应用程序和相关任务。此配置文件启用了高级别的追踪和访问日志,因此不适合进行性能测试。
3、minimal:与默认配置文件相同,但只安装了控制平面组件。 它允许您使用
Separate Profile配置控制平面和数据平面组件(例如 Gateway)。
4、remote:配置
Multicluster Mesh的 Remote Cluster。
5、empty:不部署任何东西。可以作为自定义配置的基本配置文件。
6、preview:预览文件包含的功能都是实验性。这是为了探索 Istio 的新功能。不确保稳定性、安全性和性能(使用风险需自负)。

标注✔的组件安装在每个配置文件中:
在这里插入图片描述

# 查看demo配置
istioctl profile dump demo

对于本次安装,我们采用demo配置组合。 选择它是因为它包含了一组专为测试准备的功能集合,另外还有用于生产或性能测试的配置组合。

$ istioctl install --set profile=demo -y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete

给命名空间添加标签,指示 Istio 在部署应用的时候,自动注入 Envoy 边车代理

$ kubectl label namespace default istio-injection=enabled
namespace/default labeled

4.部署Bookinfo示例应用

官网:https://istio.io/latest/zh/docs/examples/bookinfo/

Bookinfo应用模仿在线书店的一个分类,显示一本书的信息。 页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。

Bookinfo 应用分为四个单独的微服务:

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

reviews微服务有 3 个版本:

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

下图展示了这个应用的端到端架构

在这里插入图片描述

4.1 启动应用服务
1)进入 Istio 安装目录。

2)Istio 默认自动注入 Sidecar. 请为default命名空间打上标签istio-injection=enabled:

$ kubectl label namespace default istio-injection=enabled

3)使用 kubectl 部署应用:

$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

上面的命令会启动全部的四个服务,其中也包括了 reviews 服务的三个版本(v1、v2 以及 v3)。

4)确认所有的服务和 Pod 都已经正确的定义和启动:

$ kubectl get services
NAME          TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
details       ClusterIP   10.0.0.31    <none>        9080/TCP   6m
kubernetes    ClusterIP   10.0.0.1     <none>        443/TCP    7d
productpage   ClusterIP   10.0.0.120   <none>        9080/TCP   6m
ratings       ClusterIP   10.0.0.15    <none>        9080/TCP   6m
reviews       ClusterIP   10.0.0.170   <none>        9080/TCP   6m

还有:

$ kubectl get pods
NAME                                        READY     STATUS    RESTARTS   AGE
details-v1-1520924117-48z17                 2/2       Running   0          6m
productpage-v1-560495357-jk1lz              2/2       Running   0          6m
ratings-v1-734492171-rnr5l                  2/2       Running   0          6m
reviews-v1-874083890-f0qf0                  2/2       Running   0          6m
reviews-v2-1343845940-b34q5                 2/2       Running   0          6m
reviews-v3-1813607990-8ch52                 2/2       Running   0          6m

5)要确认 Bookinfo 应用是否正在运行,请在某个 Pod 中用curl命令对应用发送请求,例如ratings:

$ kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>

4.2 确定 Ingress 的 IP 和端口
现在 Bookinfo 服务启动并运行中,您需要使应用程序可以从外部访问 Kubernetes 集群, 例如使用浏览器。可以使用网关实现这个目标。

1)为 Bookinfo 应用程序定义一个网关:

使用以下命令创建Istio Gateway:

$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created

确认网关创建完成:

$ kubectl get gateway
NAME               AGE
bookinfo-gateway   32s

2)设置GATEWAY_URL:

$ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

4.3 确认可以从集群外部访问应用
可以用curl命令来确认是否能够从集群外部访问 Bookinfo 应用程序:

$ curl -s "http://${GATEWAY_URL}/productpage" | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>

还可以用浏览器打开网址http://$GATEWAY_URL/productpage,来浏览应用的 Web 页面。 如果刷新几次应用的页面,就会看到productpage页面中会随机展示reviews服务的不同版本的效果 (红色、黑色的星形或者没有显示)。reviews服务出现这种情况是因为我们还没有使用 Istio 来控制版本的路由。

4.4 定义服务版本
在可以使用 Istio 控制 Bookinfo 版本路由之前,您需要定义可用的版本。

Istio 在目标规则中使用subsets定义服务的版本。运行以下命令为 Bookinfo 服务创建默认的目标规则:

$ kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

等待几秒钟,以使目标规则生效。

您可以使用以下命令查看目标规则:

$ kubectl get destinationrules -o yaml

4.5 清理
结束对 Bookinfo 示例应用的体验之后,就可以使用下面的命令来完成应用的删除和清理了:

$ samples/bookinfo/platform/kube/cleanup.sh

流量管理

1、Gateway
在安装 Istio 的时候,安装了入口和出口网关。这两个网关实际都运行了一个 Envoy 代理实例,它们在网格的边缘作为负载均衡器运行。入口网关接收入站连接,而出口网关接收从集群出去的连接。

使用入口网关,我们可以对进入集群的流量应用路由规则。

我们可以有一个指向入口网关的单一外部 IP 地址,并根据Header将流量路由到集群内的不同服务。

在这里插入图片描述

使用 Gateway 资源来配置网关。

下面是一个网关资源的例子:

apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:name: my-gatewaynamespace: defaultspec:selector:istio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- dev.example.com- test.example.com

网关资源描述了负载均衡器的暴露端口、协议、SNI配置等。

GateWay字段名称、字段含义

metadata.name

Gateway 名称

metadata.namespace

Gateway 命名空间

spec.selector

Gateway 使用填写的标签键值对匹配配置下发的边缘代理网关实例

spec.servers.port.number

端口

spec.servers.port.protocol

通信协议,支持:HTTP, HTTPS, GRPC, HTTP2, MONGO, TCP, TLS,请注意同一网关同一端口的协议配置需要保持一致。

spec.servers.port.name

端口名称

spec.severs.hosts

域名,支持通配符 *

spec.servers.tls.httpsRedirect

值为 true 时,边缘代理网关会对所有 http 请求返回 301 重定向,要求客户端发起 https 请求

spec.servers.tls.mode

配置当前端口的 TLS 安全认证模式,如需要开启当前端口的安全认证则需要填写。支持:PASSTHROUGH, SIMPLE, MUTUAL, AUTO_PASSTHROUGH, ISTIO_MUTUAL

spec.servers.tls.credentialName

配置发现 TLS 证书密钥的 secret 的名称

spec.servers.tls.serverCertificate

设置端口的 TLS 证书密钥通过 file mount 形式(不推荐,推荐采用填写 credentialName 字段加载证书私钥)挂载时需要填写的证书路径字段,Istio 默认使用网关所在命名空间下 istio-ingressgateway-certs secret 加载证书至路径 /etc/istio/ingressgateway-certs

spec.servers.tls.privateKey

设置端口的 TLS 证书密钥通过 file mount 形式(不推荐,推荐采用填写 credentialName 字段加载证书私钥)挂载时需要填写的私钥路径字段,Istio 默认使用网关所在命名空间下 istio-ingressgateway-certs secret 加载私钥至路径 /etc/istio/ingressgateway-certs

spec.servers.tls.caCertificates

设置端口的 TLS 证书密钥通过 file mount 形式(不推荐,推荐采用填写 credentialName 字段加载证书私钥)挂载时需要填写的跟证书路径字段,Istio 默认使用网关所在命名空间下 istio-ingressgateway-ca-certs 加载根证书至路径 /etc/istio/ingressgateway-ca-certs,双向认证时需要配置根证书

SNI,即服务器名称指示,是TLS协议的扩展。它指示在“握手”过程开始时浏览器正在联系哪个主机名;允许服务器为多个站点安全地托管多个SSL证书,多个网站存在于同一IP地址上。

上述配置文件的解释:

  • 配置了一个代理,作为负载均衡器
  • 为入口暴露80端口
  • 配置应用于istio入口网关代理
  • hosts字段作为一个过滤器,只有以dev.example.com和test.example.com为目的地的流量会被允许通过。

为了控制和转发流量到集群内运行的实际 Kubernetes 服务,我们必须用特定的主机名(例如dev.example.com和test.example.com)配置一个VirtualService,然后将网关连接到它。

在这里插入图片描述

1.1 简单路由实例
部署一个tomcat,并通过istio网关进行访问。

tomcatdeploy.yaml :

apiVersion: apps/v1
kind: Deployment
metadata:creationTimestamp: nulllabels:app: tomcatname: tomcatnamespace: microservice
spec:replicas: 1selector:matchLabels:app: tomcatstrategy: {}template:metadata:creationTimestamp: nulllabels:app: tomcatspec:containers:- image: hub.c.163.com/library/tomcat:latestimagePullPolicy: IfNotPresentname: tomcatports:- containerPort: 8080resources: {}

创建一个tomcat service,tomcatsvc.yaml :

apiVersion: v1
kind: Service
metadata:creationTimestamp: nulllabels:app: tomcatname: tomcatnamespace: microservice
spec:ports:- port: 80name: tcpprotocol: TCPtargetPort: 8080selector:app: tomcat
status:loadBalancer: {}

部署一个Gateway资源:

ingressgateway80.yaml

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: ingressgateway80
spec:selector:istio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- '*'

这设置*,可以使用ip地址来访问入口网关,如果配置为具体域名,需要修改hosts文件(真实域名需要修改A记录)

现在还没有绑定VirtualService,所以网关还不知道将流量路由到哪里,为tomcat服务创建一个 VirtualService,并将其绑定到 Gateway 资源上:

tomcat-virtualservice.yaml:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: tomcat-virtualservice
spec:hosts:- "*"  gateways: #把VirtualService绑定到ingressgateway80这个网关- ingressgateway80http:- route: #表示路由到tomcat这个service,microservice表示命名空间- destination:host: tomcat.microservice.svc.cluster.localport:number: 80

访问:curl -v 网关外部ip:80

注意其中的header,其中有一个server=istio-envoy,这表明请求经过了envoy代理

2、VirtualService详解
使用 VirtualService 资源在 Istio 服务网格中进行流量路由。通过 VirtualService,我们可以定义流量路由规则,并在客户端试图连接到服务时应用这些规则。

具体的配置含义:

VirtualService字段名称、字段说明

spec.hosts

定义路由规则关联一组的 hosts,可以是带有通配符的 DNS 名称或者 IP 地址(IP 地址仅能应用于来源流量为边缘代理网关)。该字段能应用于 HTTP 和 TCP 流量。在 Kubernetes 环境中,可以使用 service 的名称作为缩写,Istio 会按照 VirtualService所在 namespace 补齐缩写,例如在 default namespace 的 VirtualService 包含 host 缩写 reviews 会被补齐为 reviews.default.svc.cluster.local。为避免误配置,推荐填写 host 全称

spec.gateways

定义应用路由规则的来源流量,可以是一个或多个网关,或网格内部的 sidecar,指定方式为/,保留字段 mesh 表示网格内部所有的 sidecar,当该参数缺省时,会默认填写 mesh,即该路由规则的来源流量为网格内部所有 sidecar

spec.http

定义一组有序的(优先匹配靠前的路由规则)应用于 HTTP 流量的路由规则,HTTP 路由规则会应用于网格内部的 service 端口命名为 http-, http2-, grpc- 开头的流量以及来自 gateway 的协议为 HTTP, HTTP2, GRPC, TLS-Terminated-HTTPS 的流量

spec.http.match

定义路由的匹配规则列表,单个匹配规则项内所有条件是且关系,列表中多个匹配规则之间为或关系

spec.http.route

定义路由转发目的地列表,一条 HTTP 路由可以是重定向或转发(默认),转发的目的地可以是一个或多个服务(服务版本)。同时也可以配置权重、header 操作等行为

spec.http.redirect

定义路由重定向,一条 HTTP 路由可以是重定向或转发(默认),如规则中指定了 passthrough 选项,route、redirect 均会被忽略。可将 HTTP 301 重定向到另外的 URL 或 Authority

spec.http.rewrite

定义重写 HTTP URL 或 Authority headers,不能与重定向同时配置,重写操作会在转发前执行

spec.http.timeout

定义 HTTP 请求的超时时间

spec.http.retries

定义 HTTP 请求的重试策略

spec.http.fault

定义 HTTP 流量的故障注入策略,开启时超时和重试策略不会开启

spec.http.mirror

定义将 HTTP 流量复制到另一个指定的目的端,被复制的流量按照“best effort”原则,sidecar/网关不会等待复制流量的响应结果就会从源目的端返回响应。镜像流量的目的服务端会产生监控指标。

spec.http.mirrorPercent

定义流量镜像的复制百分比,缺省时复制100%的流量。最大值为100

spec.http.corsPolicy

定义 CORS 策略(跨域资源共享,Cross-Origin Resource Sharing,CORS)

spec.http.headers

定义 header 操作规则,包括 request 和 response header 的更新,增加,移除操作

spec.tcp

定义一组有序的(优先匹配靠前的路由规则)应用于 TCP 流量的路由规则,该路由规则会应用于任何非 HTTP 和 TLS 的端口

spec.tcp.match

定义 TCP 流量路由的匹配规则列表,单个匹配规则项内所有条件是且关系,列表中多个匹配规则之间为或关系

spec.tcp.route

定义 TCP 连接转发的目的端

spec.tls

定义一组有序的(优先匹配靠前的路由规则)应用于未终止的 TLS 或 HTTPS 流量的路由规则,该路由规则会应用于网格内部的 service 端口命名为 https-,tls- 开头的流量,来自 gateway 的端口协议为 HTTPS, TLS 的未终止加密流量,Service Entry 使用 HTTPS, TLS 协议的端口。当 https-, tls- 端口未关联 VirtualService 规则时将会被视为 TCP 流量

spec.tls.match

定义 TLS 流量路由的匹配规则列表,单个匹配规则项内所有条件是且关系,列表中多个匹配规则之间为或关系

spec.tls.route

定义连接转发的目的端

2.1 route详解
HTTPRoute规则的功能是:满足HTTPMatchRequest条件的流量都被路由到HTTPRouteDestination,执行重定向(HTTPRedirect)、重写(HTTPRewrite)、重试(HTTPRetry)、故障注入(HTTPFaultInjection)、跨站(CorsPolicy)策略等。HTTPRoute不仅可以做路由匹配,还可以做一些写操作来修改请求本身。

2.2 match
match是进行路由的匹配条件。

其支持以下一些字段的定义:

  • uri、scheme、method、authority:这四个字段都是StringMatch类型,匹配请求时都支持exact、prefix和regex三种模式的匹配。
- match:# 代表匹配uri以advertisment开头的请求- uri:prefix: "/advertisment"
  • headers:匹配请求中的Header,是一个map类型。map的key是字符串类型,value是StringMatch类型。即对于每一个Header的值,都可以使用精确、前缀和正则三种方式进行匹配。
- match:
# 匹配header key为source value为north- headers:source:exact: north
  • port:表示请求服务的端口。大部分服务只开放一个端口,这也是在微服务中推荐的做法,在这种场景下可以不指定port;
  • sourceLabels:是一个map类型的键值对,表示请求来源负载匹配标签。这在很多情况有用,可以对一组服务都打一个相同的标签,然后使用sourceLabels字段对这些服务实施相同的流量规则。在Kubernetes平台上,这里的Label就是Pod上的标签。
http:
- match:    - sourceLabels:app: testAversion: v2
  • gateway:表示规则应用的Gateway名称,语义同VirtualService 上面的gateway定义,是一个更细的Match条件,会覆盖在VirtualService上配置的gateway。
    在VirtualService中match字段都是数组类型。HTTPMatchRequest中的诸多属性如uri、header、method等都是“与”逻辑,而数组中几个元素间关系是“或”逻辑。

例子:

- match:- heraders:source:exact: northuri:prefix: "/advertisment"- uri:prefix: "/forecast"

match包含两个HTTPMatchRequest元素,其条件的语义是:headers中的source取值为“north”,且uri以“/advertisment”开头的请求,或者uri以“/forecast”开头的请求。

2.3 路由目标(RouteDestination)
route字段是一个HTTPRouteDestination类型的数组,表示满足条件的流量目标。

在HTTPRouteDestination中主要有三个字段:destination(请求目标)、weight(权重)、和headers(HTTP头操作),destination是必选字段。

  • destination: 这个字段是一个Destination类型结构,通过host、subset和port三个属性来描述。表示最终将流量路由到此目标。host是Destination必选字段,表示在Istio中注册的服务名,建议写全域名。subset表示在host上定义的一个子集。例如,在灰度发布中将版本定义为subset,配置路由策略会将流量转发到不同版本的subset上。
.....
spec:hosts:- forecasthttp:- route:- destination:host: forecastsubset: v2- destination:host: forecastsubset: v1
  • weight: 表示流量分配的比例,在一个route下多个destination的weight总和要求是100。默认100,必填字段。示例:从原有的v1版本中切分20%的流量到v2版本,这也是灰度发布常用的一个流量策略,即不区分内容,平等的从总流量中切出一部分流量给新版本。
.....
spec:hosts:- forecasthttp:- route:- destination:host: forecastsubset: v2weight: 20- destination:host: forecastsubset: v1weight: 80
  • headers:提供了对HTTP header的一种操作机制,可以修改一次HTTP请求中的Request或Response的值,包含request和response两个字段。
  • request:表示在发请求给目标地址时修改Request的header。
  • response:表示在返回应答时修改Response的header
    对应的类型都是HeaderOperations类型,使用set、add、remove字段来定义对Header的操作。
  • set:使用map上的key和value覆盖Request和Response中对应的Header
  • add:追加map上的key和value到原有的Header
  • remove:删除在列表中华指定的Header

2.4 HTTP重定向(HTTPRedirect)
Istio对于HTTP除了做流量路由,还可以做适当的其他操作,很多原来需要在代码中进行的HTTP操作,在使用Istio后通过这些配置都可以达到同样的效果。

通过HTTPRedirect可以发送一个301重定向的应答给服务调用方,简单讲就是从一个URL到另外一个URL的永久重定向。用户输入一个URL,通过HTTPRedirect可以将其跳转到另一个URL。比较常见的场景:有一个在线网站,网址变了,通过这样的重定向,可以在用户输入老地址时跳转到新地址。比如:

  • 用户请求老地址:
    http://forecast/advertisement
  • 服务端返回301重定向新地址
    http://new-forecast/recommendation/activity
  • 用户请求新地址
    http://new-forecast/recommendation/activity
  • 得到新地址
    HTTPRedirect包括两个重要的字段来表示重定向的目标。
  • uri:替换URL中的uri部分
  • authority:替换URL中的Authority部分

示例:

apiVersion:networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: forecastnamespace: weather
spec:hosts:- forecasthttp:- match:- uri: prefix: /advertisementredirect:uri: /recommendation/activityauthority: new-forecast

对forecast服务所有前缀是/advertisement的请求都会被重定向到new-forecast的/recommendation/activity地址。

2.5 HTTP重写(HTTPRewrite)
通过HTTP重写可以在将请求转发给目标服务前修改HTTP请求中指定部分的内容,不同于重定向,用户是可见,HTTP重写对用户是不可见的,因为是在服务端进行的。

和重定向配置类似,重写HTTP也包括uri和authority这两个字段。

  • uri:重写URL中的Path部分
  • authority:重写URL中的Authority

和HTTPRedirect规则稍有不同的是,HTTPRedirect的uri只能替换全部的Path,HTTPRewrite的uri是可以重写前缀的,即如果原来匹配条件是前缀匹配,则修改后只修改匹配到的前缀。

示例:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: forecastnamespace: weather
spec:hosts:- forecasthttp:- match:- uri:prefix: /advertisementrewrite:uri: /recommendation/activityroute:- destination:host: forecast

前缀匹配/advertisement的请求,其请求uri中的这部分前缀会被/recommendation/activity替换

2.6 HTTP重试(HTTPRetry)
HTTP重试是解决很多请求异常最直接、简单的方法,尤其是在工作环境比较复杂的场景下,可提高总体的服务质量。

但是重试使用不当也会有问题,最糟糕的情况是重试一直不成功,反而增加延迟和性能开销。所以,根据系统运行环境、服务自身特点,配置适当的重试规则显得尤为重要。

HTTPRetry可以定义请求失败时的重试策略,重试策略包括重试次数、超时、重试条件等,这里分别描述相应的三个字段。

  • attempts:必选字段,定义重试的次数
  • perTryTimeout:每次重试超时的时间,单位可以是ms、s、m和h
  • retryOn:进行重试的条件,可以是多个条件,以逗号分隔

其中重试条件retryOn的取值可以包括以下几种:

  • 5xx:在上游服务返回5xx应答码,或者在没有返回时重试
  • gateway-error:类似于5xx异常,只对502、503和504应答码进行重试。
  • connect-failure:在链接上游服务失败时重试
  • retriable-4xx:在上游服务返回可重试的4xx应答码时执行重试。
  • refused-stream:在上游服务使用REFUSED_STREAM错误码重置时执行重试。
  • cancelled:gRPC应答的Header中状态码是cancelled时执行重试。
  • deadline-exceeded:在gRPC应答的Header中状态码是deadline-exceeded时执行重试
  • internal:在gRPC应答的Header中状态码是internal时执行重试
  • resource-exhausted:在gRPC应答的Header中状态码是resource-exhausted时执行重试
  • unavailable:在gRPC应答的Header中状态码是unavailable时执行重试。

示例:

配置了一个重试策略,在5xx,connect-failure条件下进行最多5次重试,每次重试超时为3秒

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
medata:name: forecastnamespace: weather
spec:hosts:- forecasthttp:- route:- destination:host: forecastretries:attempts: 5perTryTimeout: 3sretryOn: 5xx,connect-failure

2.7 HTTP流量镜像(Mirror)
HTTP流量镜像指的是将流量转发到原目标地址的同时将流量给另外一个目标地址镜像一份。把生产环境中的实际流量镜像一份到另外一个系统上,完全不会对生产系统产生影响,这里只是镜像了一份流量,数据面代理只需要关注原来转发的流量就可以,不用等待镜像目标地址的返回。

apiVersion: networking.istio.io:v1alpha3
kind: VirtualService
metadata:name: forecastnamespace: weather
spec:hosts:- forecasthttp:- route:- destination:host: forecastsubset: v1mirror:host: forecastsubset: v2

2.8 HTTP故障注入(HTTPFaultInjection)
HTTPFaultInjection通过delay和abort两个字段设置延时和中止两种故障,分别表示Proxy延迟转发HTTP请求和中止HTTP请求。

延迟故障注入HTTPFaultInjection中的延迟故障使用HTTPFaultInjection.Delay 类型描述延时故障,表示在发送请求前进行一段延时,模拟网络、远端服务负载均衡等各种原因导致的失败,主要是如下两个字段:

  • fixedDelay:一个必选字段,表示延迟时间,单位可以是毫秒、秒、分钟和小时,要求至少大于1毫秒
  • percentage:配置的延迟故障作用在多少的比例的请求上,通过这种方式可以只让部分请求发生故障。

示例:forecast服务v1版本上的1.5%的请求产生10秒的延时

......
route:
- destination:host: forecastsubset: v1
fault:delay:percenttage:value: 1.5fixedDelay: 10s

请求中止故障注入HTTPFaultInjection 使用HTTPFaultInjection.Abort 描述中止故障,模拟服务端异常,给调用的客户端返回预先定义的错误状态码,主要有以下两个字段:

  • httpStatus:是一个必选字段,表示中止的HTTP状态码
  • percentage:配置中止故障作用在多少比例的请求上,通过这种方式可以只让部分请求发生故障,用法通延迟故障

示例:让forecast服务v1版本上1.5%的请求返回“500”代码

......
route:
- destination:host: forecastsubset: v1
fault:abort:percnetage: value: 1.5httpStatus: 500

2.9 HTTP跨域资源共享(CorsPolicy)
当一个资源向该资源所在服务器的不同的域发起请求时,就会产生一个跨域的HTTP请求。出于安全考虑,浏览器会限制从脚本发起的跨域HTTP请求。通过跨域资源共享CORS(Cross Origin Resource Sharing)机制可允许web应用服务器进行跨域访问控制,使跨域数据传递安全进行。在实现上是在HTTP Header中追加一些额外的信息来通知浏览器准许以上访问。

在 VirtualService 中可以对满足条件的请求配置跨域资源共享。有allowOrigin、allowMethods、allowHeader、exposeHeader、maxAge、allowCredentials,其实都是被转化为 Access-Control-* 的Header。 如下所示,允许源自news.com的GET方法的请求的访问:

......
http:
- route:- destination:host: forecastcorsPolicy:allowOrigin:- news.comallowMethods:- GETmaxAge: "2d"

3、DestinationRule
在讲解virtualService中,路由目标对象destination中会包含Service子集的subset字段,这个服务子集就是通过DestinationRule定义的。

比如:

apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:name: customers-destinationspec:host: customers.default.svc.cluster.localsubsets:- name: v1labels:version: v1- name: v2labels:version: v2

上述定义了两个子集,v1和v2,同时根据标签来决定哪个Pod需要包含在子集中。

DestinationRule字段名称、字段含义

spec.host

关联 DestinationRule 配置的服务名称,可以是自动发现的服务(例如 Kubernetes service name),或通过 ServiceEntry 声明的 hosts。如填写的服务名无法在上述源中找到,则该 DestinationRule 中定义的规则无效

spec.subsets

定义服务的版本(subsets),版本可通过标签键值对匹配匹配服务中的endpoints。可以在 subsets 级覆盖流量策略配置

spec.trafficPolicy

定义流量策略,包括负载均衡、连接池、健康检查、TLS 策略

spec.trafficPolicy.loadBalancer

配置负载均衡算法,可配置:简单负载均衡算法(round robin, least conn, random…),一致性哈希(会话保持,支持按 header name,cookie,IP,query parameter 哈希),地域感知负载均衡算法

spec.trafficPolicy.connectionPool

配置与上游服务的连接量,可设置 TCP/HTTP 的连接池

spec.trafficPolicy.outlierDetection

配置从负载均衡池中驱逐不健康的 hosts

spec.trafficPolicy.tls

连接上游服务的 client 端 TLS 相关配置,与 PeerAuthentication 策略(server 端 TLS 模式配置)配合使用

spec.trafficPolicy.portLevelSettings

配置端口级别的流量策略,端口级别的流量策略会覆盖服务 / subsets 级别的流量策略配置

通过 DestinationRule,我们可以定义设置,如负载均衡配置、连接池大小、局部异常检测等,在路由发生后应用于流量。我们可以在trafficPolicy字段下设置流量策略。以下是这些设置:

  • 负载均衡器设置
  • 连接池设置
  • 局部异常点检测
  • 客户端 TLS 设置
  • 端口流量策略

3.1 负载均衡器设置
通过负载均衡器设置,我们可以控制目的地使用哪种负载均衡算法。

示例:

apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:name: customers-destinationspec:host: customers.default.svc.cluster.localtrafficPolicy:loadBalancer:simple: ROUND_ROBIN #将负载均衡算法设置为轮询方式subsets:- name: v1labels:version: v1- name: v2labels:version: v2
  • simple字段:提供的负载均衡算法如下:

ROUND_ROBIN:轮询算法,如果未指定,则默认采用这种算法。
LEAST_CONN:最少连接算法,算法实现是从两个随机选择的服务后端选择一个活动请求数较少 的后端实例。
RANDOM:从可用的健康实例中随机选择一个。
PASSTHROUGH:直接转发连接到客户端连接的目标地址,即没有做负载均衡。

  • consistentHash字段:一致性hash,并根据 HTTP 头、cookies 或其他请求属性提供会话亲和性。

httpHeaderName: 基于Header。
httpCookie: 基于Cookie。
useSourceIp:基于源IP计算哈希值。
minimumRingSize:哈希环上虚拟节点数的最小值,节点数越多则负载均衡越精细。

trafficPolicy:loadBalancer:consistentHash:httpCookie:name: locationttl: 4s

3.2 连接池配置
可以在 TCP 和 HTTP 层面应用于上游服务的每个主机,我们可以用它们来控制连接量

TCP连接池配置

  • maxConnections:上游服务的所有实例建立的最大连接数,默认是 1024,属于 TCP层的配置,对于 HTTP,只用于 HTTP/1.1,因为 HTTP/2对每个主机都使用单个连接。
  • connectTimeout:TCP连接超时,表示主机网络连接超时,可以改善因调用服务变慢导致整个链路变慢的情况。
  • tcpKeepalive:设置TCP keepalives,是Istio1.1新支持的配置,定期给对端发送一个keepalive的探测包,判断连接是否可用。
spec:host: myredissrv.prod.svc.cluster.localtrafficPolicy:connectionPool:tcp:maxConnections: 50connectTimeout: 25mstcpKeepalive:probes: 5time: 3600interval: 60s

http连接池配置

  • http1MaxPendingRequests: 最大等待 HTTP 请求数,默认值是 1024,只适用于HTTP/1.1 的服务,因为 HTTP/2 协议的请求在到来时会立即复用连接,不会在连接池等待。
  • http2MaxRequests:最大请求数,默认是1024。只适用于HTTP/2服务,因为HTTP/1.1使用最大连接数maxConnections即可,表示上游服务的所有实例处理的最大请求数
  • maxRequestsPerConnection:每个连接的最大请求数。HTTP/1.1和HTTP/2连接池都遵循此参数。如果没有设置,则没有限制。设置为1时表示每个连接只处理一个请求,也就是禁用了Keep-alive
  • maxRetries:最大重试次数,默认是3,表示服务可以执行的最大重试次数。如果调用端因为偶尔抖动导致请求直接失败,则可能会带来业务损失,一般建议配置重试,若重试成功则可正常返回数据, 只不过比原来响应得慢一点,但重试次数太多会影响性能,要谨慎使用。
  • idleTimeout:空闲超时,定义在多长时间内没有活动请求则关闭连接。
    http可以和tcp配置使用,示例:
spec:host: myredissrv.prod.svc.cluster.localtrafficPolicy:connectionPool:tcp:maxConnections: 80connectTimeout: 25mshttp:http2MaxRequests: 800maxRequestsPerConnection: 10

配置最大80个连接,只允许最多有800个并发请求,每个连接 的请求数不超过10个,连接超时是25毫秒。

3.3 异常点检测
异常点检测是一个断路器的实现,它跟踪上游服务中每个主机(Pod)的状态。如果一个主机开始返回 5xx HTTP 错误,它就会在预定的时间内被从负载均衡池中弹出。对于 TCP 服务,Envoy 将连接超时或失败计算为错误。

两种健康检查:

  • 主动型的健康检查:定期探测目标服务实例,根据应答来判断服务实例的健康状态。如负载均衡器中的健康检查
  • 被动型的健康检查:通过实际的访问情况来找出不健康的实例,如isito中的异常点检查。

异常实例检查相关的配置:

  • consecutiveErrors:实例被驱逐前的连续错误次数,默认是 5。对于 HTTP 服务,返回 502、503 和 504 的请求会被认为异常;对于 TCP 服务,连接超时或者连接错误事件会被认为异常。
  • interval:驱逐的时间间隔,默认值为10秒,要求大于1毫秒,单位可以是时、分、毫秒。
  • baseEjectionTime:最小驱逐时间。一个实例被驱逐的时间等于这个最小驱逐时间乘以驱逐的次数。这样一个因多次异常被驱逐的实例,被驱逐的时间会越来越长。默认值为30秒,要求大于1毫秒,单 位可以是时、分、毫秒。
  • maxEjectionPercent:指负载均衡池中可以被驱逐的故障实例的最大比例,默认是10%,设置这个值是为了避免太多的服务实例被驱逐导致服务整体能力下降。
  • minHealthPercent:最小健康实例比例,是Istio 1.1新增的配置。当负载均衡池中的健康实例数的 例大于这个比例时,异常点检查机制可用;当可用实例数的比例小于这个比例时,异常点检查功能将被禁用,所有服务实例不管被认定为健康还是不健康,都可以接收请求。参数的默认值为50%。

下面是一个例子,它设置了 500 个并发的 HTTP2 请求(http2MaxRequests)的限制,每个连接不超过 10 个请求(maxRequestsPerConnection)到该服务。每 5 分钟扫描一次上游主机(Pod)(interval),如果其中任何一个主机连续失败 10 次(contracticalErrors),Envoy 会将其弹出 10 分钟(baseEjectionTime)。

trafficPolicy:connectionPool:http:http2MaxRequests: 500maxRequestsPerConnection: 10outlierDetection:consecutiveErrors: 10interval: 5mbaseEjectionTime: 10m

3.4 TLS 设置
包含任何与上游服务连接的 TLS 相关设置。下面是一个使用提供的证书配置 mTLS 的例子:

trafficPolicy:tls:mode: MUTUALclientCertificate: /etc/certs/cert.pemprivateKey: /etc/certs/key.pemcaCertificates: /etc/certs/ca.pem

mtls : 双向认证,客户机和服务器都通过证书颁发机构彼此验证身份。

由同一个 root ca 生成两套证书,即客户端证书和服务端证书。客户端使用 https 访问服务端时,双方会交换证书,并进行认证,认证通过方可通信。

其他支持的 TLS 模式有DISABLE(没有 TLS 连接),SIMPLE(在上游端点发起 TLS 连接),以及ISTIO_MUTUAL(与MUTUAL类似,使用 Istio 的 mTLS 证书)。

3.5 端口流量策略
在端口上配置流量策略,且端口上流量策略会覆盖全局的流量策略。关于配置方法与TrafficPolicy没有大差别,一个关键的差别字段就是port。

示例:

trafficPolicy:connectionPool:tcp:maxConnections: 80portLevelSettings:- port:number: 80loadBalancer:simple: LEAST_CONNconnectionPool:tcp:maxConnections: 100- port:number: 8000loadBalancer:simple: ROUND_ROBIN

3.6 服务子集
Subset,定义服务的子集。

属性:

  • name: Subset的名字,为必选字段。通过VirtualService引用的就是这个名字。
  • labels:Subset上的标签,通过一组标签定义了属于这个Subset的服务实例。比如最常用的标识服务版本的Version标签。
  • trafficPolicy:应用到这个Subset上的流量策略。

示例:

.....
spec:hosts: forecastsubsets:- name: v2labels:version: v2trafficPolicy:connectionPool:tcp:maxConnections: 80    # 给一个特定的Subset配置最大连接数

4. 实战
使用权重在不同的服务版本之间路由流量
先部署一个Gateway

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: gateway
spec:selector:istio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- '*'
[root@master weight]# kubectl apply -f gateway.yaml
#将default加入istio中
[root@master weight]# kubectl label namespace default istio-injection=enabled

部署一个应用(deploy和service)

 apiVersion: apps/v1kind: Deploymentmetadata:name: web-frontendlabels:app: web-frontendspec:replicas: 1selector:matchLabels:app: web-frontendtemplate:metadata:labels:app: web-frontendversion: v1spec:containers:- image: web-frontend:1.0.0imagePullPolicy: IfNotPresentname: webports:- containerPort: 8080env:- name: CUSTOMER_SERVICE_URLvalue: 'http://customers.default.svc.cluster.local'
---kind: ServiceapiVersion: v1metadata:name: web-frontendlabels:app: web-frontendspec:selector:app: web-frontendports:- port: 80name: httptargetPort: 8080
kubectl apply -f web-frontend.yaml

CUSTOMER_SERVICE_URL是说上述的web-frontend服务需要访问一个customers的服务,所以我们需要部署一个customer的服务

部署 Customers 服务的 v1版本

apiVersion: apps/v1
kind: Deployment             
metadata:name: customers-v1labels:app: customersversion: v1
spec:replicas: 1selector:matchLabels:app: customersversion: v1template:metadata:labels:app: customersversion: v1spec:containers:- image: customers:1.0.0imagePullPolicy: IfNotPresentname: svcports:- containerPort: 3000
---
kind: Service
apiVersion: v1
metadata:name: customerslabels:app: customers
spec:selector:app: customersports:- port: 80name: httptargetPort: 3000
kubectl apply -f customers-v1.yaml

为web-frontend创建一个 VirtualService,并将其绑定到 Gateway 资源上

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: web-frontend
spec:hosts:- '*'gateways:- gatewayhttp:- route:- destination:host: web-frontend.default.svc.cluster.localport:number: 80
kubectl apply -f web-frontend-vs.yaml

访问gateway

创建 DestinationRule,并定义两个子集,代表 v1 和 v2 版本

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: customers
spec:host: customers.default.svc.cluster.localsubsets:- name: v1labels:version: v1- name: v2labels:version: v2
kubectl apply -f customers-dr.yaml 

创建 VirtualService 并在目标中指定 v1子集

 apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: customersspec:hosts:- 'customers.default.svc.cluster.local'http:- route:- destination:host: customers.default.svc.cluster.localport:number: 80subset: v1

每当有请求被发送到 Kubernetes Customers 服务时,它将被路由到同一服务的 v1子集

kubectl apply -f customers-vs.yaml

部署 v2 版的 Customers 服务

 apiVersion: apps/v1kind: Deploymentmetadata:name: customers-v2labels:app: customersversion: v2spec:replicas: 1selector:matchLabels:app: customersversion: v2template:metadata:labels:app: customersversion: v2spec:containers:- image: customers:2.0.0imagePullPolicy: IfNotPresentname: svcports:- containerPort: 3000
kubectl apply -f customers-v2.yaml

使用weight字段并修改 VirtualService,使 50% 的流量被发送到 v1 子集,另 50% 发送到 v2 子集

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: customers
spec:hosts:- 'customers.default.svc.cluster.local'http:- route:- destination:host: customers.default.svc.cluster.localport:number: 80subset: v1weight: 50- destination:host: customers.default.svc.cluster.localport:number: 80subset: v2weight: 50
kubectl apply -f customers-50-50.yaml

测试刷新页面,在v1和v2版本之间切换,更改权重 刷新页面观察

使用请求属性在多个服务版本之间路由流量
部署 Gateway

 apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:name: gatewayspec:selector:istio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- '*'
kubectl apply -f gateway.yaml 

部署Web前端、Customers v1、Customers v2,以及相应的 VirtualServices 和 DestinationRule。一旦一切部署完毕,所有流量将被路由到

Customers v1。apiVersion: apps/v1kind: Deploymentmetadata:name: web-frontendlabels:app: web-frontendspec:replicas: 1selector:matchLabels:app: web-frontendtemplate:metadata:labels:app: web-frontendversion: v1spec:containers:- image: web-frontend:1.0.0imagePullPolicy: IfNotPresentname: webports:- containerPort: 8080env:- name: CUSTOMER_SERVICE_URLvalue: 'http://customers.default.svc.cluster.local'
---kind: ServiceapiVersion: v1metadata:name: web-frontendlabels:app: web-frontendspec:selector:app: web-frontendports:- port: 80name: httptargetPort: 8080
---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: web-frontendspec:hosts:- '*'gateways:- gatewayhttp:- route:- destination:host: web-frontend.default.svc.cluster.localport:number: 80
kubectl apply -f web-frontend.yaml
 apiVersion: apps/v1kind: Deploymentmetadata:name: customers-v1labels:app: customersversion: v1spec:replicas: 1selector:matchLabels:app: customersversion: v1template:metadata:labels:app: customersversion: v1spec:containers:- image: customers:1.0.0imagePullPolicy: IfNotPresentname: svcports:- containerPort: 3000
---apiVersion: apps/v1kind: Deploymentmetadata:name: customers-v2labels:app: customersversion: v2spec:replicas: 1selector:matchLabels:app: customersversion: v2template:metadata:labels:app: customersversion: v2spec:containers:- image: customers:2.0.0imagePullPolicy: IfNotPresentname: svcports:- containerPort: 3000
---kind: ServiceapiVersion: v1metadata:name: customerslabels:app: customersspec:selector:app: customersports:- port: 80name: httptargetPort: 3000
---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: customersspec:hosts:- 'customers.default.svc.cluster.local'http:- route:- destination:host: customers.default.svc.cluster.localport:number: 80subset: v1
---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:name: customersspec:host: customers.default.svc.cluster.localsubsets:- name: v1labels:version: v1- name: v2labels:version: v2
kubectl apply -f customers.yaml

此时测试,流量都来自于v1.

更新VirtualService,如果请求中包含一个 headeruser: debug,就把流量路由到 Customers v2,没有就路由到v1

 apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: customersspec:hosts:- 'customers.default.svc.cluster.local'http:- match:- headers:user:exact: debugroute:- destination:host: customers.default.svc.cluster.localport:number: 80subset: v2- route:- destination:host: customers.default.svc.cluster.localport:number: 80subset: v1
kubectl apply -f customers-vs.yaml

测试curl -H “user: debug” http://GATEWAY_URL/

5、实战:观察故障注入
部署 Web 前端和 Customer V1 服务。然后,我们将在 Zipkin、Kiali 和 Grafana 中注入故障和延迟,并观察它们
在这里插入图片描述

部署Gateway

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: ingressgateway80
spec:selector:istio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- '*'
kubectl apply -f ingressgateway80.yaml 

部署 Web Frontend、Service 和 VirtualService。

apiVersion: apps/v1
kind: Deployment
metadata:name: web-frontendlabels:app: web-frontend
spec:replicas: 1selector:matchLabels:app: web-frontendtemplate:metadata:labels:app: web-frontendversion: v1spec:containers:- image: web-frontend:1.0.0imagePullPolicy: Alwaysname: webports:- containerPort: 8080env:- name: CUSTOMER_SERVICE_URLvalue: 'http://customers.default.svc.cluster.local'
---
kind: Service
apiVersion: v1
metadata:name: web-frontendlabels:app: web-frontend
spec:selector:app: web-frontendports:- port: 80name: httptargetPort: 8080
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: web-frontend
spec:hosts:- '*'gateways:- ingressgateway80http:- route:- destination:host: web-frontend.default.svc.cluster.localport:number: 80
kubectl apply -f web-frontend.yaml

部署 Customers v1 和相应的资源

apiVersion: apps/v1
kind: Deployment
metadata:name: customers-v1labels:app: customersversion: v1
spec:replicas: 1selector:matchLabels:app: customersversion: v1template:metadata:labels:app: customersversion: v1spec:containers:- image: customers:1.0.0imagePullPolicy: Alwaysname: svcports:- containerPort: 3000
---
kind: Service
apiVersion: v1
metadata:name: customerslabels:app: customers
spec:selector:app: customersports:- port: 80name: httptargetPort: 3000
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: customers
spec:host: customers.default.svc.cluster.localsubsets:- name: v1labels:version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: customers
spec:hosts:- 'customers.default.svc.cluster.local'http:- route:- destination:host: customers.default.svc.cluster.localport:number: 80subset: v1fault:delay:percent: 50fixedDelay: 5s
kubectl apply -f customers-delay.yaml

测试另开一个窗口,循环请求
while true; do curl http://$GATEWAY_URL/; done
打开Grafana ,进入Istio Service Dashboard,你会发现客户端请求持续时间图上的持续时间增加了
在这里插入图片描述

打开zipkin,选择serviceName和web-frontend.default,然后添加minDuration条件,输入 5s,点击搜索按钮,找到 trace。
点击其中一个 trace,打开详细信息页面。在详情页上,我们会发现持续时间是 5 秒。
在这里插入图片描述

单个 trace 有 4 个 span——点击 第3 个span,代表从web-frontend到客户服务的请求。你会注意到在细节中,response_flags标签设置为DI。“DI” 代表 “延迟注入”,表示该请求被延迟了。

再次更新 VirtualService,这一次,我们将注入一个故障,对 50% 的请求返回 HTTP 500

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: customers
spec:hosts:- 'customers.default.svc.cluster.local'http:- route:- destination:host: customers.default.svc.cluster.localport:number: 80subset: v1fault:abort:httpStatus: 500percentage: value: 50
kubectl apply -f customers-fault.yaml

回到 Grafana 并打开 Istio Service Dashboard,我们会注意到客户端的成功率在下降。
在这里插入图片描述

在 Zipkin 中也有类似的情况。如果我们再次搜索 trace(我们可以删除最小持续时间),我们会发现有错误的 trace 会以红色显示打开 Kiali,通过点击 Graph 项查看服务图。

在这里插入图片描述

你会注意到web-frontend服务有一个红色的边框

在这里插入图片描述

点击web-frontend服务,看看右边的侧边栏,你会发现 HTTP 请求的细节。图中显示了成功和失败的百分比,这两个数字都在 50% 左右,这与我们在 VirtualService 中设置的百分比值相一致。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/64932.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter web - 5 项目打包优化

介绍 目前 flutter 对 web 的打包产物优化较少&#xff0c;存在 main.dart.js 单个文件体积过大问题&#xff0c;打包文件名没有 hash 值&#xff0c;如果有使用 CDN 会存在资源不能及时更新问题。本文章会对这些问题进行优化。 优化打包产物体积 从打包产物中可以看到其中 …

KingbaseES(金仓数据库)入门学习

前言 金仓是一种多进程架构&#xff0c;每一个连接到服务器的会话&#xff0c;在服务器上面都会为该会话分配进程 图形化界面管理 新建数据库名 然后新建一个模式 再创建一个表 新建一个表&#xff0c;然后设置列名 记得要保存 查询数据 也可以新建数据表&#xff0c;用命令…

基于Springboot的数字科技风险报告管理系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实…

【大模型】ChatGPT 打造个人专属GPTs助手使用详解

目录 一、前言 二、GPTs介绍 2.1 GPTs是什么 2.2 GPTs工作原理 2.3 GPTs 主要功能 2.4 GPTs 应用场景 2.5 GPTs 优缺点 三、GPTs 创建个人专属应用操作过程 3.1 内置GPTs模板 3.1.1 内置GPTs使用过程 3.2 手动配置方式创建 GPTs 3.2.1 创建过程 3.3 使用对话方式创…

Cobalt Strike 4.8 用户指南-第十四节 Aggressor 脚本

14.1、什么是Aggressor脚本 Aggressor Script 是Cobalt Strike 3.0版及更高版本中内置的脚本语言。Aggressor 脚本允许你修改和扩展 Cobalt Strike 客户端。 历史 Aggressor Script 是 Armitage 中开源脚本引擎Cortana的精神继承者。Cortana 是通过与 DARPA 的网络快速跟踪计…

Vue(四)

1.Vuex 1.1 Vuex是什么 Vuex 是一个插件&#xff0c;可以帮我们管理 Vue 通用的数据。例如&#xff1a;购物车数据、个人信息数据。 1.2 vuex的使用 1.安装 vuex 安装 vuex 与 vue-router 类似&#xff0c;vuex 是一个独立存在的插件&#xff0c;如果脚手架初始化没有选 v…

基础9 CRTP 与 Expression Templates

目录 一、奇异递归模版(CRTP) 二、表达式模板 &#x1f349; 概要 &#x1f347; 奇异递归模板模式&#xff08;CRTP&#xff09; 动机与原理 &#x1f353; 表达式模板&#xff08;Expression Templates&#xff09; 动机与原理 &#x1f348; 示例代码 &#x1f35…

分布式协同 - 分布式事务_TCC解决方案

文章目录 导图Pre流程图2PC VS 3PC VS TCC2PC&#xff08;Two-Phase Commit&#xff0c;二阶段提交&#xff09;3PC&#xff08;Three-Phase Commit&#xff0c;三阶段提交&#xff09;TCC&#xff08;Try-Confirm-Cancel&#xff09;2PC、3PC与TCC的区别2PC、3PC与TCC的联系 导…

脑肿瘤检测数据集,对9900张原始图片进行YOLO,COCO,VOC格式的标注

脑肿瘤检测数据集&#xff0c;对9900张原始图片进行YOLO&#xff0c;COCO&#xff0c;VOC格式的标注 数据集分割 训练组 70&#xff05; 6930图片 有效集 20&#xff05; 1980图片 测试集 10&#xff05; 990图片 预处理 静态裁剪&#xff1a; 24-82&…

步进电机接线和stm32引脚分配

实验设备 24v&#xff08;12-48 v&#xff09;直流电源 stm32f103最小系统板 步进电机驱动器 采用混合式二相步进电机J-5718HBS2401-野火42步进电机&#xff0c;驱动器为野火EBF-MSD4805 本人参考接线方式如下&#xff1a; 如上图所示通常采用共阴接线方式&#xff0c;具体…

极乐 15.2.6 | 清爽版简约美观音乐软件,支持网易云歌单导入

极乐是一款使用起来非常轻松的音乐播放软件&#xff0c;它拥有清新简洁的画面&#xff0c;专注于音乐播放功能。最新版本全面升级了64位架构&#xff0c;带来了前所未有的性能提升和更稳定的体验。通过优化内存管理&#xff0c;降低了应用对系统资源的占用&#xff0c;确保设备…

4、mysql高阶语句

mysql高阶语句是对复杂的条件进行查询的操作。 排序—order by 加了desc表示由大到小 1、查询name和score&#xff0c;地址都是云南西路的按id进行由小到大排序 2、查询name和score&#xff0c;先按hobbid进行排序&#xff0c;再把结果按id进行排序 第一段字段必须要有相同的…

Docker部署GitLab服务器

一、GitLab介绍 1.1 GitLab简介 GitLab 是一款基于 Git 的开源代码托管平台&#xff0c;集成了版本控制、代码审查、问题跟踪、持续集成与持续交付&#xff08;CI/CD&#xff09;等多种功能&#xff0c;旨在为团队提供一站式的项目管理解决方案。借助 GitLab&#xff0c;开发…

hadoop中hive本地模式安装mysql源不成功

目录 1.更改DNS配置 2.替换yun源 3.替换掉后&#xff0c;在执行 4.重新安装mysql源 hive本地模式安装mysql源出错 yum install mysql mysql-server mysql-devel -y 解决&#xff1a; 1.更改DNS配置 vi /etc/resolv.conf 添加下面内容&#xff1a; nameserver 8.8.8.8 …

RISC-V架构的压缩指令集介绍

1、压缩指令集介绍 RISC-V的压缩指令集&#xff08;C扩展&#xff09;‌是一种设计用于减少代码大小和提高性能的技术。标准的RISC-V指令是32位&#xff0c;压缩指令集可以将部分32位的指令用16位的指令替代&#xff0c;从未减小程序占用存储空间的大小&#xff0c;提高指令密…

Day13 苍穹外卖项目 工作台功能实现、Apache POI、导出数据到Excel表格

目录 1.工作台 1.1 需求分析和设计 1.1.1 产品原型 1.1.2 接口设计 1.2 代码导入 1.2.1 Controller层 1.2.2 Service层接口 1.2.3 Service层实现类 1.2.4 Mapper层 1.3 功能测试 1.4 代码提交 2.Apache POI 2.1 介绍 2.2 入门案例 2.2.1 将数据写入Excel文件 2.2.2 读取Excel文…

集星獭 | 高性能编排:为实时数据集成而生!

概要介绍 服务编排作为集星獭驱动业务流、数据流中不可或缺的重要环节&#xff0c;其基于分布式架构打造&#xff0c;提供了高可用、易扩展的可视化流程任务调度功能。 原服务编排的设计初衷是专注于任务调度&#xff0c;提供高性能任务调度&#xff0c;但是在实时调用方面的…

达梦8-达梦数据的示例用户和表

1、示例库说明&#xff1a; 创建达梦数据的示例用户和表&#xff0c;导入测试数据。 在完成达梦数据库的安装之后&#xff0c;在/opt/dmdbms/samples/instance_script目录下有用于创建示例用户的SQL文件。samples目录前的路径根据实际安装情况进行修改&#xff0c;本文将达梦…

windwos defender实现白名单效果(除了指定应用或端口其它一律禁止)禁止服务器上网

一、应用场景说明 当我们的一台windows服务器中毒&#xff0c;变成别人肉鸡&#xff0c;不断向外请示非法网站或攻击其它服务器。 要彻底清除相关木马或病毒往往需要的时间比较长&#xff0c;比较有效的方法是禁止服务器主动向外发包除了网站端口和远程程序除外。 其实这就是一…

1 JVM JDK JRE之间的区别以及使用字节码的好处

JDK jdk是编译java源文件成class文件的&#xff0c;我们使用javac命令把java源文件编译成class文件。 我们在java安装的目录下找到bin文件夹&#xff0c;如下图所示: 遵循着编译原理&#xff0c;把java源文件编译成JVM可识别的机器码。 其中还包括jar打包工具等。主要是针对…