亚马逊AWS官方博客
通过Istio在Amazon EKS上实现灰度发布
在微服务架构下,服务越来越多,版本更新频繁,如何能够在不影响已上线业务的情况下进行升级,需要运维团队有灰度发布的能力,通过灰度发布来说实现业务从老版本到新版本的平滑过渡,尽可能避免升级过程中出现的问题对客户造成影响。
在本篇博客中,将介绍如何通过Istio在Amazon EKS上实现灰度发布。
灰度发布:又称金丝雀发布,是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
Istio:是一种开源服务网格,是一种现代化的服务网络层,它提供一种透明、独立于语言的方法,实现应用网络功能自动化。Istio采用sidecar对应用流量进行了转发,通过Pilot下发路由规则,可以在不修改应用程序的前提下实现应用的灰度发布。借助 Istio可以保护、连接和监控微服务,可帮助组织在任何位置运行基于微服务的分布式应用,从而更快捷安全地实现企业应用现代化改造。
Amazon EKS: Amazon Elastic Kubernetes Service (Amazon EKS) 是一项托管 Kubernetes 服务,让您能够轻松在 AWS 上和本地运行 Kubernetes。Amazon EKS 经认证与 Kubernetes 一致,因此运行于上游 Kubernetes 的现有应用程序可与 Amazon EKS 兼容。Amazon EKS 可自动管理负责安排容器、管理应用程序可用性、存储集群数据和其他关键任务的 Kubernetes 控制平面节点的可用性和可扩展性。
为了演示灰度发布,我们以Istio官方提供的Bookinfo应用为例 :设置一个 EKS 集群、安装 Istio、部署bookinfo应用、使用istio实现灰度发布。
Bookinfo应用可分为四个单独的微服务: ·
- productpage 这个微服务会调用details和reviews两个微服务,用来生成页面。
- details 这个微服务中包含了书籍的信息。
- reviews 这个微服务中包含了书籍相关的评论。它还会调用ratings微服务。
- 这个微服务中包含了由书籍评价组成的评级信息。
reviews微服务有 3 个版本:
- v1 版本不会调用ratings服务。
- v2 版本会调用ratings服务,并使用 1 到 5 个黑色星形图标来显示评分信息。
- v3 版本会调用ratings服务,并使用 1 到 5 个红色星形图标来显示评分信息。
下图展示了这个应用的端到端架构。
环境准备
1.安装AWS CLI(以Linux为例)
其他类型操作系统安装AWS CLI请参考:安装AWS CLI
2.配置AWS Configuration
参考样例:
部署 EKS 集群
1.安装eksctl
eksctl是一个简单的 CLI 工具,用于在 Amazon EKS上创建和管理集群。
2.安装kubectl
Kubectl 是 Kubernetes 的命令行配置工具,可与 Kubernetes API 服务器进行通信,使用 kubectl 可以创建、检查、更新和删除 Kubernetes 对象。
3.创建EKS集群
通过eksctl在us-west-1创建EKS集群,包含2个节点,节点类型是c5.large。
看到如下输出内容时,EKS集群创建完成。
4.检查所有namespaces中的pod和节点的状态,确保所有namespaces中的pod都是Running,节点状态是Ready。
设置 Istio
1.安装Istio
Istio提供了一个二进制文件istioctl用于设置Istio并与Istio交互,下载安装Istio,并将istioctl工具添加到用户的PATH环境变量中。
通过运行istioctl x precheck预检查命令确认EKS环境是否正常;
为istio安装demo profile,包含Istio-core,Istiod,Egress gateway,Ingress gateway等插件。
istioctl install --set profile=demo -y
为default namespaces中设置istio-injection=enabled标签,开启sidercar自动注入。
kubectl label namespace default istio-injection=enabled
查看istio对应的namespaces和pods是否已经正常创建,并检查状态是否为Running。
2. 部署bookinfo应用:使用kubectl部署bookinfo应用。
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
检查services和pods状态,确认已经启动成功。
在ratings pod中调用productpage,验证bookinfo应用是否正常,当输出”<title>Simple Bookstor App</title>”时说明应用正常。
3. 部署Backinfo-Gateway
Bookinfo服务已经启动并在运行中,需要部署istio Gateway从外部访问Bookinfo应用。创建Gateway和Virtual Service等用户自定义资源(CRDs),然后访问应用程序
确认Node Port使用的Ingress IP和端口,并设置Gateway_URL。
通过浏览器访问productpage页面,刷新页面,如果看到reviews星级发生变化,说明已经成功部署了istio的demo。
4. 部署istio附加组件,如kiali dashboard、grafana、prometheus和jager,通过kubectl apply示例中addons目录下所有的文件。
kubectl apply -f samples/addons
5. 配置Kiali
Kiali是一个基于服务网格的istio管理控制台,它提供了一些列的仪表盘和可观测能力,展示整个网格的网络拓扑和服务的健康状况。默认情况下,Kiali通过Cluster IP暴露服务,如果需要从外部访问kiali的控制台页面,需要将默认配置spec.type:ClusterIp 修改为LoadBalancer。
配置生效后,查看kiali的访问地址和端口。
kubectl get svc kiali -n istio-system
在浏览器中访问Kiali,默认端口是20001
在Graph页面也看到调用关系。
6. 配置Grafana
修改grafana的Service配置,使用LoadBalancer的方式提供对外访问。
配置生效后,查看grafana的访问地址和端口。
在浏览器中访问grafana dashboard,默认端口是3000
用Istio实现灰度发布
采用Istio实现灰度发布,可以通过定制路由规则将特定的流量导入新版本服务中,可以最小化升级中出现的故障对用户的影响,同时存在新老版本服务时,还可根据应用压力对不同版本的服务进行独立的缩扩容。实现灰度发布前,我们先熟悉一下虚拟服务(VirtualService)和目标规则(destination rule)这两个概念。
虚拟服务(Vistrual Service)是 Istio 重要的资源对象,作用是将流量路由到网格中的服务,支持基于权重、http header条件等优先级的路由,颗粒度更加精细。
目标规则(Destination Rule)是 Istio 重要的资源对象,不能独自使用,必须跟 Virtual Service 共同发挥作用,作用是将流量标记分组并路由到具体服务。
下面我们通过4个任务模拟实现基于权重路由的灰度发布:
任务1:流量全部发送到reviews v1版本
任务2:90%流量发送到reviews v1版本,%10流量发送到reviews v2版本
任务3:50%流量发送到reviews v1版本,50%流量发送到reviews v3版本
任务4:流量全部发送到review v3版本
检查pods和服务的状态
任务1:
执行以下命令,将流量全部发送到reviews v1版本
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
yaml文件内容如下:
在Kiali中查看服务拓扑图如下:
任务2:
执行如下命令,将90%的流量发送到reviews v1版本,另外10%的流量发送到reviews v2版本:
kubectl apply -f virtual-service-reviews-90-10.yaml
yaml文件内容如下:
在Kiali中查看服务拓扑图如下:
任务3:
执行如下命令,将50%的流量发送到reviews v1版本,另外50%流量发送到reviews v3版本
kubectl apply -f virtual-service-reviews-50-v3.yaml
yaml文件内容如下:
在Kiali中查看服务拓扑图如下:
任务4:
运行如下命令,将流量全部发送到reviews v3版本。
kubectl apply -f virtual-service-reviews-v3.yaml
yaml文件内容如下:
在Kiali中查看服务拓扑图如下:
清理环境
1.卸载istio&bookinfo
2.删除EKS集群
eksctl delete cluster --name=eks-lab
参考资料:
istio参考文档:https://istio.io/latest/docs/setup/getting-started/
kubectl参考文档:https://kubernetes.io/docs/reference/kubectl/
eksctl参考文档:https://eksctl.io/introduction/