全部产品

基于Istio的Kubernetes蓝绿发布

更新时间:2019-07-30 15:59:27

基于Istio的Kubernetes蓝绿发布

本文将向读者介绍如何在云效中发布基于Istio的应用程序,同时利用云效提供的蓝绿发布能力更安全的发布和验证应用。

本文采用Istio官方的Bookinfo实例程序,源码地址:https://gitee.com/moo/bookinfo.git

前提条件

  • 在阿里云容器服务Kubernetes中创建集群,并导入到当前企业中
  • Kuberntes集群安装Istio组件
  • 开通阿里云镜像仓库服务用于托管容器镜像

    创建项目

在云效中我们采用项目的概念来管理一组相关的应用,并且对项目提供了如敏捷看板,测试,文档等服务。通过项目可以端到端的管理应用的整个交付周期:

创建项目

这里我们为Bookinfo创建一个独立的项目,创建完成后就可以进入到该项目的主页:

项目首页

创建应用

Bookinfo应用是一个典型的微服务应用程序,其主要结构如下所示:

Bookinfo

Bookinfo示例程序组要由Productpage,Reviews,Details以及Ratings4个部分组成,同时使用了Python,Java,Ruby以及Node四种不同的技术栈。

创建Productpage应用

首先,我们在Bookinfo项目下创建应用productpage,如下所示:

创建应用1

由于示例应用源码是托管到码云(Gitee)中,我们需要完成码云授权,并关联已有源码:

创建应用2

关联已有代码后,我们需要为当前应用选择相应的应用模板,当前Productpage应用采用Python进行开发,并且使用Kubernetes进行部署:

创建应用3

在完成编程语言以及部署选项的设置后,用户需要定义应用时如何构建的,由于需要将应用部署到Kubernetes中,这里我们勾选Docker构建选项,并且定义了当前应用镜像发布的镜像仓库为rdc-samples/productpage。云效会自定在项目中生成productpage.release文件,该文件定义了Productpage是如何构建的:

创建应用4

下一步,预览并创建应用即可。

应用列表

查看源码,可以看到云效自动创建的release文件:https://gitee.com/moo/bookinfo/blob/master/productpage.release

app.release

由于Productpage应用是在项目的src/productpage路径下,这里需要手动修改productpage.release文件的内容,并制定Productpage应用的Dockerfile文件路径,完整配置如下所示:

  1. # 构建源码语言类型
  2. code.language=python2.7
  3. # Docker镜像构建之后push的仓库地址
  4. docker.file=src/productpage/Dockerfile
  5. docker.repo=registry.cn-hangzhou.aliyuncs.com/rdc-samples/productpage

进入到productpage应用,可以看到在云效中应用会包含应用的发布流水线,配置管理,环境管理以及版本等能力:

应用首页

进入到应用的发布页面可以看到云效为应用自动创建的持续交付流水线。触发流水线构建,在构建阶段云效会根据productpage.release文件定义的内容对项目进行打包以及镜像构建,并且将镜像推送到阿里云镜像仓库服务:

流水线

不过由于,我们还未进行日常,预发以及正式环境的部署配置,因此当流水线运行到日常部署阶段,会出现如下错误信息:

部署配置提示

根据提示,我们进入到日常环境的部署配置页面,这里我们为日常环境创建了名为dev的命名空间,并且为该命名空间启用了Istio的自动注入能力:

  1. kubectl create namespace dev
  2. kubectl label namespace dev istio-injection=enabled

选择集群,命名空间并且新建productpage服务:

新建服务

这里需要指定Productpage服务的端口以及相应的容器端口,在bookinfo中productpage应用监听的是9080端口,完成配置后如下所示,对于启用了Istio支持的集群,云效会自动打开蓝绿部署选项:

部署配置

完成配置后,回到流水线页面重新触发日常环境部署动作,由于是第一次部署Productpage服务,云效会直接完成服务的初始化动作:

首次部署

查看发布单,可以查看具体的资源信息,这里云效自动创建了productpage的Pod实例,并且可以看到自动注入的istio-proxy容器:

发布单

部署单发布完成后,查看当前集群dev命名空间下的所有资源如下所示:

  1. $ kubectl -n dev get all --selector='app=productpage'
  2. NAME READY STATUS RESTARTS AGE
  3. pod/productpage-vuhpe-df8967b85-gw28g 2/2 Running 0 3m
  4. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  5. service/productpage ClusterIP 172.19.0.131 <none> 9080/TCP 54m
  6. NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
  7. deployment.apps/productpage-vuhpe 1 1 1 1 3m
  8. NAME DESIRED CURRENT READY AGE
  9. replicaset.apps/productpage-vuhpe-df8967b85 1 1 1 3m

云效会为应用版本创建相应的DestinationRules以及VirtualService资源,并且在第一次部署完成后自动将路由规则定向到当前部署版本。

