istio流量管理

流量管理

image-20231110102205352

目录

image-20231111150752155

文章目录

    • 流量管理
    • 目录
    • 流量管理概述
    • 请求路由
      • 1.路由到版本1
        • ==🚩 实战:路由到版本1-2023.11.11(测试成功)==
      • 2.基于用户身份的路由
        • ==🚩 实战:基于用户身份的路由-2023.11.11(测试成功)==
    • 关于我
    • 最后

流量管理概述

上面我们了解了 GatewayVirtualService 资源对象的作用,以及它们是如何影响 Envoy 的配置的,那么这些资源对象又是如何影响流量的呢?通过 Istio 如何实现流量管理的呢?

Istio 的流量路由规则可以很容易的控制服务之间的流量和 API 调用。Istio 简化了服务级别属性的配置,比如熔断器、超时和重试,并且能轻松的设置重要的任务,如 A/B 测试、金丝雀发布、基于流量百分比切分的分阶段发布等。它还提供了开箱即用的故障恢复特性, 有助于增强应用的健壮性,从而更好地应对被依赖的服务或网络发生故障的情况。

为了在网格中路由,Istio 需要知道所有的 endpoint 在哪以及它们属于哪些服务。为了定位到 service registry(服务注册中心),Istio 会连接到一个服务发现系统。如果在 Kubernetes 集群上安装了 Istio,那么它将自动检测该集群中的服务和 endpoint。

使用此服务注册中心,Envoy 代理可以将流量定向到相关服务。大多数基于微服务的应用程序,每个服务的工作负载都有多个实例来处理流量,称为负载均衡池。默认情况下,Envoy 代理基于轮询调度模型在服务的负载均衡池内分发流量,按顺序将请求发送给池中每个成员, 一旦所有服务实例均接收过一次请求后,就重新回到第一个池成员。

Istio 基本的服务发现和负载均衡能力提供了一个可用的服务网格,但它能做到的远比这多的多。在许多情况下我们可能希望对网格的流量情况进行更细粒度的控制。作为 A/B 测试的一部分,可能想将特定百分比的流量定向到新版本的服务,或者为特定的服务实例子集应用不同的负载均衡策略。可能还想对进出网格的流量应用特殊的规则,或者将网格的外部依赖项添加到服务注册中心。通过使用 Istio 的流量管理 API 将流量配置添加到 Istio,就可以完成所有这些甚至更多的工作。

请求路由

首先我们来实现下最基本的流量请求路由的功能,这里我们将学习如何将请求动态路由到微服务的多个版本。

我们知道 Bookinfo 示例包含四个独立的微服务,每个微服务都有多个版本。其中 reviews 服务的三个不同版本已经部署并同时运行。我们可以在浏览器中访问 Bookinfo 应用程序并刷新几次。正常会看到三种不同的 reviews 服务版本的输出,有时书评的输出包含星级评分,有时则不包含。这是因为没有明确的默认服务版本可路由,Istio 将以循环方式将请求路由到所有可用版本。

我们首先来将所有流量路由到微服务的 v1 版本,稍后,您将应用规则根据 HTTP 请求 header 的值路由流量。

1.路由到版本1

🚩 实战:路由到版本1-2023.11.11(测试成功)

实验环境:

