一、部署测试用例¶
1.1 介绍应用¶
下面部署了一个用于演示多种 Istio 特性的应用,该应用由四个单独的微服务构成:
productpage. 这个微服务会调用details和reviews两个微服务,用来生成页面。details. 这个微服务中包含了书籍的信息。reviews. 这个微服务中包含了书籍相关的评论。它还会调用ratings微服务。ratings. 这个微服务中包含了由书籍评价组成的评级信息。
其中reviews 微服务有 3 个版本:
- v1 版本不会调用
ratings服务。 - v2 版本会调用
ratings服务,并使用 1 到 5 个黑色星形图标来显示评分信息。 - v3 版本会调用
ratings服务,并使用 1 到 5 个红色星形图标来显示评分信息。
其中应用的端到端架构如下:

Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成,并且 reviews 服务具有多个版本。
1.2 部署应用¶
要在 Istio 中运行这一应用,无需对应用自身做出任何改变。 只要简单的在 Istio 环境中对服务进行配置和运行,具体一点说就是把 Envoy sidecar 注入到每个服务之中。 最终的部署结果将如下图所示:

所有的微服务都和 Envoy sidecar 集成在一起,被集成服务所有的出入流量都被 sidecar 所劫持,这样就为外部控制准备了所需的 Hook,然后就可以利用 Istio 控制平面为应用提供服务路由、遥测数据收集以及策略实施等功能。
下面开始正式部署:
1.创建 Bookinfo所需的ns
[root@k8s-master01 ~]# kubectl create ns bookinfo
2.添加一个 istio-injection=enabled 的标签,之后在该 Namespace 下创建的 Pod 就会被自动注入 Istio 的 Proxy
[root@k8s-master01 ~]# kubectl label ns bookinfo istio-injection=enabled
当然了,你也可以在kiali界面上操作也可以实现相同的目的

