技术漫谈 | 使用Kubernetes,Istio和Helm实现金丝雀发布

栏目: 编程工具 · 发布时间: 5年前

内容简介:在近期的项目上,我通过流水线实现了金丝雀/灰度发布微服务应用。这些微服务被部署在Azure Kubernetes集群上(AKS)。本文假设您熟悉Kubernetes,Helm和Istio流量管理这篇文章描述了发布的基本要求,为这些要求选择的发布策略,以及每个阶段实现细节。

在近期的项目上,我通过流水线实现了金丝雀/灰度发布微服务应用。这些微服务被部署在Azure Kubernetes集群上(AKS)。

本文假设您熟悉Kubernetes,Helm和Istio流量管理

这篇文章描述了发布的基本要求,为这些要求选择的发布策略,以及每个阶段实现细节。

关键要求

高级要求是将应用程序服务通过金丝雀版本发布到生产环境中。

基本要求/限制:

1、每个Micro服务都应打包为单独的Helm图表。

2、不同的团队管理不同的微服务,每个团队应该能够独立于其他微服务发布。

3、服务网格Istio安装在kubernetes集群上

在项目的初始阶段,只有Helm和Istio可用于集群。在此阶段,不使用类似flagger这样的工具。

4、团队可以使用Helm chart分阶段的发布新版本应用程序:

  • 10%的流量路由到新版本
  • 90%的流量路由到新版本
  • 100%的流量路由到新版本

5、在每个阶段之后,需要手动判断以进入下一个发布阶段

6、每个阶段都可以使用Helm chart回滚到前一个生产版本

发布微服务资源

每个微服务都需要如下Kubernetes资源:

1、当前版本deployment,在新版本发布之前稳定运行的版本,承载100%的流量

2、金丝雀deployment,在发布之前是0个实例,不承载流量。当发布时,承载流量会逐步增至10%、90%、100%

3、service,与微服务当前deployment对应

4、Istio Virtual Service,用于控制当前deployment和金丝雀deployment流量分配的权重

5、Istio Destination Rule,包含当前deployment和金丝雀deployment的子集(subset)

6、Istio Gateway(可选),如果服务需要从容器集群外被访问则需要搭建gateway

列出上述资源,有助于我们理解第一章的实现细节。

查看Github仓库

这个仓库包含上述微服务的样例代码,dockerfile,Helm chart以及每个阶段执行的Helm命令。同时,仓库还包含了由Helm Chart的helm template命令生成的kubernetes示例资源。

使用的示例服务是istio产品页面应用程序,应用程序代码和 docker 文件来自istio github仓库。

仓库结构

1、产品页面应用的源码

2、应用容器的Dockerfile

3、Helm Chart文件夹包含kubernetes和istio资源

4、helm-commands.sh,包含各阶段helm命令(rollback命令、helm template命令)

5、helm-template-output.yaml,包含由helm template命令生成的kubernetes示例资源

关键内容

Helm Values

让我们看下Helm valuse文件:

service:

name: product-page-svc

port: 9080

productionDeployment:

replicaCount: 2

weight: 100

image:

repository: myacrepo.azurecr.io/bookinfo/productpage

tag: 83

pullPolicy: IfNotPresent

canaryDeployment:

replicaCount: 0

weight: 0

image:

repository: myacrepo.azurecr.io/bookinfo/productpage

tag: 83

pullPolicy: IfNotPresent

service部分包含了service名称。productionDeployment包含了副本数量、路由转发权重、容器镜像仓库名称、以及镜像tag。它跟canaryDeployment 有一点类似。上面的值表示当处于稳定状态时,100%的浏览被路由转发到现有生产版本Pods。而金丝雀版本则被设置为0副本,并且与生产版本使用相同镜像。当使用金丝雀发布时,金丝雀版本将被设置为使用新版本镜像。

在这个案例中,容器镜像打tag策略是使用对应的build id,然后把它推送到镜像仓库。所以如果应用程序的新版本被触发构建,则下一个版本容器镜像tag为84(83+1)。

我们也可以选择其他适合的镜像tag策略。

