随着京东云业务规模、管理机器规模的扩大,各类agent也在逐渐增多,如日志agent、监控agent、控制系统agent等。这对agent的部署、升级、状态维护提出了很高的要求,一旦某个全局agent进行了错误地部署、升级,可能会导致agent的资源使用率过高,进而会对全公司的业务产生影响。在此背景下需要有一个统一管理系统来对全网agent的部署、升级进行管控,可以灵活的指定不同的发布策略进行灰度更新,如按照pin层面升级、按照集群层面等等。基于此,京东云自研了ifrit系统用于全网agent的部署、升级和状态维护。
总体架构
ifrit是阿拉伯神话中一种遇火而生,浴火重生的精灵,只有英雄才有驾驭它的能力。这里的“火”可以指代全网每一个节点,“英雄”则可以指代管理员。此外,阿拉丁神话中的“灯神”就是一种ifrit,灯神可以帮阿拉丁实现愿望,京东云ifrit系统也可以帮助我们管理节点。
ifrit 架构自上而下分为ifrit-manage、ifrit-master、ifrit-agent三大模块,如下图所示:
ifrit-agent:负责本机所需业务agent以及ifrit-agent本身的部署、升级、状态维护,定期从ifrit-master中拉取本机agent配置用以管理本机所有agent。配置完成后向ifrit-master汇报本机的agent状态信息。
ifrit-master:每个集群内部署一套master,向上提供ifrit-manage发布部署、更新指令和agent状态查询接口;向下为本集群内所有ifrit-agent提供agent配置信息查询和agent状态回传接口。
ifrit-manage:向用户提供web界面,在该页面可以对指定agent进行灰度更新和全量更新、查看操作记录等。
ifrit-agent
ifrit-agent设计目标:
• 定期获取agent配置信息并向master汇报agent状态信息
• 程序包下载、校验
• 安装
• 卸载
• 升级
• 安装包完整性检测
• 实例存活检测
• 自升级
• 自守护
由于几乎所有部署、监控等相关功能都依赖于agent,ifrit-agent在机器中以服务形式存在并且开机自启动。若ifrit-agent启动时网络服务未启动。则会导致机器在数分钟内无法使用部署、监控、日志服务等功能,同时也无法采集到docker容器类应用的初始化日志,因此ifrit-agent启动时配备重试机制,以确保网络服务已经启动。
ifrit-agent在访问master接口获取期望agent状态信息时,需要带上机器类型和机器uuid(例如内网中的ip、云主机上的instance-id等)。其中机器类型(主要是操作系统、cpu架构)可通过初始化时执行命令获取,或使用golang中的条件编译将机器类型直接写在程序中。
iFrit-master
ifrit-master负责agent管理工作,全网部署agent的增删查改都是通过ifirt-manage调用ifrit-master接口完成的。当集群规模增大时,直接读取mysql获取agent版本信息会对数据库造成很大压力,为了避免这类问题,ifrit-master中采用redis缓存,以固定时间间隔读取mysql中agent版本信息,并合成为ifrit-agent可直接读取的数据缓存到redis,如下图所示:
为了减少因agent升级导致的全网业务故障,ifrit-master提供了灰度发布机制,即指定一批机器更新agent到指定版本灰度运行。待灰度验证通过后,在集群内全量部署该agent。同时,ifrit系统可以根据不同机器类型部署不同的业务agent,目前京东云内支持了容器、linux物理机、arm64架构机器和windows系统机器。
iFrit-manage
ifrit-manage统一管理多个集群的master,主要功能如下:
• 用户权限管理
• 分级发布(集群粒度)
• agent状态查询
• 操作审计
ifrit-manage本身作为运营后台的一部分,可读权限由运营后台统一管理。ifrit写操作是高危操作,默认只有超级管理员(一般为公司运维人员)有写权限,其他人员可以通过在配置文件中添加写权限。
根据业务需要,可以将机器划分到不同集群中,当有agent需要变更时,运维人员在灰度验证通过后,按照给定的集群顺序分集群进行部署。运维完成一个集群的agent部署后,15分钟内(ifrit-agent主循环周期+ifrit-master redis缓存周期)该集群内所有指定类型机器应当变更生效,运维验证部署生效后方可对下一个集群进行部署。
单集群分级发布
以上的ifrit系统已经具备了集群粒度的分级发布功能,但是随着集群规模越来越大,集群粒度的agent上线仍然有很大风险,因此需要一套更细粒度的分级发布机制,以便于降低agent上线事故带来的影响。
ifrit中根据集群规模大小,使用一致性hash算法将集群中的机器均匀分成若干批,并分批上线。一致性hash算法是hash算法的改进,和普通hash算法的关键区别是,对于节点和数据(ifrit中使用机器uuid)都做一次hash运算,并比较节点和数据的hash值,顺时针方向取距离数据点的节点。若hash后的节点分布不均匀,可通过引入虚拟节点增大节点数目,从而使得散落在hash环上的节点更加均匀,如下图。
集群分批完成后,集群内进行agent全量上线时首先进行小流量验证,验证通过后按照一定时间间隔更新redis缓存信息,新增键值expect_default_hash1_CONTAINER等。此时ifrit-agent获取agent版本信息的优先级为:灰度数据>hash数据>全量数据(时间戳相同的情况)。还可以通过暂停更新/删除redis中hash类型的数据,实现agent上线的暂停与回滚(操作mysql数据间接实现)。
自此,ifrit实现了单集群内的agent上线分级发布。
看完本文后,您是否有所收获呢,如果您想了解更多关于京东云翼的讯息,欢迎点击“阅读”了解更多~
也欢迎点击“京东云”了解更多精彩内容