一.模块概览

在本模块中,我们将开始使用 Istio 服务网格在服务之间进行流量路由。使用流量路由,我们将学习如何部署新版本的服务,并在已发布的生产版本的服务旁边运行,而不干扰生产流量。随着两个服务版本的部署,我们将逐步发布(金丝雀发布)新版本,并开始将一定比例的传入流量路由到最新版本。

使用服务网格Istio进行流量路由的前提是已经安装好了istio,关于istio的安装部署,请查看博客《Istio(二):在Kubernetes(k8s)集群上安装部署istio1.14》https://www.cnblogs.com/renshengdezheli/p/16836404.html

二.系统环境

服务器版本 docker软件版本 Kubernetes(k8s)集群版本 Istio软件版本 CPU架构
CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 v1.21.9 Istio1.14 x86_64

Kubernetes集群架构:k8scloude1作为master节点,k8scloude2,k8scloude3作为worker节点

服务器 操作系统版本 CPU架构 进程 功能描述
k8scloude1/192.168.110.130 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master节点
k8scloude2/192.168.110.129 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker节点
k8scloude3/192.168.110.128 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker节点

三.简单路由

3.1 简单路由

我们可以使用 VirtualService 资源在 Istio 服务网格中进行流量路由通过 VirtualService,我们可以定义流量路由规则,并在客户端试图连接到服务时应用这些规则。例如向 dev.example.com 发送一个请求,最终到达目标服务。

让我们看一下在集群中运行 customers 应用程序的两个版本(v1 和 v2)的例子。我们有两个 Kubernetes 部署,customers-v1customers-v2。属于这些部署的 Pod 有一个标签 version:v1 或一个标签 version:v2 的设置。

路由到 Customers如下所示:

我们想把 VirtualService 配置为将流量路由到应用程序的 V1 版本。70% 的传入流量应该被路由到 V1 版本。30% 的请求应该被发送到应用程序的 V2 版本。

下面是上述情况下 VirtualService 资源的yaml文件:

 apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: customers-route
spec:
hosts:
- customers.default.svc.cluster.local
http:
- name: customers-v1-routes
route:
- destination:
host: customers.default.svc.cluster.local
subset: v1
weight: 70
- name: customers-v2-routes
route:
- destination:
host: customers.default.svc.cluster.local
subset: v2
weight: 30

hosts 字段下,我们要定义流量被发送到的目标主机。在我们的例子中,这就是 customers.default.svc.cluster.local Kubernetes 服务。

下一个字段是 http,这个字段包含一个 HTTP 流量的路由规则的有序列表。destination 是指服务注册表中的一个服务,也是路由规则处理后请求将被发送到的目的地Istio 的服务注册表包含所有的 Kubernetes 服务,以及任何用 ServiceEntry资 源声明的服务

