# 基于Kubernetes Nginx-Ingress实现应用的灰度发布
#### 应用场景
本实践基于Kubernetes原生的特性实现灰度发布。在用户进行新系统升级时，会遇到停服部署或者无法灰度验证的情况，本实践采用基于Kubernetes原生的Service特性，在不影响业务正常运行的前提下，实现系统的平滑升级。
#### 方案架构
系统升级时，开发人员第一次部署应用会创建出一组灰度负载，此时灰度负载中的系统版本为新版本，此时Service将部分流量转发至灰度负载上，由测试人员在灰度负载中进行版本验证。版本验证结束后，开发人员开始第二次部署应用升级现网服务，此时Service将全部流量转发至灰度负载上并升级现网服务，现网服务升级到最新版本后，Service将全部流量转发回现网负载并释放灰度负载，完成新系统的发布。
图1灰度发布原理   
![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919020252.png "点击放大")
#### 前提条件
- 已有可用项目，如果没有，请先[新建 CodeArts 项目](https://support.huaweicloud.com/usermanual-devcloud/codearts_01_0027.html)。
- 具有创建应用的权限，参考[权限管理](https://support.huaweicloud.com/usermanual-deployman/deployman_hlp_0035.html)。
- 服务包含以下资源，并定义为v1版本：
  - 已有CCE集群，示例：cce-demo；
  
  - CCE集群中已创建无状态工作负载，示例：deployment-doc；
  
  - CCE集群中已创建服务，示例：service-doc；
  
  - CCE集群中已创建路由，示例：ingress-doc；
  
  - CCE集群中已安装nginx-ingress插件。
   
 
#### 操作流程
图2操作流程示意图   
![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001919020244.png)
1. 新建应用。
   
   1. 进入CodeArts平台，单击目标项目名称进入项目。
   
   2. 单击**"持续交付 \> 部署"** ，单击**"新建应用"** ，进入**"基本信息"**页面。
   
   3. 可根据需要修改以下基本信息。
      
      | 参数项     | 是否必填 | 说明                                                                                                                                                                                           |
      |:---|:---|:---|
      | 名称       | 是    | 应用的名称。示例：**Kubernetes_Nginx-Ingress灰度部署**                                                                                                                                                    |
      | 所属项目     | 是      | 默认。该应用的归属项目。                                                                                                                                                                                  |
      | 描述     | 否    | 对应用的描述。示例：**无**                                                                                                                                                                              |
      | 执行主机   | 否   | 资源池是部署软件包时执行部署命令的物理环境的集合，用户可以使用华为云托管的**默认资源池** ，也可以将自有的服务器作为**自定义资源池** 托管到华为云，托管方式请参考[自定义资源池场景](https://support.huaweicloud.com/usermanual-deployman/deployman_hlp_1082.html)。示例：**默认资源池** |
      | 来自流水线 | 否      | 开启后，只能通过流水线驱动执行，不能单独执行。                                                                                                                                                                      |
         
      
   
   4. 完成应用基本信息的编辑后，单击**"下一步"** ，进入选择部署模板页面，选择**"空白模板"** ，单击**"确定"**。
   
   
   
   
2. 编辑应用。 
   在**"部署步骤"** 页签中添加**"Kubernetes Nginx-Ingress灰度发布(CCE集群)"** 步骤并修改为如下参数：
   表1参数说明 
   | 参数项       | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | 示例                                                                                                                                                                                                                       |
   |:---|:---|:---|
   | 步骤显示名称    | 步骤添加后在部署步骤编排区显示的名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | 默认                                                                                                                                                                                                                       |
   | 部署租户       | - **当前租户：** 表示将软件包部署到当前租户的CCE集群中发布。 选择"**当前租户**"，当前租户需要有CCE集群操作权限，如果没有CCE集群操作权限，可以通过下方的IAM授权选择已有权限的授权用户进行部署。   - **其他租户：** 表示通过IAM授权方式将软件包部署到其他租户的CCE集群中发布。 选择"**其他租户**"，则必须选择授权租户进行CCE集群部署。                                                                                                                                                                                                                 | 当前租户                                                                                                                                                                                                                        |
   | IAM授权   | 如果当前用户无操作权限执行接口时，可通过IAM提权获取到其他用户的临时AK/SK去执行CCE接口。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | 不勾选                                                                                                                                                                                                                      |
   | 区域      | 选择要部署的区域。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | 默认                                                                                                                                                                                                                       |
   | 集群名称    | 选择CCE云容器引擎中申请的K8S集群。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | cce-ldf                                                                                                                                                                                                                 |
   | 命名空间名称 | 选择CCE云容器引擎中K8S集群的命名空间。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | default                                                                                                                                                                                                                  |
   | 工作负载名称  | 选择需要部署的无状态工作负载。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | deployment-doc                                                                                                                                                                                                           |
   | 访问方式名称  | 选择与目标工作负载所绑定的service服务名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | service-doc                                                                                                                                                                                                             |
   | 路由名称     | 选择与目标service服务所绑定的路由名称。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | ingress-doc                                                                                                                                                                                                              |
   | 容器名称   | 选择需要部署的容器实例名。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | container-1                                                                                                                                                                                                               |
   | 镜像名称   | 选择需要部署的镜像。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 默认                                                                                                                                                                                                                       |
   | 镜像版本     | 选择需要部署的镜像版本。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | v2                                                                                                                                                                                                                        |
   | 开启灰度配置   | **灰度策略** ： - **Header** Header-Key：持输入自定义Header的键。 Header-Value：支持输入自定义Header的值，支持字符串及正则表达式，正则表达式格式为：\^....$。 灰度流量权重（%）：支持流量自定义配置。   - **Cookie** Cookie：支持输入自定义Cookie内容。 灰度流量权重（%）：支持流量自定义配置。    长度限制：**Header** 与**Cookie**所输入的字符串长度最大为500。 | 勾选 灰度策略：Header Header-Key：foo Header-Value：bar 灰度流量权重（%）：30 |
      
   
   
3. 部署应用（创建灰度版本）。 
   单击**"保存并部署"**，部署该应用。此时，部署服务已为您在CCE集群中创建了以下灰度版本资源并将30%的现网流量引向灰度负载：
   - 工作负载：deployment-doc-v2，镜像为V2版本
     图3增加镜像版本为V2的工作负载   
     ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001948499165.png "点击放大") 
   
   - 服务：service-doc-v2
   
   - 路由：ingress-doc-v2
   
   
   此时，测试人员可以在Header中添加一条数据（Key取值为foo，Value取值为bar）到灰度负载中验证最新版本。
   
   
4. 编辑应用（部署最新版本）。 
   进入[步骤1]中创建的应用，修改以下参数：
   表2参数说明 
   | 参数项    | 是否必填 | 示例 |
   |:---|:---|:---|
   | 开启灰度配置 | 否    | 不勾选 |
      
   
   
5. 部署应用（部署最新版本）。 
   单击**"保存并部署"**，部署该应用。此时，部署服务已为您在CCE集群中删除了以下灰度环境资源并将V1版本镜像替换为V2版本镜像：
   - 工作负载：deployment-doc-v2
   
   - 服务：service-doc-v2
   
   - 路由：ingress-doc-v2
   
   
   图4镜像版本升级为V2   
   ![](https://support.huaweicloud.com/bestpractice-deployman/zh-cn_image_0000001948499173.png "点击放大")
   此时，用户可以到现网查看系统是否为升级后的最新版本。更多部署问题，请参考[应用部署常见问题](https://support.huaweicloud.com/deployman_faq/deployman_faq_00002.html)排查。
   
   
 