生产版本deployment文件

apiVersion: apps/v1beta2

kind: Deployment

metadata:

name: productpage

labels:

app: productpage

canary: "false"

spec:

replicas: 2

selector:

matchLabels:

  app: productpage

  canary: "false"

template:

metadata:

  labels:

    app: productpage

    canary: "false"

spec:

  containers:

    - name: productpage

      image: "myacrepo.azurecr.io/bookinfo-canary/productpage:83"

      imagePullPolicy: IfNotPresent

      ports:

        - name: http

          containerPort: 9080

          protocol: TCP

....

金丝雀版本Deployment文件

apiVersion: apps/v1beta2

kind: Deployment

metadata:

name: productpagecanary

labels:

app: productpage

canary: "true"

chart: productpage-0.1.0

spec:

replicas: 0

selector:

matchLabels:

  app: productpage

  canary: "true"

template:

metadata:

  labels:

    app: productpage

    canary: "true"

spec:

  containers:

    - name: productpagecanary

      image: "myacrepo.azurecr.io/bookinfo-canary/productpage:83"

      imagePullPolicy: IfNotPresent

      ports:

        - name: http

          containerPort: 9080

          protocol: TCP

   .....

两个Deployment文件的关键区别在于,生产版本canary标签的值为false,而金丝雀版本canary标签的值为true。另一个区别是在稳定状态下,金丝雀版本副本实例数量为0,所以不会运行任何金丝雀版本的pod。

Kubernetes Service

apiVersion: v1

kind: Service

metadata:

name: product-page-svc

spec:

ports:

- port: 9080

  targetPort: http

  protocol: TCP

  name: http

selector:

app: productpage

......

Istio Destination Rule

apiVersion: networking.istio.io/v1alpha3

kind: DestinationRule

.........

spec:

host: product-page-svc.bookinfo-k8s-helm-istio-canary.svc.cluster.local

.......

subsets:

- name: production

labels:

  canary: "false"

- name: canary

labels:

  canary: "true"

Istio destination rule描述了生产版本和金丝雀版本两个版本子集(subset)。生产版本子集的流量将会被转发给canary标签值为false的pod。金丝雀版本子集的流量将会转发给canary标签值为true的pod。

Destination rule中的host是service的FQDN,由service名称和kubernetes namespace构成。

Istio Virtual Service

apiVersion: networking.istio.io/v1alpha3

kind: VirtualService

...

spec:

hosts:

- product-page-svc.bookinfo-k8s-helm-istio-canary.svc.cluster.local

gateways:

- product-page

http:

- route:

- destination:

    host: product-page-svc.bookinfo-k8s-helm-istio-canary.svc.cluster.local

    subset: production

    port:

      number: 9080

  weight: 100

- destination:

    host: product-page-svc.bookinfo-k8s-helm-istio-canary.svc.cluster.local

    subset: canary

    port:

      number: 9080

  weight: 0

Virtual service控制着生产版本与金丝雀版本之间的流量分配比例。

发布阶段的细节

在阶段概览图中用黄色高亮标注出上一节介绍的变化值。接下来我们将docker镜像tag从当前的83升级至84。

阶段1:稳定状态,100%流量转发给应用当前部署的生产版本。没有版本正在发布,金丝雀版本为0个副本,并且不被转发任何流量。

Helm命令

helm upgrade  --install --namespace bookinfo-k8s-helm-istio-canary --values 

./productpage/chart/productpage/values.yaml --set 

productionDeployment.image.repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,productionDeployment.image.tag=83,productionDeployment.

weight=100,productionDeployment.replicaCount=2,canaryDeployment.

image.repository=myacrepo.azurecr.io/bookinfo-canary/productpage,canaryDeployment.image.tag=83,canaryDeployment.

replicaCount=0,canaryDeployment.weight=0 --wait productpage 

./productpage/chart/productpage

阶段概览

技术漫谈 | 使用Kubernetes,Istio和Helm实现金丝雀发布

