一、部署测试用例

1.1 介绍应用

下面部署了一个用于演示多种 Istio 特性的应用,该应用由四个单独的微服务构成:

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

其中reviews 微服务有 3 个版本:

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

其中应用的端到端架构如下:

部署测试用例-1

Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成,并且 reviews 服务具有多个版本。

1.2 部署应用

要在 Istio 中运行这一应用,无需对应用自身做出任何改变。 只要简单的在 Istio 环境中对服务进行配置和运行,具体一点说就是把 Envoy sidecar 注入到每个服务之中。 最终的部署结果将如下图所示:

部署测试用例-2

所有的微服务都和 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

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

部署测试用例-4

查看资源

[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

部署测试用例-5

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

部署测试用例-6

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

部署测试用例-7

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

部署测试用例-8

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

部署测试用例-9

部署测试用例-10

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

部署测试用例-11

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

部署测试用例-12

二、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实现灰度发布

关于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 变成了三个版本

Istio 灰度发布演示-1

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 处不再显示评分

Istio 灰度发布演示-2

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

Istio 灰度发布演示-3

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%的访问会出现评分(仅有黑色)

Istio 灰度发布演示-4

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

Istio 灰度发布演示-5

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%的访问会出现评分(仅有黑色)

Istio 灰度发布演示-6

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

Istio 灰度发布演示-7

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】

图形化管理灰度流量-1

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

图形化管理灰度流量-2

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

图形化管理灰度流量-3

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

图形化管理灰度流量-4

图形化管理灰度流量-5

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

图形化管理灰度流量-6