EMQX 在 Kubernetes 中如何进行优雅升级
背景
为了降低 EMQX 在 Kubernetes 上的部署、运维成本,我们将一些日常运维能力进行总结、抽象并整合到代码中,以 EMQX Kubernetes Operator 的方式帮助用户实现 EMQX 的自动化部署和运维。
此前,EMQX Kubernetes Operator v1beta1、v1beta2、v1beta3 的升级策略均为滚动升级,相关升级流程如下:
问题分析
滚动升级在生产环境中可能会面临以下问题:
- 升级过程中会逐个销毁旧的节点再创建新的节点,因此可能导致客户端多次断连(最糟糕的情况下断连次数与节点数量一致),从而影响用户体验。
- 当集群处于较高连接的情况下,一个节点被销毁,那么该节点上面的连接会在瞬间断开,由客户端重试逻辑来进行重连;当单节点连接数较大时,如果大量客户端进行重连,则可能会给服务端造成压力导致过载。
- 升级完成后,各节点间的负载不均衡(如上图:emqx-ee-0 在升级过程中,客户端可能会进行重连,此时由于 emqx-ee-0 还未就绪,因此可能连接到 emqx-ee-1 或者 emqx-ee-2,升级完成后 emqx-ee-0 上可能只有较少负载或者无负载),从而打破业务容量模型的规划,可能影响到服务。
- 由于使用 StatefulSets 进行部署,在升级过程中提供服务的节点会比实际节点要少一个(影响到用户的业务模型),这可能会增加服务端的一些压力。
如果上面几个步骤的问题叠加(多次断连与大量断连的客户端不停的重试连接),则可能会放大客户端重连的规模,从而造成服务端过载或雪崩。
下图是在现有升级模式下连接数的监控图(在不同的业务中会存在差异,比如后端依赖的不同资源、服务器配置、客户端重连或重试策略等,均会带来一些不同的影响)。其中:
- sum:总的连接数,图中最上面的一条线
- emqx-ee-a:前缀表示的是升级前 3 个 EMQX 节点
- emqx-ee-b:前缀表示的是升级后 3 个 EMQX 节点
在上图中,当我们开始执行滚动升级时,首先 emqx-ee-a-emqx-ee-2 进行销毁,并创建新的 emqx-ee-b-emqx-ee-2,此时仅有 emqx-ee-a-emqx-ee-1、emqx-ee-a-emqx-ee-0 能够提供服务,当客户端进行重连时,LB 会将流量转移到 emqx-ee-a-emqx-ee-0、emqx-ee-a-emqx-ee-1 上面,因此我们能够看到 emqx-ee-a-emqx-ee-1、emqx-ee-a-emqx-ee-0 有明显的流量上升,当后面更新这两个 pod 时,意味着客户端可能多次断连。由于新 pod 建立的过程存在着时间差,以上图为例,emqx-ee-a-emqx-ee-0 最后升级,当升级完成后,可能客户端已经完成重试、重连,此时主要连接已经被另两个 pod 接纳,因此会导致 pod 之间流量不均衡,从而影响到用户业务模型的评估,或者影响到服务。
为了方便展示,我们未压测大量连接模拟重连、导致服务端过载的场景(在实际生产环境中可能遇到,TPS 超过云端规划的容量模型),但从连接数监控图上,我们依然看到一个大缺口,说明对业务产生了较大影响。因此我们需制定一种方案来规避以上几个问题,保障升级过程中的平滑稳定。
问题解决
目标
- 升级过程中实现连接数可控迁移(可根据服务端处理能力设置相应的迁移速率)。
- 升级过程中减少连接断开的次数(一次断连)。
- 在整个升级的过程中始终保持预期的节点来提供服务。
- 升级完成后,不需要集群负载重平衡,各节点间的连接相对均衡(与 LB 调度策略有一定关系)。
方案设计
蓝绿发布是一种同时运行两个版本应用的发布策略。EMQX Kubernetes Operator 近日在 2.1.0 版本中实现了 EMQX Enterprise 的蓝绿发布,即从现有的 EMQX Enterprise 集群开始,创建一套新版本的 EMQX Enterprise 集群,在这一过程中不停止掉老版本,等新版本集群运行起来后,再将流量逐步平滑切换到新版本上。
从 4.4.12 版本开始,EMQX 企业版本支持节点疏散功能。节点疏散功能允许用户在关闭节点之前强制将连接和会话以一定速率迁移到其他节点,以避免节点关闭带来的会话数据丢失。
关于节点疏散更多信息请参考相关文档
在 Kubernetes 上我们通过模拟蓝绿发布以及结合节点疏散功能,实现了连接可控迁移,极大减少了断连的次数(仅断连一次)。相关升级流程图如下:
整个升级流程大致可分为以下几步:
- 升级时(镜像、Pod 相关资源修改调整)我们会先创建一个同规格的节点加入到现有集群中。
- 当新节点全部就绪后,我们将 service 全部指向新创建的节点,此时新节点开始接受新的连接请求。
- 将旧节点从 service 中摘出,此时旧节点不再接收新的连接请求。
- 通过 EMQX 节点疏散功能,逐个对节点上的连接进行可控迁移,直至连接全部完成迁移,再对节点进行销毁。
操作流程
节点疏散是 EMQX Enterprise 4.4.12 开始支持的新特性,EMQX Kubernetes Operator 在 2.1 版本中对该能力进行适配,如需使用该能力,请将 EMQX 升级到企业版 v4.4.12,EMQX Kubernetes Operator 升级到 v2.1。
- 配置蓝绿升级
apiVersion: apps.emqx.io/v1beta4
...
spec:
blueGreenUpdate:
initialDelaySeconds: 60
evacuationStrategy:
waitTakeover: 5
connEvictRate: 200
sessEvictRate: 200
...
initialDelaySeconds
:所有的节点就绪后(蓝绿节点),开始节点疏散前的等待时间 (由于切换 Service 后,LoadBalancer 需要时间来处理 service 与 pod 的关系)(单位:秒)
waitTakeover
:所有连接断开后,等待客户端重连以接管会话的时间(单位:秒)
connEvictRate
:客户端每秒断开连接速度
sessEvictRate
:waitTakeover
之后每秒会话疏散速度
详情可参考:Operator 文档
升级过程中连接数监控图如下(本次测试以 10 万连接进行):
sum:总的连接数,图中最上面的一条线
emqx-ee-86d7758868:前缀表示的是升级前的 3 个 EMQX 节点
emqx-ee-745858464d:前缀表示升级后的 3 个 EMQX 节点
如上图,我们通过 EMQX Kubernetes Operator 的蓝绿发布在 Kubernetes 中实现了优雅升级,通过该方案升级,总连接数未出现较大抖动(取决于迁移速率、服务端能够接收的速率、客户端重连策略等),能够极大程度保障升级过程的平滑,有效防止服务端过载,减少业务感知,从而提升服务的稳定性。
注:由于升级后的集群,三个节点负载较平均,因此上图三条线重叠在了一起。
结语
通过采用节点疏散功能结合模拟蓝绿发布,本文所提供的方案解决了普通升级导致的多次断连和可能的服务过载与负载不均问题,实现了在 Kubernetes 上优雅的升级。
作为一个自动化管理工具,EMQX Kubernetes Operator 旨在帮助用户轻松创建和管理 EMQX 集群,充分享受 EMQX 的强大产品能力。通过本文方案完成 EMQX 的升级,用户可以进一步体验 EMQX 的最新特性,构建创新物联网应用。
版权声明: 本文为 EMQ 原创,转载请注明出处。
原文链接:https://www.emqx.com/zh/blog/how-to-upgrade-emqx-in-kubernetes
EMQX 在 Kubernetes 中如何进行优雅升级的更多相关文章
- 如何将云原生工作负载映射到 Kubernetes 中的控制器
作者:Janakiram MSV 译者:殷龙飞 原文地址:https://thenewstack.io/how-to-map-cloud-native-workloads-to-kubernetes- ...
- Kubernetes 中的核心组件与基本对象概述
Kubernetes 是 Google 基于 Borg 开源的容器编排调度,用于管理容器集群自动化部署.扩容以及运维的开源平台.作为云原生计算基金会 CNCF(Cloud Native Computi ...
- StatefulSet: Kubernetes 中对有状态应用的运行和伸缩
在最新发布的 Kubernetes 1.5 我们将过去的 PetSet 功能升级到了 Beta 版本,并重新命名为StatefulSet.除了依照社区民意改了名字之外,这一 API 对象并没有太大变化 ...
- [转帖]Kubernetes中安装Helm及使用
Kubernetes中安装Helm及使用 2018年07月02日 17:41:09 灬勿忘丶心安 阅读数 3699更多 分类专栏: K8S 版权声明:本文为博主原创文章,遵循CC 4.0 BY-S ...
- Helm, 在Kubernetes中部署应用的利器
一.背景 Kubernetes(k8s)是一个基于容器技术的分布式架构领先方案.它在Docker技术的基础上,为容器化的应用提供部署运行.资源调度.服务发现和动态伸缩等一系列完整功能,提高了大规模容器 ...
- Kubernetes中Service的使用
目录 简介 1. Service资源定义 1.1 Service Type ClusterIP 无头service NodePort sessionAffinity实现源地址session绑定 简介 ...
- Kubernetes中予许及限制(PodSecurityPolicy)使用宿主机资源
1.在pod中使用宿主机命名空间.端口等资源 pod中的容器通常在分开的Linux命名空间中运行.这些命名空间将容器中的进程与其他容器中,或者宿主机默认命名空间中的进程隔离开来. 例如,每一个pod有 ...
- 如何发现 Kubernetes 中服务和工作负载的异常
大家好,我是来自阿里云的李煌东,今天由我为大家分享 Kubernetes 监控公开课的第二节内容:如何发现 Kubernetes 中服务和工作负载的异常. 本次分享由三个部分组成: 一.Kuberne ...
- Kubernetes 中部署 NFS-Subdir-External-Provisioner 为 NFS 提供动态分配卷
文章转载自:http://www.mydlq.club/article/109/ 系统环境: 操作系统: CentOS 7.9 Docker 版本: 19.03.13 Kubernetes 版本: 1 ...
- 在C#中实现软件自动升级
在C#中实现软件自动升级 winform程序相对web程序而言,功能更强大,编程更方便,但软件更新却相当麻烦,要到客户端一台一台地升级,本文结合实际情况,通过软件实现自动升级,弥补了这一缺陷,有较好的 ...
随机推荐
- JZOJ 3889
\(\text{Problem}\) 小H是个善于思考的学生,她正在思考一个有关序列的问题. 她的面前浮现出了一个长度为 \(n\) 的序列 \({ai}\),她想找出两个非空的集合 \(S.T\). ...
- 关于php imagettftext 函数错误解决问题
imagettftext 这个函数是给图片添加水印的,但是不知道为什么我用不起,直到在网上找到了答案: 是因为字体文件路径原因,相对路径可能我位置不对,该成绝对路径就没问题了! 把'Facon-2.t ...
- Commons-Collections反序列化
Java反序列化漏洞 Commons Collections Apache Commons 是 Apache 软件基金会的项目.Commons Collections 包为 Java 标准的 Coll ...
- element-ui中rules使用正则验证、表单验证
<template> <el-form :model="DataForm" label-position="top" :rules=" ...
- 【Java-01-1】java基础-基本语法(1)(基本输入输出,计算)
1.基本输出语句 /* * java * 多行注释 */ //java单行注释 public class _01_HelloWorld { public static void main(String ...
- 解决用flex布局时内容溢出的问题
1,2正常现象如下: 2,点击折叠图标 再点折叠 无图标了 解决:flex:1,width:0 就可以了
- 不可忽略的.gitignore_global
会不会很奇怪,本地的代码运行没有问题,以为自己提交到远程仓库了 但是别人下载下来却没有,有没有可能是你根本没提交上去,对了,你真的有可能没提交上去 你本地这个文件是灰色的,确实没有提交上去,但是项目中 ...
- linux 端口的相关命令
查看某个端口是否开发 isof -i:端口 说明:如果有显示说明已经开放了,如果没有显示说明没有开放 开放端口之后,查看防火墙是否对端口开放 查询端口号80 是否开启: firewall-cmd -- ...
- 解决React 安装 antd 后出现的Module not found: Can't resolve './locale' in '...rc-picker/node-modules.....'一系列问题问题
最近看到很多小伙伴发现了antd的这个问题,试用了网上的办法不行,我自己想了一种可行的方法,大家可以试一试. 有位大佬用了yarn eject 方式 ,通过暴露config配置,在config.web ...
- 52道常见Python面试题,你都看过了吗?(转发供参考学习)
https://blog.csdn.net/xiaohei3ge/article/details/88080284?utm_medium=distribute.pc_relevant.none-tas ...