阶段2:正在发布,金丝雀版本副本数量被设置为2个,它使用新版应用镜像(tag 84)。10%的流量被转发给金丝雀版本pod,其余90%的流量被转发给原来的生产版本pod。

Helm命令

helm upgrade  --install --namespace bookinfo-k8s-helm-istio-canary --values 

./productpage/chart/productpage/values.yaml --set 

productionDeployment.image.repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,productionDeployment.image.tag=83,productionDeployment.

weight=90,productionDeployment.replicaCount=2,canaryDeployment.image.

repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,canaryDeployment.image.tag=84

,canaryDeployment.replicaCount=2,canaryDeployment.weight=10 --wait 

productpage ./productpage/chart/productpage

阶段概览

技术漫谈 | 使用Kubernetes,Istio和Helm实现金丝雀发布

阶段3:90%流量被转发给金丝雀版本pod,10%流量被转发给原有生产版本pod。

Helm命令

helm upgrade  --install --namespace bookinfo-k8s-helm-istio-canary --values 

./productpage/chart/productpage/values.yaml --set 

productionDeployment.image.repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,productionDeployment.image.tag=83,productionDeployment.

weight=10,productionDeployment.replicaCount=2,canaryDeployment.image.

repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,canaryDeployment.image.tag=84,

canaryDeployment.replicaCount=2,canaryDeployment.weight=90 --wait 

productpage ./productpage/chart/productpage

阶段概览

技术漫谈 | 使用Kubernetes,Istio和Helm实现金丝雀发布

阶段4:100%流量被转发给金丝雀版本pod

Helm命令

helm upgrade  --install --namespace bookinfo-k8s-helm-istio-canary --values

./productpage/chart/productpage/values.yaml --set 

productionDeployment.image.repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,productionDeployment.image.tag=83,productionDeployment.

weight=0,productionDeployment.replicaCount=2,canaryDeployment.image.

repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,canaryDeployment.image.tag=84,

canaryDeployment.replicaCount=2,canaryDeployment.weight=100 --wait 

productpage ./productpage/chart/productpage

阶段概览

技术漫谈 | 使用Kubernetes,Istio和Helm实现金丝雀发布

阶段5:当100%流量被转发给金丝雀版本后,对生产版本执行滚动更新,将镜像tag更新为84。

这一步需要在将流量切回生产部署版本之前操作。

Helm命令

helm upgrade  --install --namespace bookinfo-k8s-helm-istio-canary --values 

./productpage/chart/productpage/values.yaml --set

productionDeployment.image.repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,productionDeployment.image.tag=84,productionDeployment.

weight=0,productionDeployment.replicaCount=2,canaryDeployment.image.

repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,canaryDeployment.image.tag=84,canaryDeployment.

replicaCount=2,canaryDeployment.weight=100 --wait productpage 

./productpage/chart/productpage

阶段概览

技术漫谈 | 使用Kubernetes,Istio和Helm实现金丝雀发布

阶段6:将100%流量切换回生产版本pod,而此时生产版本pod已经使用最新应用镜像(tag 84)。

helm upgrade  --install --namespace bookinfo-k8s-helm-istio-canary --values

./productpage/chart/productpage/values.yaml --set 

productionDeployment.image.repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,productionDeployment.image.tag=84,productionDeployment.

weight=100,productionDeployment.replicaCount=2,canaryDeployment.image.

repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,canaryDeployment.image.tag=84,canaryDeployment.

replicaCount=2,canaryDeployment.weight=0 --wait productpage

./productpage/chart/productpage

阶段概览

技术漫谈 | 使用Kubernetes,Istio和Helm实现金丝雀发布

阶段7:新的稳定状态,金丝雀版本副本数量再次被修改为0,100%流量被转发给最新应用生产版本(容器镜像tag为84)。

Helm命令

helm upgrade  --install --namespace bookinfo-k8s-helm-istio-canary --values 

./productpage/chart/productpage/values.yaml --set

productionDeployment.image.repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,productionDeployment.image.tag=84,productionDeployment.

weight=100,productionDeployment.replicaCount=2,canaryDeployment.image.