我们也在设置每个目的地的权重(weight权重等于发送到每个子集的流量的比例。所有权重的总和应该是 100。如果我们有一个单一的目的地,权重被假定为 100。

通过 gateways 字段,我们还可以指定我们想要绑定这个 VirtualService 的网关名称。比如说:

 apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: customers-route
spec:
hosts:
- customers.default.svc.cluster.local
gateways:
- my-gateway
http:
...

上面的 YAML 文件将 customers-route 这个VirtualService 绑定到名为 my-gateway 的网关上。这有效地暴露了通过网关的目标路由

当一个 VirtualService 被附加到一个网关上时,只允许在网关资源中定义的主机。下表解释了网关资源中的 hosts 字段如何作为过滤器,以及 VirtualService 中的 hosts 字段如何作为匹配。

Gateway Hosts VirtualService Hosts 行为
* customers.default.svc.cluster.local 流量通过 VirtualService 发送,因为 * 允许所有主机
customers.default.svc.cluster.local customers.default.svc.cluster.local hosts 匹配,流量将被发送
hello.default.svc.cluster.local customers.default.svc.cluster.local hosts 不匹配,无效
hello.default.svc.cluster.local ["hello.default.svc.cluster.local", "customers.default.svc.cluster.local"] 只允许 hello.default.svc.cluster.local。它绝不允许 customers.default.svc.cluster.local 通过网关。然而,这仍然是一个有效的配置,因为 VirtualService 可以连接到第二个网关,该网关的 hosts 字段中包含 *.default.svc.cluster.local

四.Subset和DestinationRule

4.1 Subset 和 DestinationRule

目的地指的是不同的子集(subset)或服务版本通过子集,我们可以识别应用程序的不同变体。在我们的例子中,我们有两个子集,v1v2,它们对应于我们 customer 服务的两个不同版本。每个子集都使用键/值对(标签)的组合来确定哪些 Pod 要包含在子集中。我们可以在一个名为 DestinationRule 的资源类型中声明子集

下面是定义了两个子集的 DestinationRule 资源的yaml文件。

 apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: customers-destination
spec:
host: customers.default.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2

让我们看看我们可以在 DestinationRule 中设置的流量策略。

4.2 DestinationRule 中的流量策略

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

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

4.2.1 负载均衡器设置

通过负载均衡器设置,我们可以控制目的地使用哪种负载均衡算法。下面是一个带有流量策略的 DestinationRule 的例子,它把目的地的负载均衡算法设置为 round-robin(轮询)。

 apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: customers-destination
spec:
host: customers.default.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2

我们还可以设置基于哈希的负载均衡,并根据 HTTP 头、cookies 或其他请求属性提供会话亲和性。下面是一个流量策略的片段,它设置了基于哈希的负载均衡,并使用一个叫做 location 的 cookie 来实现亲和力。

 trafficPolicy:
loadBalancer:
consistentHash:
httpCookie:
name: location
ttl: 4s

4.2.2 连接池配置

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

下面是一个片段,显示了我们如何设置对服务的并发请求的限制

 spec:
host: myredissrv.prod.svc.cluster.local
trafficPolicy:
connectionPool:
http:
http2MaxRequests: 50

4.2.3 异常点检测

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

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

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

4.2.4 客户端 TLS 设置

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

 trafficPolicy:
tls:
mode: MUTUAL
clientCertificate: /etc/certs/cert.pem
privateKey: /etc/certs/key.pem
caCertificates: /etc/certs/ca.pem

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

4.2.5 端口流量策略

注释:LEAST_CONN表示最少连接,ROUND_ROBIN表示轮询,轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同。这有个前提,就是每个请求所占用的后端时间要差不多,如果有些请求占用的时间很长,会导致其所在的后端负载较高。在这种场景下,把请求转发给连接数较少的后端,能够达到更好的负载均衡效果,这就是least_conn算法。least_conn算法很简单,首选遍历后端集群,比较每个后端的conns/weight,选取该值最小的后端。如果有多个后端的conns/weight值同为最小的,那么对它们采用加权轮询算法。

使用 portLevelSettings 字段,我们可以将流量策略应用于单个端口。比如说:

 trafficPolicy:
portLevelSettings:
- port:
number: 80
loadBalancer:
simple: LEAST_CONN
- port:
number: 8000
loadBalancer:
simple: ROUND_ROBIN

五.高级路由

5.1 高级路由

在前面,我们了解了如何利用流量的比例(weight 字段)在多个子集之间进行流量路由在某些情况下,纯粹的基于权重的流量路由或分割已经足够了。然而,在有些场景和情况下,我们可能需要对流量如何被分割和转发到目标服务进行更细化的控制

Istio 允许我们使用传入请求的一部分,并将其与定义的值相匹配。例如,我们可以匹配传入请求的 URI 前缀,并基于此路由流量。

属性 描述
uri 将请求 URI 与指定值相匹配
schema 匹配请求的 schema(HTTP、HTTPS...)
method 匹配请求的 method(GET、POST...)
authority 匹配请求 authority 头
headers 匹配请求头。头信息必须是小写的,并以连字符分隔(例如:x-my-request-id)。注意,如果我们使用头信息进行匹配,其他属性将被忽略(urischemamethodauthority)。

上述每个属性都可以用这些方法中的一种进行匹配:

  • 精确匹配:例如,exact: "value" 匹配精确的字符串
  • 前缀匹配:例如,prefix: "value" 只匹配前缀
  • 正则匹配:例如,regex:"value" 根据 ECMAscript 风格的正则进行匹配

例如,假设请求的 URI 看起来像这样:https://dev.example.com/v1/api。为了匹配该请求的 URI,我们会这样写:

 http:
- match:
- uri:
prefix: /v1

上述片段将匹配传入的请求,并且请求将被路由到该路由中定义的目的地

另一个例子是使用正则并在头上进行匹配。

 http:
- match:
- headers:
user-agent:
regex: '.*Firefox.*'

上述匹配将匹配任何用户代理头与 Regex 匹配的请求。

5.2 重定向和重写请求

在头信息和其他请求属性上进行匹配是有用的,但有时我们可能需要通过请求 URI 中的值来匹配请求

例如,让我们考虑这样一种情况:传入的请求使用 /v1/api 路径,而我们想把请求路由到 /v2/api 端点

这样做的方法是重写所有传入的请求和与 /v1/api 匹配的 authority/host headers 到 /v2/api

例如:

 ...
http:
- match:
- uri:
prefix: /v1/api
rewrite:
uri: /v2/api
route:
- destination:
host: customers.default.svc.cluster.local
...

即使目标服务不在 /v1/api 端点上监听,Envoy 也会将请求重写到 /v2/api

我们还可以选择将请求重定向或转发到一个完全不同的服务。下面是我们如何在头信息上进行匹配,然后将请求重定向到另一个服务

 ...
http:
- match:
- headers:
my-header:
exact: hello
redirect:
uri: /hello
authority: my-service.default.svc.cluster.local:8000
...

redirectdestination 字段是相互排斥的。如果我们使用 redirect,就不需要设置 destination

5.3 AND 和 OR 语义

在进行匹配时,我们可以使用 AND 和 OR 两种语义。让我们看一下下面的片段:

 ...
http:
- match:
- uri:
prefix: /v1
headers:
my-header:
exact: hello
...

上面的片段使用的是 AND 语义这意味着 URI 前缀需要与 /v1 相匹配,并且头信息 my-header 有一个确切的值 hello

使用 OR 语义,我们可以添加另一个 match,像这样:

 ...
http:
- match:
- uri:
prefix: /v1
...
- match:
- headers:
my-header:
exact: hello
...

在上面的例子中,将首先对 URI 前缀进行匹配,如果匹配,请求将被路由到目的地。如果第一个不匹配,算法会转移到第二个,并尝试匹配头。如果我们省略路由上的匹配字段,它将总是评估为 true

六.实战:简单流量路由

6.1 简单流量路由

我们将学习如何使用权重在不同的服务版本之间路由流量。然后,我们将部署 Customers 服务版本 v2,并使用子集在这两个版本之间分配流量。

让我们从部署 Gateway 开始:

 apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- '*'

将上述 YAML 保存为 gateway.yaml,并使用 kubectl apply -f gateway.yaml 部署 Gateway。

接下来,我们将创建 Web Frontend 和 Customers 服务的部署以及相应的 Kubernetes 服务。让我们首先从 web-frontend 开始:

 apiVersion: apps/v1
kind: Deployment
metadata:
name: web-frontend
labels:
app: web-frontend
spec:
replicas: 1
selector:
matchLabels:
app: web-frontend
template:
metadata:
labels:
app: web-frontend
version: v1
spec:
containers:
- image: gcr.io/tetratelabs/web-frontend:1.0.0
imagePullPolicy: Always
name: web
ports:
- containerPort: 8080
env:
- name: CUSTOMER_SERVICE_URL
value: 'http://customers.default.svc.cluster.local'
---
kind: Service
apiVersion: v1
metadata:
name: web-frontend
labels:
app: web-frontend
spec:
selector:
app: web-frontend
ports:
- port: 80
name: http
targetPort: 8080

注意,我们正在设置一个名为 CUSTOMER_SERVICE_URL 的环境变量,它指向我们接下来要部署的 customer 服务。Web Frontend 使用这个 URL 来调用 Customers 服务。

将上述 YAML 保存为 web-frontend.yaml ,并使用 kubectl apply -f web-frontend.yaml 创建部署和服务。

现在我们可以部署 Customers 服务的 v1版本了。注意我们是如何在 Pod 模板中设置 version: v1 标签的。然而,该服务在其选择器中只使用app: customers。这是因为我们将在 DestinationRule 中创建子集,这些子集将在选择器中应用额外的版本标签,使我们能够到达运行特定版本的 Pod

 apiVersion: apps/v1
kind: Deployment
metadata:
name: customers-v1
labels:
app: customers
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: customers
version: v1
template:
metadata:
labels:
app: customers
version: v1
spec:
containers:
- image: gcr.io/tetratelabs/customers:1.0.0
imagePullPolicy: Always
name: svc
ports:
- containerPort: 3000
---
kind: Service
apiVersion: v1
metadata:
name: customers
labels:
app: customers
spec:
selector:
app: customers
ports:
- port: 80
name: http
targetPort: 3000

将上述内容保存为 customers-v1.yaml,并使用 kubectl apply -f customers-v1.yaml 创建部署和服务。

我们应该有两个应用程序的部署在运行:

 $ kubectl get po
NAME READY STATUS RESTARTS AGE
customers-v1-7857944975-5lxc8 2/2 Running 0 36s
web-frontend-659f65f49-jz58r 2/2 Running 0 3m38s

现在我们可以为 web-frontend 创建一个 VirtualService,并将其绑定到 Gateway 资源上:

 apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: web-frontend
spec:
hosts:
- '*'
gateways:
- gateway
http:
- route:
- destination:
host: web-frontend.default.svc.cluster.local
port:
number: 80

将上述 YAML 保存为 web-frontend-vs.yaml,并使用 kubectl apply -f web-frontend-vs.yaml 创建 VirtualService。

现在我们可以在浏览器中打开 GATEWAY_URL,并进入显示 Customers 服务中客户列表的 Web Frontend,如下图所示。

如果我们部署了 Customers 服务 v2 版本,我们在调用 http://customers.default.svc.cluster.local,得到的回应将是随机的。它们要么来自 Customers 服务的 v2 版本,要么来自 v1 版本。

我们需要为 Customers 服务创建 DestinationRule,并定义两个子集,代表 v1 和 v2 版本。然后,我们可以创建一个 VirtualService,并将所有流量路由到 v1 版本的子集。之后,我们可以在不影响现有服务的情况下部署 v2 版本的 Customers 服务。

让我们从 DestinationRule 和两个子集开始:

 apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: customers
spec:
host: customers.default.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2

将上述内容保存到 customers-dr.yaml,并使用 kubectl apply -f customers-dr.yaml 创建 DestinationRule。

我们可以创建 VirtualService 并在目标中指定 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.local
port:
number: 80
subset: v1

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

将上述 YAML 保存为 customers-vs.yaml,并使用 kubectl apply -f customers-vs.yaml 创建 VirtualService。

现在我们已经准备好部署 v2 版的 Customers 服务了。v2 版本返回与前一版本相同的客户列表,但它也包括城市名称。

让我们创建 Customers v2 部署。我们不需要部署 Kubernetes 服务,因为我们已经部署了一个 v1 版本的服务。

 apiVersion: apps/v1
kind: Deployment
metadata:
name: customers-v2
labels:
app: customers
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: customers
version: v2
template:
metadata:
labels:
app: customers
version: v2
spec:
containers:
- image: gcr.io/tetratelabs/customers:2.0.0
imagePullPolicy: Always
name: svc
ports:
- containerPort: 3000

该部署与 v1 部署几乎相同。唯一的区别是所使用的 Docker 镜像版本和设置在版本标签上的 v2 值。

将上述 YAML 保存为 customers-v2.yaml,并使用 kubectl apply -f customers-v2.yaml 创建部署。

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

要做到这一点,我们将创建第二个 destination,有相同的主机名,但有不同的子集。我们还将为 destination 添加 weight: 50,以便在两个版本之间平均分配流量。

 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.local
port:
number: 80
subset: v1
weight: 50
- destination:
host: customers.default.svc.cluster.local
port:
number: 80
subset: v2
weight: 50

将上述 YAML 保存为 customers-50-50.yaml 并使用 kubectl apply -f customers-50-50.yaml 更新 VirtualService。

在浏览器中打开 GATEWAY_URL,刷新几次页面,看看不同的响应。来自 Customers v2 的响应显示在下图中。

为了改变发送到一个或另一个版本的流量比例,我们可以更新 VirtualService。同样,我们也可以添加 v3 或 v4 版本,并在这些版本之间分割流量。

6.2 清理

删除 Deployments、Services、VirtualServices、DestinationRule 和 Gateway:

 kubectl delete deploy web-frontend customers-{v1,v2}
kubectl delete svc customers web-frontend
kubectl delete vs customers web-frontend
kubectl delete dr customers
kubectl delete gateway gateway

七.实战:高级流量路由

7.1 高级流量路由

在这个实验中,我们将学习如何使用请求属性在多个服务版本之间路由流量

我们将从部署 Gateway 开始:

 apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- '*'

将上述 YAML 保存为 gateway.yaml 并使用 kubectl apply -f gateway.yaml 部署网关。

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

 apiVersion: apps/v1
kind: Deployment
metadata:
name: web-frontend
labels:
app: web-frontend
spec:
replicas: 1
selector:
matchLabels:
app: web-frontend
template:
metadata:
labels:
app: web-frontend
version: v1
spec:
containers:
- image: gcr.io/tetratelabs/web-frontend:1.0.0
imagePullPolicy: Always
name: web
ports:
- containerPort: 8080
env:
- name: CUSTOMER_SERVICE_URL
value: 'http://customers.default.svc.cluster.local'
---
kind: Service
apiVersion: v1
metadata:
name: web-frontend
labels:
app: web-frontend
spec:
selector:
app: web-frontend
ports:
- port: 80
name: http
targetPort: 8080
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: web-frontend
spec:
hosts:
- '*'
gateways:
- gateway
http:
- route:
- destination:
host: web-frontend.default.svc.cluster.local
port:
number: 80

将上述 YAML 保存为 web-frontend.yaml 并使用 kubectl apply -f web-frontend.yaml 创建部署和服务。

 apiVersion: apps/v1
kind: Deployment
metadata:
name: customers-v1
labels:
app: customers
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: customers
version: v1
template:
metadata:
labels:
app: customers
version: v1
spec:
containers:
- image: gcr.io/tetratelabs/customers:1.0.0
imagePullPolicy: Always
name: svc
ports:
- containerPort: 3000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: customers-v2
labels:
app: customers
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: customers
version: v2
template:
metadata:
labels:
app: customers
version: v2
spec:
containers:
- image: gcr.io/tetratelabs/customers:2.0.0
imagePullPolicy: Always
name: svc
ports:
- containerPort: 3000
---
kind: Service
apiVersion: v1
metadata:
name: customers
labels:
app: customers
spec:
selector:
app: customers
ports:
- port: 80
name: http
targetPort: 3000
---
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.local
port:
number: 80
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: customers
spec:
host: customers.default.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2

将上述 YAML 保存为 customers.yaml,用 kubectl apply -f customers.yaml 创建资源。

为了确保一切部署和工作正常,打开 GATEWAY_URL,并确保我们从 Customers v1 获得响应。

我们将更新 Customers 的 VirtualService,并更新流量在两个版本的 Customers 服务之间的路由。

让我们看一下 YAML,如果请求中包含一个 header user: debug,就把流量路由到 Customers v2。如果没有设置这个 header,我们就被路由到 Customers v1。

 apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: customers
spec:
hosts:
- 'customers.default.svc.cluster.local'
http:
- match:
- headers:
user:
exact: debug
route:
- destination:
host: customers.default.svc.cluster.local
port:
number: 80
subset: v2
- route:
- destination:
host: customers.default.svc.cluster.local
port:
number: 80
subset: v1

将上述 YAML 保存为 customers-vs.yaml,然后用 kubectl apply -f customers-vs.yaml 更新 VirtualService。

如果我们不提供端口号,VirtualService 中的目的地也会工作。这是因为该服务只定义了一个端口。

如果我们打开 GATEWAY_URL,我们仍然应该得到来自 Customers v1的响应。如果我们在请求中添加 header user: debug,我们会注意到customers 的响应是来自 Customers v2。

我们可以使用 ModHeader 扩展来修改浏览器中的头信息。另外,我们也可以使用 cURL,像这样把头信息添加到请求中。

 $ curl -H "user: debug" http://GATEWAY_URL/
...
<th class="px-4 py-2">CITY</th>
<th class="px-4 py-2">NAME</th>
...

如果我们看一下回复,你会注意到有两栏——CITY 和 NAME。

7.2 清理

删除 Deployment、Service、VirtualService、DestinationRule 和 Gateway:

 kubectl delete deploy web-frontend customers-{v1,v2}
kubectl delete svc customers web-frontend
kubectl delete vs customers web-frontend
kubectl delete dr customers
kubectl delete gateway gateway

Istio(五):使用服务网格Istio进行流量路由的更多相关文章

  1. 服务网格Istio初探

    1. 服务网格Istio初探 1.1. 什么是Istio 它是一个完全开源的服务网格.什么是服务网格? 这个术语通常用于描述构成这些应用程序的微服务网络以及应用之间的交互.随着规模和复杂性的增长,服务 ...

  2. 服务网格istio概念应知应会

    一.背景 最近架构组基于istio开发了服务网格(Service Mesh)平台,借此机会把相关的背景知识做一次学习和记录,方便回头查看. 初版的效果: 二.istio 官方手册:https://is ...

  3. 【连载】微服务网格Istio(一)

    Istio基础 服务网格是用于描述构成应用程序的微服务网络以及应用之间的交互,服务网格的功能包括服务发现.负载均衡.故障恢复.指标和监控以及更加复杂的运维工作,例如A/B测试.金丝雀发布.限流.访问控 ...

  4. 服务网格Istio入门-详细记录Kubernetes安装Istio并使用

    我最新最全的文章都在南瓜慢说 www.pkslow.com,文章更新也只在官网,欢迎大家来喝茶~~ 1 服务网格Istio Istio是开源的Service Mesh实现,一般用于Kubernetes ...

  5. 精彩分享 | 欢乐游戏 Istio 云原生服务网格三年实践思考

    作者 吴连火,腾讯游戏专家开发工程师,负责欢乐游戏大规模分布式服务器架构.有十余年微服务架构经验,擅长分布式系统领域,有丰富的高性能高可用实践经验,目前正带领团队完成云原生技术栈的全面转型. 导语 欢 ...

  6. Cilium 1.11 发布,带来内核级服务网格、拓扑感知路由....

    原文链接:https://isovalent.com/blog/post/2021-12-release-111 作者:Cilium 母公司 Isovalent 团队 译者:范彬,狄卫华,米开朗基杨 ...

  7. Service Mesh服务网格新生代--Istio(转)

    万字解读:Service Mesh服务网格新生代--Istio  官网地址:https://preliminary.istio.io/zh/docs/concepts/security/ Servic ...

  8. Service Mesh服务网格新生代--Istio

    原文: 数人云|万字解读:Service Mesh服务网格新生代--Istio 参考: istio 简介 Istio是啥?一文带你彻底了解! 使用Istio治理微服务入门 Istio 流量管理 ist ...

  9. Istio VirtualService 虚拟服务

    概念及示例 VirtualService 描述了一个或多个用户可寻址目标到网格内实际工作负载之间的映射 . 虚拟服务让您配置如何在服务网格内将请求路由到服务,这基于 Istio 和平台提供的基本的连通 ...

随机推荐

  1. MapReduce入门实战

    MapReduce 思想 MapReduce 是 Google 提出的一个软件架构,用于大规模数据集的并行运算.概率"Map(映射)"和"Reduce(归约)" ...

  2. Jmeter工具使用总结

    Jmeter工具使用总结 目录 Jmeter函数总结 第一章 前言 第二章 常用函数的介绍 2.1. timeShift函数 2.2. time函数 2.3. groovy函数 第三章 常用用法 3. ...

  3. (原创)【MAUI】在窗口(页面)关闭后获取其返回值

    一.前言 作为一名 Winform 和 WPF 的老用户,没想到 MAUI 上变化那么大. 就像传统的窗口,我弹出一个模式窗口,关闭窗口后是可以获取到窗口的返回值的,即: DialogResult.后 ...

  4. .NET WebAPI 采用 IDistributedCache 实现分布式缓存过滤器 Redis 模式

    分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护. 分布式缓存可以提高 ASP.NET Core 应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时. 与其 ...

  5. 原生应用、Web 应用和混合应用的概念,以及 Flutter 技术是什么

    应用类型 原生应用 原生应用就是使用特定的语言开发的应用,例如 Android 原生应用.Windows 原生应用.iOS 原生应用等.开发 Android 原生应用时,其特定的编程语言为 Java ...

  6. jbd2的死锁分析

    已经运行多年的jbd2,它还是死锁了 背景:这个是在centos7的环境上复现的,内核版本为3.10.0-957.27.2.el7 下面列一下我们是怎么排查并解这个问题的. 一.故障现象 oppo云内 ...

  7. 手把手教你怎么将linux的一个函数性能搞奔溃

    static struct fib_table *fib_empty_table(struct net *net){    u32 id;    for (id = 1; id <= RT_TA ...

  8. SyncFusion安装和使用

    1.Visual Studio 继承 Visual Studio菜单栏 → 扩展 → 扩展管理 → 搜索框中搜索 "Syncfusion Windows",单击 "Win ...

  9. 【短道速滑九】仿halcon中gauss_filter小半径高斯模糊优化的实现

    通常,我们谈的高斯模糊,都知道其是可以行列分离的算法,现在也有着各种优化算法实现,而且其速度基本是和参数大小无关的.但是,在我们实际的应用中,我们可能会发现,有至少50%以上的场景中,我们并不需要大半 ...

  10. csp每日习题

    欢迎加入:qq群号:1054587486 做题链接:https://csp.ccf.org.cn/csp/index.action?_access_code=1584494752035 点击模拟考试进 ...