
# CCI 2.0应用进行优雅滚动升级
#### 应用场景
用户在云容器实例 CCI 2.0中部署工作负载时，应用发布为LoadBalancer类型的Service且对接的独享型ELB，经过ELB的访问流量支持直通到容器中，应用进行滚动升级或者弹性扩缩容时，可以配置容器探针、最短就绪时间等实现优雅升级和优雅弹性扩缩容，避免升级或扩缩容过程中出现5xx的错误响应。
表1应用场景 
| 场景           | 措施                |
|:---|:---|
| Deployment升级 | 滚动升级+存活/就绪探针+优雅终止 |
| Deployment缩容 | 存活/就绪探针+优雅终止      |
   
- 滚动升级 Deployment可以采用滚动升级的升级方式，会对各个实例逐步进行更新，并非同时对所有实例进行全部更新，可以控制Pod的更新速度和并发数，从而确保了升级过程中业务不中断。例如，可以设置maxSurge和maxUnavailable参数，控制同时创建的新Pod数量和同时删除的旧Pod数量。确保升级过程中始终有工作负载能够提供服务。
  示例：配置最大浪涌（maxSurge）为25%，最大无效实例数（maxUnavailable）为25%，假设Deployment的副本数为2，那实际升级过程中，maxSurge允许最多3个Pod存在（向上取整，2\*1.25=2.5，取整为3），而maxUnavailable则不允许有Pod Unavailable（向下取整，2\*0.25=0.5，取整为0），也就是说在升级过程中，不允许有Pod处于非运行状态，每次新建一个Pod，待新的Pod创建成功后再删掉一个旧的Pod，直至Pod全部为新Pod。
  

- 设置存活/就绪探针 存活探针可以用来确定什么时候需要重启容器，如果容器的存活检查的结果为失败，云容器实例会对该容器执行重启操作，有利于提高应用的可用性。
  就绪探针可以知道容器何时准备好接口请求流量，若Pod尚未就绪，将会被从负载均衡器后端服务器组中剔除。
  
- 优雅终止 负载升级或缩容过程中，负载均衡器会将正在终止的pod从后端服务器组中移除，但会保持还在处理的请求的连接。如果后端服务Pod在收到结束信号后立即退出，可能会导致正在处理的请求失败或部分流量仍被转发到已经退出的Pod中，导致流量损失和服务中断。为了避免这种情况，建议在后端服务的Pod中配置优雅删除时间（terminationGracePeriodSeconds）和preStop Hook。
  优雅删除时间（terminationGracePeriodSeconds）：默认为30秒，删除Pod时发送SIGTERM终止信号，然后等待容器中的应用程序终止执行。如果在terminationGracePeriodSeconds时间内未能终止，则发送SIGKILL的系统信号强行终止。
  如果用户的业务代码中没有处理SIGTERM信号，也可以尝试为Pod配置preStop Hook，在Pod被移除后继续工作一段时间，以解决流量中断的问题。
  建议用户在业务代码中对SIGTERM信号进行处理，实现优雅终止，同时也可以利用preStop先sleep一会，等待 kube-proxy 完成规则同步再开始停止容器内进程。用户可根据实际情况自定义优雅删除时间（preStop + 业务进程停止可能超过30s），避免过早被SIGKILL信号强行终止。
  
 
#### 操作步骤
以部署nginx无状态工作负载为例，在云容器实例 CCI 2.0中进行优雅滚动升级或者弹性扩缩容。
1. 在云容器实例 CCI2.0控制台，单击左侧导航栏中的"负载管理 \> 无状态负载"，单击左上角"YAML创建"。 
   ![](https://support.huaweicloud.com/bestpractice-cci2/zh-cn_image_0000002211495756.png "点击放大")
   
   
   
2. 参考以下yaml示例创建负载： 
   ```
   kind: Deployment
   apiVersion: cci/v2
   metadata:
     name: nginx
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: nginx
     template:
       metadata:
         labels:
           app: nginx
       spec:
         containers:
           - name: nginx
             image: nginx:latest
             ports:
             - containerPort: 80
             resources:
               limits:
                 cpu: 500m
                 memory: 1Gi
               requests:
                 cpu: 500m
                 memory: 1Gi
             livenessProbe:            # 存活探针
               httpGet:                # 以HTTP请求检查为例
                 path: /               # HTTP检查路径为/
                 port: 80              # 检查端口为80
               initialDelaySeconds: 5
               periodSeconds: 5
             readinessProbe:           # 就绪探针，该配置是检查用户业务是否就绪，不就绪则不转发流量到当前实例。
               httpGet:
                 path: /
                 port: 80
               initialDelaySeconds: 5
               periodSeconds: 5
             lifecycle:
               preStop:               # 停止前处理，该配置是保证业务容器在退出过程中能够对外提供服务。
                 exec:
                   command:
                   - /bin/bash
                   - '-c'
                   - sleep 30
         dnsPolicy: Default
         imagePullSecrets:
           - name: imagepull-secret
     strategy:
       type: RollingUpdate
       rollingUpdate:
         maxUnavailable: 0           # 滚动升级期间最多容忍的不可用的pod数量
         maxSurge: 100%              # 滚动升级期间可冗余的pod比例
     minReadySeconds: 10             # 最小就绪时间，用于指定新创建的Pod在没有任意容器崩溃情况下的最小就绪时间，只有超出这个时间Pod才被视为可用。
   ```
   ![](https://support.huaweicloud.com/bestpractice-cci2/public_sys-resources/note_3.0-zh-cn.png)
   - 推荐的配置minReadySeconds时长，为业务容器的启动预期时间加上ELB服务下发member到生效的时间。
   
   - minReadySeconds的时长需要小于sleep时长，保证旧的容器停止并退出之前，新的容器已经准备就绪。
    
   
   
3. 配置完成后，对应用进行升级和弹性扩缩容的测试。 
   准备一台集群外的客户端节点，预置检测脚本**detection_script.sh**，内容如下，其中100.85.125.90:80为service的公网访问地址：
   ```
   #! /bin/bash 
   for (( ; ; ))
   do
            curl -I 100.85.125.90:80 | grep "200 OK"
            if [ $? -ne 0 ]; then
                     echo "response error!"
                     exit 1
            fi 
   done
   ```
   
   
4. 运行检测脚本：**bash detection_script.sh** ，并在云容器实例 CCI2.0控制台，单击左侧导航栏中的"负载管理 \> 无状态负载"，选择相关工作负载，单击"YAML编辑"，来触发应用的滚动升级。
   
   ![](https://support.huaweicloud.com/bestpractice-cci2/zh-cn_image_0000002220391849.png "点击放大")
   
   滚动升级的过程中，应用的访问并未中断，并且返回的请求都是"200 OK"，说明升级过程是优雅升级，无中断。
   ![](https://support.huaweicloud.com/bestpractice-cci2/zh-cn_image_0000002220392321.png "点击放大")
   
   
   
 