repository=myacrepo.azurecr.io/b

ookinfocanary/productpage,canaryDeployment.image.tag=84,

canaryDeployment.replicaCount=0,canaryDeployment.weight=0 --wait 

productpage ./productpage/chart/productpage

阶段概览

技术漫谈 | 使用Kubernetes,Istio和Helm实现金丝雀发布

任一阶段回滚

我们可以在任一阶段使用Helm命令回滚至应用的前一个版本

helm upgrade  --install --namespace bookinfo-k8s-helm-istio-canary --values

./productpage/chart/productpage/values.yaml --set

productionDeployment.image.repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,productionDeployment.image.tag=83,productionDeployment.

weight=100,productionDeployment.replicaCount=2,canaryDeployment.image.

repository=myacrepo.azurecr.io/bookinfo-

canary/productpage,canaryDeployment.image.tag=83,canaryDeployment.

replicaCount=0,canaryDeployment.weight=0 --wait productpage ./productpage/chart/productpage

在任一阶段测试应用

在这个案例中,产品页面需要可以从集群外部访问,因此我们需要istio网关。从服务器外部访问istio网关,需要获取它的外部IP。

kubectl get svc istio-ingressgateway  -n istio-system

一旦获取了外部IP,可以通过添加主机host文件记录的方式来快速测试

23.XX.YY.ZZ product-page-svc.bookinfo-k8s-helm-istio-canary.svc.cluster.local

服务访问url

http://product-page-svc.bookin ... local

/productpage?u=normal。

翻译作者:Song

微信翻译原文: https://mp.weixin.qq.com/s/0bfKeNogIw4_W_UY_zLp4g

原文阅读:

< https://medium.com/microsoftaz ... 406f0 7>

相关链接:

AKS:

https://azure.microsoft.com/en ... rvice /)

Kubernetes:

https://kubernetes.io/

Helm:

https://helm.sh/

Istio流量管理:

https://istio.io/docs/concepts/traffic-management/

Istio:

https://istio.io/

flagger:

https://github.com/weaveworks/flagger

关于睿云智合

深圳睿云智合科技有限公司成立于2012年,总部位于深圳,并分别在成都、深圳设立了研发中心,北京、上海设立了分支机构,核心骨干人员全部为来自金融、科技行业知名企业资深业务专家、技术专家。早期专注于为中国金融保险等大型企业提供创新技术、电子商务、CRM等领域专业咨询服务。

自2016年始,在率先将容器技术引进到中国保险行业客户后,公司组建了专业的容器技术产品研发和实施服务团队,旨在帮助中国金融行业客户将容器创新技术应用于企业信息技术支持业务发展的基础能力改善与提升,成为中国金融保险行业容器技术服务领导品牌。

此外,凭借多年来在呼叫中心领域的业务经验与技术积累,睿云智合率先在业界推出基于开源软交换平台FreeSwitch的微服务架构多媒体数字化业务平台,将语音、视频、webchat、微信、微博等多种客户接触渠道集成,实现客户统一接入、精准识别、智能路由的CRM策略,并以容器化治理来支持平台的全应用生命周期管理,显著提升了数字化业务处理的灵活、高效、弹性、稳定等特性,为帮助传统企业向“以客户为中心”的数字化业务转型提供完美的一站式整体解决方案。


以上所述就是小编给大家介绍的《技术漫谈 | 使用Kubernetes,Istio和Helm实现金丝雀发布》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

商业的常识

商业的常识

申音 / 山西经济出版社 / 2011-7-1 / 35.00元

★为什么美国没有史玉柱,中国没有乔布斯? ★什么是“对的行业”、“错的行业”? ★我们需要什么样的营销? ★老板为什么要读商学院? ★山寨公司还需要管理吗? ★资源问题是个“伪问题”? ★别把商业模式当成葵花宝典 ★给海归技术创业兄弟的九个忠告 ★在一个不伟大的行业里,做一个伟大的公司 ★是什么让互联网遭遇了有史以来最鸡犬不宁的一战?一起来看看 《商业的常识》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具