k8s v1.27.6(containerd://1.6.20)(cni:flannel:v0.22.2)[root@master1 ~]#istioctl version
client version: 1.19.3
control plane version: 1.19.3
data plane version: 1.19.3 (8 proxies)

实验软件:

链接:https://pan.baidu.com/s/1pMnJxgL63oTlGFlhrfnXsA?pwd=7yqb
提取码:7yqb
2023.11.5-实战:BookInfo 示例应用-2023.11.5(测试成功) --本节测试yaml在此目录里

image-20231105111842627

实验步骤:

image-20231111150558060

graph LRA[实战步骤] -->B(1️⃣ 部署VirtualService)A[实战步骤] -->C(2️⃣ DestinationRule)A[实战步骤] -->D(3️⃣ 验证)

要只路由到一个版本,则需要为微服务设置默认版本的 VirtualService

🍀

应用规则

Istio 使用 VirtualService 来定义路由规则,只需要应用下面的资源对象即可:

$ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
virtualservice.networking.istio.io/productpage created
virtualservice.networking.istio.io/reviews created
virtualservice.networking.istio.io/ratings created
virtualservice.networking.istio.io/details created

该资源清单中定义了四个 VirtualService 对象,分别是 productpagereviewsratingsdetails,它们分别对应着 Bookinfo 应用中的四个微服务,完整的清单如下所示:

# virtual-service-all-v1.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: productpage
spec:hosts:- productpagehttp:- route:- destination:host: productpagesubset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: reviews
spec:hosts:- reviewshttp:- route:- destination:host: reviewssubset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: ratings
spec:hosts:- ratingshttp:- route:- destination:host: ratingssubset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: details
spec:hosts:- detailshttp:- route:- destination:host: detailssubset: v1
---

我们可以看到这里的 VirtualService 对象中都定义了 subset 字段,这个字段就是用来指定微服务的版本的,这里我们将所有的微服务都指定为 v1 版本,这样所有的流量都会被路由到 v1 版本的微服务中,包括 reviews 服务,这样我们就不会再看到星级评分了。

🍀

但是如果我们现在直接去访问 Bookinfo 应用的话,是不能正常访问的,因为我们压根就还没指定这些 v1 版本的微服务到底在哪里。

image-20231111144249758

🍀

这个时候就需要用到另外一个资源对象 DestinationRule 了,我们需要为每个微服务创建一个 DestinationRule 对象,用来指定这些微服务的实际地址,这样 VirtualService 对象才能将流量路由到这些微服务中。Istio 在 DestinationRule 目标规则中使用 subsets 定义服务的版本,运行以下命令为 Bookinfo 服务创建默认的目标规则即可:

$ kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created

该资源清单中定义了四个 DestinationRule 对象,分别是 productpagereviewsratingsdetails 几个服务的目标规则,它们分别对应着 Bookinfo 应用中的四个微服务,完整的清单如下所示:

# destination-rule-all.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: productpage
spec:host: productpagesubsets:- name: v1labels:version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: reviews
spec:host: reviewssubsets:- name: v1labels:version: v1- name: v2labels:version: v2- name: v3labels:version: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: ratings
spec:host: ratingssubsets:- name: v1labels:version: v1- name: v2labels:version: v2- name: v2-mysqllabels:version: v2-mysql- name: v2-mysql-vmlabels:version: v2-mysql-vm
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: details
spec:host: detailssubsets:- name: v1labels:version: v1- name: v2labels:version: v2
---

🍀

现在我们就可以正常访问 Bookinfo 应用了,并且无论刷新多少次,页面的评论部分都不会显示评级星标,这是因为我们将 Istio 配置为将 reviews 服务的所有流量路由到版本 reviews:v1,而此版本的服务不访问星级评分服务。

img

这样我们就成功将流量路由到服务的某一个版本上了。

原理分析

🍀

前面章节中我们只定义了一个名为 bookinfoVirtualService 资源对象就可以正常访问了:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:name: bookinfonamespace: default
spec:gateways:- bookinfo-gatewayhosts:- "*"http:- match:- uri:exact: /productpage- uri:prefix: /static- uri:exact: /login- uri:exact: /logout- uri:prefix: /api/v1/productsroute:- destination:host: productpageport:number: 9080

很明显上面这个虚拟服务对象是我们访问 Bookinfo 应用的入口路由规则,所以这个虚拟服务对象实际上是为 istio-ingressgateway 入口网关服务定义的。 它将所有的流量都路由到了 productpage 这个服务上,而 productpage 这个服务又会去调用其他的服务来获取数据,在 productpage 服务中调用其他微服务 其实就是直接通过服务名称来调用的,比如调用 reviews 服务就是直接通过 reviews:9080 这个服务来调用的,我们可以查看 productpage 的代码来验证这一点:

img

🍀

我们可以再次查看 Bookinfo 在网格内的请求架构图:

img

当我们在浏览器中访问 http://<gateway url>/productpage 时,请求将进入网格中的 istio-ingressgateway 服务,然后将请求转发到 productpage 服务。productpage 服务将调用 reviewsdetails 服务来填充页面的内容,然后将其返回给用户。(reviews 服务包括 3 个不同版本的应用,可以通过 version 标签区分)

🍀

现在我们只想将流量路由到 reviews:v1 版本去,按照传统的方法只需要将 reviews 的 Service 对象去强制关联 version: v1 这个标签即可,现在我们所有的服务都被注入了一个 Envoy 的 Sidecar 代理,通过 Envoy 很容易就可以实现这个路由功能,而相应的在 Istio 中我们只需要通过 VirtualServiceDestinationRule 这两个资源对象就可以来实现了。上面我们创建的关于 reviews 服务的这两个对象如下所示:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: reviews
spec:hosts:- reviewshttp:- route:- destination:host: reviewssubset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: reviews
spec:host: reviewssubsets:- name: v1labels:version: v1- name: v2labels:version: v2- name: v3labels:version: v3

那么这两个对象是如何来影响 Envoy Sidecar 的呢?前面我们已经分析了流量从 istio-ingressgateway 进来后被路由到了 productpage 服务,那么 productpage 又该如何去访问其他微服务呢?同样我们可以使用 istioctl proxy-config 来查看 productpage 服务的 Envoy 配置。

🍀

每个 Envoy Sidecar 都有一个绑定到 0.0.0.0:15001 的监听器,然后利用 IP tables 将 pod 的所有入站和出站流量路由到这里,此监听器会配置一个 useOriginalDst: true,这意味着它将请求交给最符合请求原始目标的监听器。如果找不到任何匹配的虚拟监听器,它会将请求发送给返回 404 的 BlackHoleCluster,我们可以查看下 15001 端口的监听器配置:

[root@master1 istio-1.19.3]#istioctl proxy-config listeners productpage-v1-564d4686f-7vhks --port 15001 -oyaml
- accessLog:- filter:responseFlagFilter:flags:- NRname: envoy.access_loggers.filetypedConfig:'@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLoglogFormat:textFormatSource:inlineString: |[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS% %CONNECTION_TERMINATION_DETAILS% "%UPSTREAM_TRANSPORT_FAILURE_REASON%" %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" %UPSTREAM_CLUSTER% %UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS% %REQUESTED_SERVER_NAME% %ROUTE_NAME%path: /dev/stdoutaddress:socketAddress:address: 0.0.0.0portValue: 15001filterChains:- filterChainMatch:destinationPort: 15001filters:- name: istio.statstypedConfig:'@type': type.googleapis.com/stats.PluginConfig- name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxycluster: BlackHoleClusterstatPrefix: BlackHoleClustername: virtualOutbound-blackhole- filters:- name: istio.statstypedConfig:'@type': type.googleapis.com/stats.PluginConfig- name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxyaccessLog:- name: envoy.access_loggers.filetypedConfig:'@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLoglogFormat:textFormatSource:inlineString: |[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS% %CONNECTION_TERMINATION_DETAILS% "%UPSTREAM_TRANSPORT_FAILURE_REASON%" %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" %UPSTREAM_CLUSTER% %UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS% %REQUESTED_SERVER_NAME% %ROUTE_NAME%path: /dev/stdoutcluster: PassthroughClusterstatPrefix: PassthroughClustername: virtualOutbound-catchall-tcpname: virtualOutboundtrafficDirection: OUTBOUNDuseOriginalDst: true[root@master1 istio-1.19.3]#

🍀

实际上我们的请求是到 9080 端口(productpage 服务绑定 9080 端口)的 HTTP 出站请求,这意味着它被切换到 0.0.0.0:9080 虚拟监听器。所以我们查看下 9080 端口的监听器配置:

# productpage 默认访问其他服务的 9080 端口
$ istioctl proxy-config listeners productpage-v1-564d4686f-wwqqf --port 9080 -oyaml
- address:socketAddress:address: 0.0.0.0portValue: 9080# ......rds:configSource:ads: {}initialFetchTimeout: 0sresourceApiVersion: V3routeConfigName: "9080"  # RDS的路由配置名称# ......name: 0.0.0.0_9080trafficDirection: OUTBOUND  # 出流量

可以看到此监听器在其配置的 RDS 中查找名为 9080 的路由配置,我们可以使用 istioctl proxy-config routes 命令来查看这个路由配置的详细信息:

# 查看 9080 这个路由配置
$ istioctl proxy-config routes productpage-v1-564d4686f-wwqqf --name 9080 -oyaml
- name: "9080"virtualHosts:- domains:- details.default.svc.cluster.local- details- details.default.svc- details.default- 10.111.83.224name: details.default.svc.cluster.local:9080routes:- decorator:operation: details.default.svc.cluster.local:9080/*match:prefix: /metadata:filterMetadata:istio:config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/detailsroute:cluster: outbound|9080|v1|details.default.svc.cluster.local# ......- domains:- productpage.default.svc.cluster.local- productpage- productpage.default.svc- productpage.default- 10.97.120.23name: productpage.default.svc.cluster.local:9080routes:- decorator:operation: productpage.default.svc.cluster.local:9080/*match:prefix: /name: defaultroute:cluster: outbound|9080||productpage.default.svc.cluster.local# ......- domains:- ratings.default.svc.cluster.local- ratings- ratings.default.svc- ratings.default- 10.101.184.235name: ratings.default.svc.cluster.local:9080routes:- decorator:operation: ratings.default.svc.cluster.local:9080/*match:prefix: /metadata:filterMetadata:istio:config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/ratingsroute:cluster: outbound|9080|v1|ratings.default.svc.cluster.local# ......- domains:- reviews.default.svc.cluster.local- reviews- reviews.default.svc- reviews.default- 10.97.120.56name: reviews.default.svc.cluster.local:9080routes:- decorator:operation: reviews.default.svc.cluster.local:9080/*match:prefix: /metadata:filterMetadata:istio:config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/reviewsroute:cluster: outbound|9080|v1|reviews.default.svc.cluster.local# ......- domains:- '*'name: allow_anyroutes:- match:prefix: /name: allow_anyroute:cluster: PassthroughCluster# ......

这个路由配置中其实包含了 K8s Service 对象中监听 9080 端口的所有服务,如果没有创建对应的 VirtualService 对象,对应的路由配置就没有 metadata.filterMetadata.istio.config 这个属性。比如现在我们正在通过 productpage 请求前往 reviews 服务,因此 Envoy 将选择我们的请求与域匹配的虚拟主机。一旦在域上匹配,Envoy 会查找与请求匹配的第一条路径,我们这里没有任何高级路由,因此只有一条路由匹配所有内容。这条路由告诉 Envoy 将请求发送到 outbound|9080|v1|reviews.default.svc.cluster.local 集群,因为前面我们创建的 reviews 这个 VirtualService 对象配置了的 destination.subset: v1,所以这里的集群命名上多了一个 subset

需要注意的是我们在 VirtualService 对象里面配置了 destination.subset: v1,那么必须要有对应的 subset 存在才行,否则不会生成对应的 Envoy 集群配置,那么就不能正常访问该服务了,而该 subset 就是通过前面的 DestinationRule 对象来定义的,现在我们就可以来查看这个集群配置了:

$ istioctl proxy-config cluster productpage-v1-564d4686f-wwqqf --fqdn reviews.default.svc.cluster.local -o yaml
- edsClusterConfig:edsConfig:ads: {}initialFetchTimeout: 0sresourceApiVersion: V3serviceName: outbound|9080||reviews.default.svc.cluster.locallbPolicy: LEAST_REQUESTmetadata:filterMetadata:istio:config: /apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/reviewsservices:- host: reviews.default.svc.cluster.localname: reviewsnamespace: default# ......name: outbound|9080||reviews.default.svc.cluster.localtype: EDS
- edsClusterConfig:edsConfig:ads: {}initialFetchTimeout: 0sresourceApiVersion: V3serviceName: outbound|9080|v1|reviews.default.svc.cluster.locallbPolicy: LEAST_REQUESTmetadata:filterMetadata:istio:config: /apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/reviewsservices:- host: reviews.default.svc.cluster.localname: reviewsnamespace: defaultsubset: v1name: outbound|9080|v1|reviews.default.svc.cluster.local# ......type: EDS
- edsClusterConfig:edsConfig:ads: {}initialFetchTimeout: 0sresourceApiVersion: V3serviceName: outbound|9080|v2|reviews.default.svc.cluster.localfilters:- name: istio.metadata_exchangetypedConfig:'@type': type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchangeprotocol: istio-peer-exchangelbPolicy: LEAST_REQUESTmetadata:filterMetadata:istio:config: /apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/reviewsservices:- host: reviews.default.svc.cluster.localname: reviewsnamespace: defaultsubset: v2name: outbound|9080|v2|reviews.default.svc.cluster.local# ......type: EDS
- edsClusterConfig:edsConfig:ads: {}initialFetchTimeout: 0sresourceApiVersion: V3serviceName: outbound|9080|v3|reviews.default.svc.cluster.localfilters:- name: istio.metadata_exchangetypedConfig:'@type': type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchangeprotocol: istio-peer-exchangelbPolicy: LEAST_REQUESTmetadata:filterMetadata:istio:config: /apis/networking.istio.io/v1alpha3/namespaces/default/destination-rule/reviewsservices:- host: reviews.default.svc.cluster.localname: reviewsnamespace: defaultsubset: v3name: outbound|9080|v3|reviews.default.svc.cluster.local# ......type: EDS

从上面配置可以看到里面一共包含了 4 个 reviews 相关的集群,一个是原始的不包含 subset 的,而另外三个就是前面我们在 DestinationRule 对象中配置的 3 个 subset,所以其实 DestinationRule 映射到 Envoy 的配置文件中就是 Cluster

🍀

最后我们同样还可以查看每个集群下面包含的 endpoint 有哪些:

$ istioctl proxy-config endpoint productpage-v1-564d4686f-wwqqf --cluster "outbound|9080||reviews.default.svc.cluster.local" -o yaml
- edsServiceName: outbound|9080||reviews.default.svc.cluster.local- address:socketAddress:address: 10.244.2.84portValue: 9080# ......weight: 1- address:socketAddress:address: 10.244.2.83portValue: 9080# ......weight: 1- address:socketAddress:address: 10.244.2.88portValue: 9080# ......weight: 1name: outbound|9080||reviews.default.svc.cluster.localobservabilityName: outbound|9080||reviews.default.svc.cluster.local$ istioctl proxy-config endpoint productpage-v1-564d4686f-wwqqf --cluster "outbound|9080|v1|reviews.default.svc.cluster.local" -o yaml
- edsServiceName: outbound|9080|v1|reviews.default.svc.cluster.localhostStatuses:- address:socketAddress:address: 10.244.2.84portValue: 9080weight: 1name: outbound|9080|v1|reviews.default.svc.cluster.localobservabilityName: outbound|9080|v1|reviews.default.svc.cluster.local# 过滤 version=v1 的 reviews pod
$ kubectl get pod -l app=reviews,version=v1 -o wide
NAME                          READY   STATUS    RESTARTS        AGE     IP            NODE    NOMINATED NODE   READINESS GATES
reviews-v1-86896b7648-zjh2n   2/2     Running   4 (5h18m ago)   6d17h   10.244.2.84   node2   <none>           <none>

可以看到不包含 subset 的集群下面的 endpoint 其实就是 reviews 这个 Service 对象的 endpoint 集合,包含 subset 就只有和该子集匹配的后端实例了。到了这一步,一切皆明了,后面的事情就跟之前的套路一样了,具体的 Endpoint 对应打了标签 version=v1 的 Pod。

🍀

到这里我们是不是就实现了通过 VirtualServiceDestinationRule 对象将流量路由到了指定的版本上面了,上面的整个过程就是请求从 productpage 到 reviews 的过程,从 reviews 到网格内其他应用的流量与上面类似,就不展开讨论了。

2.基于用户身份的路由

🚩 实战:基于用户身份的路由-2023.11.11(测试成功)

实验环境:

k8s v1.27.6(containerd://1.6.20)(cni:flannel:v0.22.2)[root@master1 ~]#istioctl version
client version: 1.19.3
control plane version: 1.19.3
data plane version: 1.19.3 (8 proxies)

实验软件:

链接:https://pan.baidu.com/s/1pMnJxgL63oTlGFlhrfnXsA?pwd=7yqb
提取码:7yqb
2023.11.5-实战:BookInfo 示例应用-2023.11.5(测试成功) --本节测试yaml在此目录里

image-20231105111842627

实验步骤:

image-20231111150647965

graph LRA[实战步骤] -->B(1️⃣ 更新VirtualService)A[实战步骤] -->C(2️⃣ 测试)

接下来我们继续更改路由配置,将来自特定用户的所有流量路由到特定服务版本。我们这里将配置来自名为 Jason 的用户的所有流量被路由到服务 reviews:v2

注意 Istio 对用户身份没有任何特殊的内置机制,productpage 服务在所有到 reviews 服务的 HTTP 请求中都增加了一个自定义的 end-user 请求头来实现该效果:headers['end-user'] = session['user']

🍀

要实现该功能,只需要创建下面的资源对象即可:

$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
virtualservice.networking.istio.io/reviews configured

该资源清单文件创建了一个如下所示的 VirtualService 资源对象:

# virtual-service-reviews-test-v2.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: reviews
spec:hosts:- reviewshttp:- match:- headers:end-user:exact: jasonroute:- destination:host: reviewssubset: v2- route:- destination:host: reviewssubset: v1

该对象设置了一条路由规则,它会根据 productpage 服务发起的请求的 end-user 自定义请求头内容进行匹配,如果有该内容且为 jason 则会将流量路由到 reviews 服务的 v2 版本,其余的还是被路由到 v1 版本去。

🍀

现在我们可以前往浏览器访问 Bookinfo 应用,多刷新几次可以看到评论始终访问到的是 v1 版本的服务,即没有星标的:

img

🍀

然后我们点击页面右上角的 Sign in 按钮,使用 jason 进行登录,登录后页面就会出现带有黑色星标的 v2 版本的评论服务,即使多刷新几次依然如此:

img

如果我们选择使用其他用户进行登录或者注销则星标就会消失,这是因为除了 Jason 之外,所有用户的流量都被路由到 reviews:v1

🍀

同样的我们可以去查看下对应的 Envoy Sidecar 配置的变化,因为这里我们只更新了一个 VirtualService 对象,所以只会对 Envoy 的路由表产生影响,查看对应的路由配置即可:

$ istioctl proxy-config routes productpage-v1-564d4686f-wwqqf --name 9080 -oyaml
- name: "9080"validateClusters: falsevirtualHosts:# ......- domains:- reviews.default.svc.cluster.local- reviews- reviews.default.svc- reviews.default- 10.97.120.56includeRequestAttemptCount: truename: reviews.default.svc.cluster.local:9080routes:- decorator:operation: reviews.default.svc.cluster.local:9080/*match:caseSensitive: trueheaders:- name: end-userstringMatch:exact: jasonprefix: /metadata:filterMetadata:istio:config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/reviewsroute:cluster: outbound|9080|v2|reviews.default.svc.cluster.localmaxGrpcTimeout: 0s# ......- decorator:operation: reviews.default.svc.cluster.local:9080/*match:prefix: /metadata:filterMetadata:istio:config: /apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/reviewsroute:cluster: outbound|9080|v1|reviews.default.svc.cluster.localmaxGrpcTimeout: 0s# ......

从配置上我们可以看到现在的 Envoy 配置中新增了一条路由规则,如下所示:

match:caseSensitive: trueheaders:- name: end-userstringMatch:exact: jasonprefix: /
route:cluster: outbound|9080|v2|reviews.default.svc.cluster.local

当请求头中包含 end-user:jason 的时候请求会被路由到 outbound|9080|v2|reviews.default.svc.cluster.local 这个 Envoy Cluster 集群,这个集群就是前面我们通过 DestinationRule 创建的 v2 这个子集,所以最后请求会被路由到带有黑色星标的评论服务去。

img

🍀

到这里我们就明白了要通过 Istio 实现服务的流量管理,需要用到 GatewayVirtualServiceDestinationRule 三个 CRD 对象,这些对象其实最终都是去拼凑 Envoy 的配置,每个对象管理 Envoy 配置的一部分,把这个关系搞清楚我们就能更好的掌握 Istio 的使用了。

关于我

我的博客主旨:

  • 排版美观,语言精炼;
  • 文档即手册,步骤明细,拒绝埋坑,提供源码;
  • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

🍀 微信二维码
x2675263825 (舍得), qq:2675263825。

image-20230107215114763

🍀 微信公众号
《云原生架构师实战》

image-20230107215126971

🍀 个人博客站点

http://onedayxyy.cn/

image-20231106071817374

🍀 语雀

https://www.yuque.com/xyy-onlyone

image-20231106071948492

🍀 csdn

https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

image-20230107215149885

🍀 知乎

https://www.zhihu.com/people/foryouone

image-20230107215203185

最后

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!

image-20231016062113861

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

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

相关文章

【操作系统内核】线程

【操作系统内核】线程 为什么需要线程 比如我要做一个视频播放器&#xff0c;就需要实现三个功能&#xff1a; ① 从磁盘读取视频数据 ② 对读取到的视频数据进行解码 ③ 对解码的数据进行播放 如果串行执行&#xff08;通过一个进程来执行&#xff09;&#xff1a; 那么…

ElasticSearch7.x - HTTP 操作 - 查询文档操作

查询索引下的所有文档 http://192.168.254.101:9200/shopping/_search 条件查询 请求路径上添加条件:http://192.168.254.101:9200/shopping/_search?q=category:小米 请求体上添加条件:http://192.168.254.101:9200/shopping/_search 请求体内容 {"query" :{&qu…

「我在淘天做技术」音视频技术及其在淘宝内容业务中的应用

作者&#xff1a;李凯 一、前言 近年来&#xff0c;内容电商似乎已经充分融入到人们的生活中&#xff1a;在闲暇时间&#xff0c;我们已经习惯于拿出手机&#xff0c;从电商平台的直播间、或者短视频链接下单自己心仪的商品。 尽管优质的货品、实惠的价格、精致的布景、有趣的…

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:

错误描述如下所示&#xff1a; 我们将错误拉到最下面如下所示为导致异常的原因&#xff1a; Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type com.example.reviewmybatisplus.Service.UserService available: expec…

植发机构服务预约小程序的效果如何

不只是老年人&#xff0c;也有不少年轻人承受着掉发秃顶的痛点&#xff0c;工作压力提升及生活行为不规范&#xff0c;掉发脱发成为近些年来一个热门话题&#xff0c;同时植发服务高需求背景下&#xff0c;也促进着市场中各机构需要不断提升业务价值及客户体验&#xff0c;同时…

2023最新软件测试面试300问

一、Linux系统应用和环境配置 1、Linux系统的操作命令给我说10个&#xff0c;一般用什么工具远程连接Linux服务器&#xff1f; 2、Linux中的日志存储在哪里&#xff1f;怎么查看日志内容&#xff1f; 3、Linux中top和ps命令的区别&#xff1f; 4、Linux命令运行的结果如何写…

Libra R-CNN: Towards Balanced Learning for Object Detection(2019.4)

文章目录 AbstractIntroduction引入问题1&#xff09; Sample level imbalance2) Feature level imbalance3) Objective level imbalance进行解决贡献 Related Work&#xff08;他人的work&#xff0c;捎带与我们的对比&#xff09;Model architectures for object detection&a…

【Unity程序小技巧】如何消除多次Destory带来的性能消耗

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

跨镜头目标融合__追踪之目标重识别研究(跨镜头目标追踪)

文章目录 标题&#xff1a;跨镜头目标融合&#xff1b;目标重识别&#xff1b;跨镜头目标追踪&#xff1b; 1 目的&#xff1a;2 实现方法/策略&#xff1a;2.1 目标类型位置匹配&#xff08;或考虑结合目标轨迹&#xff09;2.2 目标重识别2.3 目标类型位置匹配(轨迹)目标重识别…

PowerPoint to HTML5 SDK Crack

Convert PowerPoint to HTML5 Retaining Animations, Transitions, Hyperlinks, Smartart, Triggers and other multimedia effects World’s first and industry best technology for building web/mobile based interactive presentations directly from PowerPoint – that …

2022最新版-李宏毅机器学习深度学习课程-P50 BERT的预训练和微调

模型输入无标签文本&#xff08;Text without annotation&#xff09;&#xff0c;通过消耗大量计算资源预训练&#xff08;Pre-train&#xff09;得到一个可以读懂文本的模型&#xff0c;在遇到有监督的任务是微调&#xff08;Fine-tune&#xff09;即可。 最具代表性是BERT&…

YOLOv8模型ONNX格式INT8量化轻松搞定

ONNX格式模型量化 深度学习模型量化支持深度学习模型部署框架支持的一种轻量化模型与加速模型推理的一种常用手段&#xff0c;ONNXRUNTIME支持模型的简化、量化等脚本操作&#xff0c;简单易学&#xff0c;非常实用。 ONNX 模型量化常见的量化方法有三种&#xff1a;动态量化…