升级实例过程中实现业务不中断
应用场景
在Kubernetes集群中,应用通常采用Deployment + LoadBalancer类型Service的方式对外提供访问。应用更新或升级时,Deployment会创建新的Pod并逐步替换旧的Pod,这个过程中可能会导致服务中断。
解决方案
避免服务中断可以从Deployment和Service两类资源入手:
- Deployment可以采用滚动升级的升级方式,为对各个实例逐个进行更新,而不是同时对所有实例进行全部更新,可以控制Pod的更新速度和并发数,从而确保了升级过程中业务不中断。例如,可以设置maxSurge和maxUnavailable参数,控制同时创建的新Pod数量和同时删除的旧Pod数量。确保升级过程中始终有工作负载能够提供服务。
- LoadBalancer类型的Service存在两种服务亲和模式:
- 集群级别的服务亲和(externalTrafficPolicy: Cluster):Cluster模式下,如果当前节点没有业务Pod,会将请求转发给其他节点上的Pod,在跨节点转发会丢失源IP。
- 节点级别的服务亲和(externalTrafficPolicy: Local):Local模式下,请求会直接转发给Pod所在的节点,不存在跨节点转发,因此可以保留源IP。但是在Local模式下,如果实例滚动升级时Pod所在节点发生变化,导致ELB侧后端服务器会同步变化,可能会出现服务中断。这种情况下可以通过实例原地升级的方式避免服务中断,即保证ELB后端的节点上存在一个正常状态的Pod。
综上,实现升级实例过程中的业务不中断的方案可参考下表:
场景 |
Service |
Deployment |
---|---|---|
不需要保留源IP |
选用集群级别的服务亲和模式 |
滚动升级 + 优雅终止 + 存活/就绪探针 |
需要保留源IP |
选用节点级别的服务亲和模式 |
滚动升级 + 优雅终止 + 存活/就绪探针 + 节点亲和(保证更新过程中每个节点上至少有一个Running Pod) |
操作步骤
本示例中,工作负载副本个数为200,并通过LoadBalance类型Service对外暴露服务。关联有Loadbalance类型Service/Ingress的工作负载滚动升级由于涉及跨服务调用,因此需要格外注意滚动升级参数的配置。
- 登录CCE控制台,单击集群名称进入集群,在左侧选择“工作负载”。
- 在工作负载列表中,单击待升级的工作负载操作列的“升级”,进入升级工作负载页面。
- 设置存活/就绪探针:在容器配置中选择“健康检查”,开启存活探针和就绪探针。示例中均为TCP端口检查,请根据应用实际情况进行设置。检测周期、延时时间、超时时间等数据需要合理设置,部分应用启动时间较长,如果设置的时间过短,会导致Pod反复重启。
本示例中配置就绪探针延迟探测时间为20s,用于控制工作负载批量滚动的时间间隔。
图1 存活/就绪探针
- 设置滚动升级:在高级配置中选择“升级策略”,升级方式设置为“滚动升级”,逐步用新版本实例替换旧版本实例。
本示例中配置最大无效实例数(maxUnavailable)为2%,最大浪涌(maxSurge)为2%,用于控制工作负载的滚动步长。配合就绪探针的延迟探测,控制每20s时间内,升级8个工作负载。
图2 滚动升级
- 设置优雅终止:
- 在容器配置中选择“生命周期”,设置停止前处理,建议设置为业务处理完所有剩余请求所需的时间,其中多为长连接请求。例如,您可以设置工作负载收到删除请求后休眠30s,能够有充足的时间来处理剩余的请求,保证服务的正常运行。
- 在高级配置中选择“升级策略”,设置缩容时间窗,即terminationGracePeriodSeconds参数,指定容器停止前命令执行的等待时间。缩容时间窗时间设置需大于“生命周期”的停止前处理时间,建议在容器停止前命令执行时间的基础上加30s。例如,停止前处理时间设置为30s,因此缩容时间窗设置为60s。
图3 停止前命令
- 设置节点亲和:Service为节点级别的服务亲和模式时建议设置。在高级配置中选择“调度策略”,设置节点亲和性,在添加调度策略时,指定工作负载需要亲和的节点。
图4 节点亲和性
- 设置存活/就绪探针:在容器配置中选择“健康检查”,开启存活探针和就绪探针。示例中均为TCP端口检查,请根据应用实际情况进行设置。检测周期、延时时间、超时时间等数据需要合理设置,部分应用启动时间较长,如果设置的时间过短,会导致Pod反复重启。
- 设置完成后单击“升级工作负载”。
在“实例列表”页签下,可查看到会先创建新实例,然后再停止旧实例,始终保证有实例正在运行。