3.创建 Bookinfo
[root@k8s-master01 ~]# cd istio-1.16.0
[root@k8s-master01 istio-1.16.0]# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
查看部署的 Pod 和 Service
[root@k8s-master01 kube]# kubectl get po -n bookinfo
NAME READY STATUS RESTARTS AGE
details-v1-698b5d8c98-jptgt 2/2 Running 0 9h
productpage-v1-bf4b489d8-xrbs9 2/2 Running 0 9h
ratings-v1-5967f59c58-6gx7z 2/2 Running 0 9h
reviews-v1-9c6bb6658-gjzpb 2/2 Running 0 9h
reviews-v2-8454bb78d8-d8gvv 2/2 Running 0 9h
reviews-v3-6dc9897554-ksdzc 2/2 Running 0 9h
[root@k8s-master01 kube]# kubectl get svc -n bookinfo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.0.253.139 <none> 9080/TCP 9h
productpage ClusterIP 10.0.99.31 <none> 9080/TCP 9h
ratings ClusterIP 10.0.128.42 <none> 9080/TCP 9h
reviews ClusterIP 10.0.18.76 <none> 9080/TCP 9h
4.通过 productpage Service 的 ClusterIP 访问 Bookinfo 项目
[root@k8s-master01 ~]# curl -I 10.0.99.31:9080
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 1683
server: istio-envoy
date: Mon, 07 Aug 2023 22:56:36 GMT
x-envoy-upstream-service-time: 1
x-envoy-decorator-operation: productpage.bookinfo.svc.cluster.local:9080/*
5.创建 Istio 的 Gateway 和 VirtualService 实现域名访问 Bookinfo 项目,域名是 bookinfo.kubeasy.com
[root@k8s-master01 ~]# vim istio-1.16.0/samples/bookinfo/networking/bookinfo-gateway.yaml
[root@k8s-master01 ~]# kubectl create -f istio-1.16.0/samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo

查看资源
[root@k8s-master01 samples]# kubectl get gw,vs -n bookinfo
NAME AGE
gateway.networking.istio.io/bookinfo-gateway 21s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/bookinfo ["bookinfo-gateway"] ["bookinfo.kubeasy.com"] 21s
6.在win主机上修改hosts文件,文件路径为:C:\Windows\System32\drivers\etc\hosts
192.168.1.31 bookinfo.kubeasy.com
将域名 bookinfo.kubeasy.com 解析至集群任意一个安装了 kube-proxy 的节点 IP 上,通过 ingressgateway 的 Service 的 NodePort 即可访问到 Bookinfo
[root@k8s-master01 samples]# kubectl get svc -n istio-system istio-ingressgateway
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway NodePort 10.0.26.1 <none> 15020:30520/TCP,80:30080/TCP,443:30443/TCP 24h
7.通过 bookinfo.kubeasy.com+ingressgateway 80 端口的 NodePort 即可访问该服 务,这里为bookinfo.kubeasy.com:30080/productpage
此时打开为v1

继续刷新,此时打开为v2版本

继续刷新,此时打开为v3版本

8.在浏览器中输入节点IP:30590登录Kiali 页面后,可以查看流量进入情况
[root@k8s-master01 samples]# kubectl get svc -n istio-system | grep kiali
kiali NodePort 10.0.160.103 <none> 20001:30590/TCP,9090:30087/TCP 24h

点击【Graph】可以看到 Bookinfo 的调用链路


至于图形对应含义可点击如下图标进行查看

点击【Display】-【Traffic Animation】即可查看调用链路走向动态图,多次刷新 bookinfo后,会显示走向动态

二、Istio 实现灰度部署¶
2.1 什么是滚动发布¶
在 Kubernetes (K8s) 中,滚动发布(Rolling Deployment)是一种应用程序更新和部署的策略。它允许你在不中断应用程序的情况下逐步将新版本部署到生产环境,以确保应用程序的连续可用性。
滚动发布的主要思想是将新版本的应用程序逐步引入生产环境,替换旧版本的实例。这样做有助于减少用户的中断,降低风险,并允许系统在更新过程中保持可用。
在 Kubernetes 中,滚动发布通常通过以下方式来实现:
- 副本集(ReplicaSet): ReplicaSet 是 Kubernetes 中的一种资源,用于管理多个副本(Pod 的副本)。当需要进行滚动发布时,可以创建一个新的 ReplicaSet,该 ReplicaSet 包含新版本的容器镜像,同时保留旧版本的 ReplicaSet。
- 控制器和策略: Kubernetes 控制器,如 Deployment 和 StatefulSet,提供了管理副本集的抽象层。你可以使用这些控制器定义滚动发布的策略,例如同时保持新旧版本的一定数量的副本,逐步增加新版本的副本数量,然后逐步减少旧版本的副本数量。
- 滚动更新策略: 在 Deployment 中,可以定义滚动更新策略,如最大不可用副本数、更新间隔等。这些策略可以帮助控制更新的速率和稳定性,以适应不同的部署需求。
滚动发布的优势在于减少了部署过程中的风险,因为新版本逐步引入,而不是一次性替换整个应用程序。这有助于捕获潜在的问题,同时保持应用程序的可用性。
2.2 什么是灰度发布¶
在 Kubernetes 中,灰度发布(Gray Release)是一种应用程序部署策略,允许你在一部分用户或流量中逐步引入新版本的应用程序,以便在生产环境中测试和验证新功能或变更,同时减少可能的风险。
与滚动发布类似,灰度发布也是为了降低部署新版本的风险,但与滚动发布不同的是,灰度发布更关注在一个时间段内只将一小部分流量导向新版本,以实现逐步迭代和验证新功能。
在 Kubernetes 中实现灰度发布可以借助以下几种方式:
- Ingress 路由规则: 使用 Ingress 控制器可以根据特定的规则将一部分流量导向新版本的服务,而将其余的流量保持在旧版本上。这可以通过 Ingress 路由规则中的路径、主机名等来实现。
- Service 路由策略: 使用 Kubernetes 的 Service 资源可以将流量导向不同的 Pod 副本集。通过逐步更新 Service 的后端 Pod 集合,你可以将一部分流量引导到新版本。
- 权重调整: 一些 Ingress 控制器和服务代理支持设置流量分配的权重。可以通过逐步调整权重来逐渐将更多流量引导到新版本。
- Header 标记: 在某些情况下,可以在请求的 Header 中添加特定标记,然后使用该标记来决定将请求发送到新版本或旧版本。
总的来说,灰度发布允许在生产环境中逐步引入新版本,以便测试和验证其功能和性能,同时避免可能的问题对所有用户造成影响。
2.3 什么是金丝雀发布¶
在 Kubernetes 中,金丝雀发布(Canary Release)是一种应用程序部署策略,用于逐步引入新版本的应用程序,以在生产环境中进行实时测试和验证。金丝雀发布的目标是在一小部分用户或流量中验证新版本,以便及早发现潜在的问题,并在验证通过后逐步扩大新版本的范围。
金丝雀发布与灰度发布类似,但更强调逐步增加新版本的用户流量,以及根据实时反馈和监测结果来决定是否继续进行发布。
在 Kubernetes 中实现金丝雀发布可以通过以下方式:
- Traffic Split(流量分割): 使用 Istio 等服务网格或 Ingress 控制器,可以定义流量分割策略,将一部分用户或流量导向新版本,而将其余的流量继续保持在旧版本。
- 权重调整: 通过调整流量分配的权重,可以逐步增加新版本的流量份额,例如从初始的少量流量开始,然后逐渐增加到全部流量。
- 监测和反馈: 在金丝雀发布过程中,监测新版本的性能、稳定性和用户反馈非常重要。可以设置监控指标,例如请求响应时间、错误率等,以及实时观察用户的反馈,以便在需要时快速回滚或继续发布。
- 自动化回滚: 如果在金丝雀发布过程中发现了问题,可以自动或手动回滚到旧版本,以确保用户体验不受影响。
总之,金丝雀发布是一种先进的部署策略,强调通过实时监测和反馈来逐步引入新版本,以保证在不影响大多数用户的情况下进行实时测试和验证。
2.4 Istio 如何实现灰度发布¶

关于Istio 如何实现灰度发布,总结如下:
1.给不同Pod打上不同意义的标签,比如version=v1、version=v2,然后使用DR划分Subnet(通过标签进行设置)
2.配置VS设置权值比重将流量全部导向旧版本
3.部署新版本
4.重新设置VS中的权值比重切换流量导向新版本
2.5 Istio 灰度发布演示¶
1.将 reviews 的所有流量指向v1版本,此时需要通过 DestinationRule 将 reviews 分成两个版本:
[root@k8s-master01 ~]# vim reviews-dr.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1 # subset v1 指向具有 version=v1 的 Pod
- name: v2
labels:
version: v2 # subset v2 指向具有 version=v2 的 Pod
创建并查看该 DestinationRule
[root@k8s-master01 ~]# kubectl create -f reviews-dr.yaml -n bookinfo
destinationrule.networking.istio.io/reviews created
[root@k8s-master01 ~]# kubectl get dr -n bookinfo
NAME HOST AGE
reviews reviews 7s
通过浏览器访问该服务时,并没有什么变化,此时只是创建了 DestinationRule,并没有做任何限制。但是 Kiali 中可以看到 reviews 变成了三个版本

2.配置 VirtualService 将所有流量指向 reviews 的 v1 版本
[root@k8s-master01 ~]# cat reviews-v1-all.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1 # 将流量指向 v1
创建vs
[root@k8s-master01 ~]# kubectl create -f reviews-v1-all.yaml -n bookinfo
virtualservice.networking.istio.io/reviews created
此时再次刷新浏览器,Reviews 处不再显示评分

同时在 Kiali 中可以看到 reviews 变成了一个版本,只有v1

3.修改 VirtualService,将 20%的流量导向 v2 版本
[root@k8s-master01 ~]# vim reviews-20v2-80v1.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1 # 将 80%流量指向 v1
weight: 80 # 只需要配置一个 weight 参数即可
- destination:
host: reviews
subset: v2 # 将 20%流量指向 v2
weight: 20
替换yaml
[root@k8s-master01 ~]# kubectl replace -f reviews-20v2-80v1.yaml -n bookinfo
virtualservice.networking.istio.io/reviews replaced
再次使用浏览器访问时,会有 20%的访问会出现评分(仅有黑色)

同时登录kiali页面也可以看到v2 版本的 review 调用 ratings,且v1和v2的流量比例大概在8:2

4.假设 v2 版本已经没有任何问题,可以将流量全部指向 v2 版本
[root@k8s-master01 ~]# cat reviews-v2-all.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v2 # 将流量指向 v2
替换yaml
[root@k8s-master01 ~]# kubectl replace -f reviews-v2-all.yaml -n bookinfo
virtualservice.networking.istio.io/reviews replaced
再次使用浏览器访问时,会有 100%的访问会出现评分(仅有黑色)

同时登录kiali页面,观察只有v2的调用链

2.6 图形化管理灰度流量¶
除了上面通过yaml的方式管理灰度流量外,还可以通过kiali界面进行灰度流量管理。
1.因为上面yaml创建的dr和vs,kiali界面无法识别,需要先删除之前的dr和vs
[root@k8s-master01 ~]# kubectl delete dr reviews -n bookinfo
[root@k8s-master01 ~]# kubectl delete vs reviews -n bookinfo
2.登录kiali界面,依次点击【Services】-【reviews】

3.再点击【Actions】-【Traffic Shifting】

4.假设流量全部分给v2版本,直接调整至100%后,点击【Preview】

此时自动生成vs和dr,点击【Create】即可


5.使用浏览器访问时,会有 100%的访问会出现评分(仅有黑色)