查看DestinationRules如下所示:

  1. #$ kubectl -n dev get destinationrules productpage -o yaml
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: DestinationRule
  4. metadata:
  5. creationTimestamp: 2018-12-14T11:59:07Z
  6. generation: 1
  7. name: productpage
  8. namespace: dev
  9. resourceVersion: "341256082"
  10. selfLink: /apis/networking.istio.io/v1alpha3/namespaces/dev/destinationrules/productpage
  11. uid: a8fe5fc8-ff97-11e8-bbda-de3c7d18d080
  12. spec:
  13. host: productpage
  14. subsets:
  15. - labels:
  16. version: vuhpe
  17. name: vuhpe

查看VirtualService如下所示:

  1. #$ kubectl -n dev get virtualservice productpage -o yaml
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: VirtualService
  4. metadata:
  5. creationTimestamp: 2018-12-14T11:59:07Z
  6. generation: 1
  7. name: productpage
  8. namespace: dev
  9. resourceVersion: "341256093"
  10. selfLink: /apis/networking.istio.io/v1alpha3/namespaces/dev/virtualservices/productpage
  11. uid: a90d8198-ff97-11e8-bbda-de3c7d18d080
  12. spec:
  13. hosts:
  14. - productpage
  15. http:
  16. - route:
  17. - destination:
  18. host: productpage
  19. subset: vuhpe

使用Istio Gateway访问应用

为了能够访问Productpage应用,用户需要在dev命名空间下部署Gateway资源如下所示:

  1. apiVersion: networking.istio.io/v1alpha3
  2. kind: Gateway
  3. metadata:
  4. name: bookinfo-gateway
  5. namespace: dev
  6. spec:
  7. selector:
  8. istio: ingressgateway
  9. servers:
  10. - hosts:
  11. - '*'
  12. port:
  13. name: http
  14. number: 80
  15. protocol: HTTP

将以上内容保存到bookinfo-gateway.yaml中,并通过Kubectl在集群中创建:

  1. $ kubectl -n dev create -f bookinfo-gateway.yaml
  2. gateway.networking.istio.io/bookinfo-gateway created

创建完Gateway之后,需要手动绑定Productpage服务和Gateway绑定:

  1. $ kubectl -n dev edit virtualservice productpage
  2. apiVersion: networking.istio.io/v1alpha3
  3. kind: VirtualService
  4. metadata:
  5. creationTimestamp: 2018-12-14T11:59:07Z
  6. generation: 1
  7. name: productpage
  8. namespace: dev
  9. resourceVersion: "341256093"
  10. selfLink: /apis/networking.istio.io/v1alpha3/namespaces/dev/virtualservices/productpage
  11. uid: a90d8198-ff97-11e8-bbda-de3c7d18d080
  12. spec:
  13. # 添加gateways节点绑定bookinfo-gateway
  14. gateways:
  15. - bookinfo-gateway
  16. hosts:
  17. # 添加需要监听的域名
  18. - productpage.yunxiao.com
  19. - productpage
  20. http:
  21. - route:
  22. - destination:
  23. host: productpage
  24. subset: vuhpe

在完成VirtualService完成Gateway绑定后,用户就可以通过集群的istio Gateway访问应用,可以通过以下命令获取Istio Gateway的外网地址:

  1. $ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  2. $ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http")].port}')

此时只需要在本地添加DNS设置,即可通过Gateway访问ProductPage应用:

  1. 182.92.244.178 productpage.yunxiao.com

打开浏览器访问http://productpage.yunxiao.com/productpage,如下所示:

ProductPage

不过由于目前我们只部署了Productpage应用,因此当前页面会提示“Error fetching product details!”和“Error fetching product reviews!”的错误信息。

使用蓝绿发布

在Productpage应用第一次发布时由于集群中并不存在任何资源,因此云效会直接创建资源并且将部署设置为成功。在第二次部署应用时,由于底层资源已存在,再次运行流水线,会触发正式的蓝绿部署流程。修改productpage.html文件如下所示:

修改页面

并重新触发流水线,此时当进入到部署阶段后部署任务会进入等待状态:

重新部署

点击查看发布单按钮,进入发布单页面,可以看到云效为当前服务创建了两个Deploymet版本:

发布暂停

在默认情况下,当前应用的所有流量依然全部指向旧版的应用实例,访http://productpage.yunxiao.com/productpage可以验证当前应用的流量情况:

验证流量

在部署暂停时如果希望某些流量能够进入到新版应用,例如,某些特定的URL或者是HTTP Header中包含特定值的请求。那可以直接在发布单中编辑灰度规则即可。例如,我们希望所有/productpage的请求都直接进入新版,那如下所示,添加一条灰度规则即可:

修改流量规则

预览生成的YAML并下发规则:

预览yaml

在灰度规则更新成功后,此时如果再次访问应用,那流量则会进入到新版的ProductPage中:

验证新版流量

在确认新版应用能够按照预期工作后,在发布单点击继续按钮,即可完成本次发布过程。发布完成后云效会自动移除旧版应用实例,并且将所有流量规则指向新版本。

发布完成

小结

在这部分中,我们完成了对bookinfo中productpage应用的发布,通过使用云效可以让用户几乎0成本的将应用接入到Istio模式,并且使用蓝绿部署模式安全的对软件进行升级和发布。