一、问题背景 大部分的应用运维工作随着服务器数量和产品数量的增长而增加,而运维人数的不足导致单个运维人员所承担的工作任务较为繁重,同时运维工作的不标准、无自动化使得应用运维任务十分复杂,耗费的大量的人员成本、时间成本和沟通成本。 应用运维工作说白了大体可以分为两种情况: 1. 在某个或某些服务器上执行某个脚本或命令; 2. 将某个或某些文件传输到某个或某些特定的服务器的特定位置上。在服务器数量较少的情况下,可以通过ssh或scp命令实现上面两个操作;服务器数量较多的情况下,我们可以通过包装ssh或者使用批量ssh工具,如pssh,ansible等来解决问题,但这种方式大多数都是一次性的方式,无论使用方法以及后续跟踪来看都并不友好。 还有,由于一系列历史原因,现网的服务环境也较为繁杂,现网的服务器上的代码、配置、软件包、脚本等文件没有进行统一的版本管理与配置管理,比如某个产品的代码版本多种多样;现网的代码和文件几乎都是通过一台复制到另一台的方式来实现;由于代码版本、配置版本等问题导致的现网质量事件也并不在少数。 另外,应用运维也需要一个统一的资源管理系统,对现网的服务的数据进行业务维度的资源管理,系统运维的CMDB系统只在静态资源维度进行了管控,动态的业务数据等资源需要应用运维团队自行来管理。 因此,针对上面所述的各种问题,需要一个运维管控系统,来解决包括:资源管理、配置管理、任务管理、文件发布等一些列常用的运维跟踪,通过简单高效、自动化的方式将繁琐的应用运维工作通过管控系统来完成,即可以降低运维的难度,也可以提高运维的效率,同时可以提高运维操作的成功率,并实现运维任务的持续跟踪和管理,甚至在不远的将来可以实现移动运维。 二、功能结构 经过上述的分析和整理,我们将整个管控平台的功能细化到如下几个大功能,如图所示: 三、详细设计 这里围绕上面功能结构图中的4个大功能,进行详细的分析和设计,其中移动运维功能为附加功能,这里暂时不介绍。 1. 资源管理 先说资源管理,资源管理是一切后续自动化运维功能的前提,也是所有自动化功能的数据依赖。 资源管理的功能可以较为薄弱,但是对数据的要求比较高,可以基于系统运维的CMDB系统进行二次构建,主要的功能可以分为:
虚拟资源数据在进行后续的虚拟资源管理、虚拟资源迁移等功能上会有较大帮助,可以基于虚拟资源管理完成自动化的实例迁移工作,节省大量的手动实例迁移任务。另外虚拟资源管理对宕机恢复或机房、机架断电等问题也会有较大的帮助。 整个资源管理比较简单,可以优先完成物理机资源管理功能,再实现虚拟资源管理功能。 2. 作业管理 作业管理是应用运维管控系统的核心功能,也是应用运维工作中最经常使用到的功能,作业管理功能也可以分为如下子功能,如图所示: 下面将分别对上面几个子功能进行详细介绍: (1) 脚本执行: 脚本执行和文件分发是整个作业功能的基础功能,其他的功能都是通过对着两个功能进行组装和装饰来实现的。 脚本执行的表现形式就是运维人员在页面中提交一个脚本,脚本建议支持shell和python两种形式,可以通过三种方式:
脚本的编写要依赖一定的语法规范,我们可以为shell和python语言提供基础的类包和函数库,同时所有的脚本的执行结果都会根据脚本的exit的 $? 值来判断,$? 值为0,则表示该脚本执行成功,若为其他值则表示脚本执行失败。脚本的输出内容会存储到数据库中用于后续的问题跟踪和排查,因此需要运维人员写脚本的时候注意写上详细的日志内容。 脚本支持输入参数。用户可以在页面中的参数一栏输入执行参数,当然也可以直接写到脚本里。 支持选择执行账户。目前大部分服务的运行账户仍然是root用户,后续可能会改成非root用户,所以这里支持选择执行账户,具体的账户名称,可以在用户管理的功能中维护。 支持选择所执行的服务器。用户在选择好相应的脚本之后,需要指定在哪些服务器上执行该脚本,因此需要支持选择所需的服务器。这里面服务器选择分为两种模式:
总结一下,脚本执行功能比较基础,同时还包含三个子功能,这三个子功能放到配置管理里面去实现,后面会具体阐述:
说完具体的功能之后,我们需要确定具体的实现方式,准确的说,实现方式有两种: 1)SSH远程执行;可以通过封装ssh和paramiko的方式实现,python中的ansible和fabric包也都支持远程SSH执行的功能。Shell就用ssh命令即可。 该方式对中心节点要求比较高,每一个远程执行命令都会在中心节点启动一个进程(线程)来执行,对中心机的压力较大,同时由于是基于SSH的原理,故命令执行的效率较差,命令执行时间长。 2)Agent执行;在每台服务器上部署一个Agent,用户执行管控系统发送的脚本。这种方式的优点是可以采用拉的方式,由各个子节点订阅分给自己的任务,执行完成后再讲结果推给中心节点的数据;当然也可以像SSH方式通过推的方式由中心节点将任务发给远程的Agent,然后Agent去执行,并将结果反馈给中心节点。这种方式的执行效率会比较高,可扩展性强,将来甚至可以通过该Agent进行配置或运行数据上报,对于配置管理也比较方便,缺点是需要开发Agent,Agent需要支持异步非阻塞模式,且需要维护每台服务器的Agent,包括部署和管理。 Python的saltstack软件就是通过Agent的方式实现的,需要在每台物理机上部署一个saltstack minion进程用于接受任务和执行任务,在每个中心机上部署saltstack master进程用于下发任务,saltstack master通过将任务下发到zeromq中从而实现各个minion获取任务并执行,同时saltstack也支持将任务执行结果存储到Redis等数据库中,便于后续的跟踪和查看。 不过Agent也可以通过自行开发的方式实现,线上所有的Agent大多都是这种原理,也都是自己实现的,不过具有一定的开发难度。 因此对于脚本执行的实现方式来看总结如下:
(2) 文件分发 文件分发是除了脚本执行的另一个基础功能,该功能的技术描述就是将某台服务器上的某个或某些文件,传输到其他的某个或某些服务器的某个位置上。 文件分发功能分为以下两个子功能,相关文件和模板的管理工作放到配置管理中去实现,这里只介绍如何实现文件分发:
模板文件分发与普通文件分发不同的区别是模板文件中存储变量替换的逻辑,这里普通文件的管理和模板文件的管理以及配置变量的管理都放到配置管理系统中去实现,用户选择文件下发的时候可以选择是普通文件还是模板文件,如果是模板文件就会自动去加载配置管理中的变量管理生成临时的普通文件并下发。 具体的下发方式也分为两种: 1)管理机文件下发到普通的业务物理机上。 其实大部分的文件分发场景应该都是这一种,也就是我们将基础文件或模板文件放到管理机上,作为我们的基准文件,比如我们的部署代码,软件包等等,我们只要保证管理机上的文件版本的一致性,就可以保证普通的业务物理机上面的文件和管理机上的文件一致,也就是配置管理功能的中的文件版本一致性管理。 这种模式下的文件可能相对容量较小,比如小文件(几k),软件包(几M),或者稍大文件(几G),文件从管理机下发到某些业务物理机上面临的问题是并发导致的传输速度问题,小文件情况下还可以忽略,基本可以在秒级完成,但稍大文件的传输就会有时间问题,随着业务物理机的个数增加而增加,因此这种情况会有并发和流量的控制。 另外文件的传输会提前进行文件md5的对比判断,如果文件的md5值相同,那就没有再传输文件的必要,在稍大文件情况下可以节省较多的时间。 文件传输,可以使用ansible的copy模块,或者salt的文件file模块,当然也可以自研方式中封装rsync的方式,rsync支持文件md5值校验以及断点续传等方式。 2)物理机之间的文件互传。 物理机之间的文件互传准确的来说是反配置管理逻辑的,这种方式就和我们现在的文件传输方式很类似,也就是从一台服务器scp文件到另一台服务器上。对于配置文件和小文件、软件包等需要配置管理的文件来说,我们需要明确禁止使用这种方式。但这种方式的好处就是可以用来P2P的传输较大的文件,比如几百G的镜像文件。 对于几百G的镜像文件来说,如果使用第一种管理机管理的方式,只能1对多的传输将会造成传输时间的极大占用,而使用这种P2P的方式,即可以极大的提升文件传输的速度。 物理机之间的文件互传使用rsync即可,由于文件较大,且可能出现断点,rsync是比较方便的解决大文件传输的方法,需要在每台服务器上的Agent上对rsync功能进行封装,支持Agent之间的rsync文件互传。 物理机文件中需要管理的文件列表,可以通过Agent汇报到配置管理系统中,用户选择文件分发的时候,可以选择配置管理系统中的点对点大文件传输功能,配置管理系统中可以自动选择传输源,针对被传输物理机的个数,实现真正的点对点传输,不需要用户自己去选择源文件服务器,可以节省大量的人为运维操作。 (3) 批量执行: 所谓的批量执行功能就是上面两个基础功能中在选择目的服务器的个数的时候支持多个服务器,而不是只能选择单个服务器。 在使用SSH方式情况下并发的速度会较差,可能控制在单机30-50个任务同时进行。 在使用Agent的方式情况下,任务本身是异步下发的,可以实现同时1000+任务同时进行。 由于服务器数量较多,且分机房的模式,整个后端架构会是与目前的UCloud后端架构类似的分布式架构,一个中心任务下发节点,每个机房一个任务中转节点,每台服务器一个Agent(或者中转节点SSH的方式)。 (4) 定制任务: 所谓的定制任务,就是可以通过任务组装的方式,将脚本执行和文件分发这两个主要功能(可以根据需要添加其他的功能,比如重启后的服务器ping探测,端口探测等),将上面的这些功能,按照1、2、3、4、5的方式组装,具体的支持功能如下:
定制任务适用于某些使用频次较高的任务,比如服务器初始化上线,代码版本发布,软件包更新等操作。 (5) 定时任务: 定时任务是对普通的基础任务以及定制任务实现定时执行的功能,该功能的实现也相对简单,即按照crontab的分时日月周的语法,支持周期性或者定时性,也可以按照手机创建闹铃的方式选择触发时间和触发频率。 具体的实现方式如下:
(6) 灰度计划: 对于非周期性重复执行的任务,都可以加入灰度计划功能,该功能又结合定时任务实现。 灰度计划可以有两个维度体现:
上面这些是作业管理系统的主要功能,当然想要实现整个作业管理系统还会有一些其他的子功能,比如:
3. 配置管理 配置管理功能是整个管控功能中十分重要的一环,上面的作业管理系统中很多功能都依赖配置管理系统才能实现。 配置管理整个功能经过梳理之后如下图所示: 下面将依次介绍上面所述的功能: (1) 账户管理: 所谓的账户管理十分简单,就是服务运行的时候所使用的用户,目前线上的服务大多都是root用户,但是有改成业务用户的趋势,故需要有一个账户管理功能。运维人员在使用作业管理的时候,选择相应的用户进行任务执行。 该功能可以发展成用户权限管理系统,即在该系统中控制每一个用户的系统权限。生成相应的权限配置文件,并下发到所有服务器上。不过用户管理的功能可能系统运维已经管理,这里就不再叙述了。 (2) 文件管理: 文件管理功能比较基础,其实主要是对管理机上的重要文件进行管理,比如代码版本,脚本文件,软件包文件等等,文件类型包括:普通文件,文件夹,压缩文件和模板文件。 文件管理中,用户按照一定的规范将所需要的文件放到管理机上的指定位置,并将相应的路径配置在数据库中。 文件管理主要用在作业管理中进行文件分发的基础文件依赖。 (3) 脚本管理: 脚本管理也是文件管理中的一种,但需要单独管理,脚本是作业管理系统的基础依赖。脚本分为基础系统脚本和用户自定义脚本两种。 所谓的基础系统脚本就是经过严格认证过的,可以重复多次使用的基础功能脚本。而用户自定义脚本指用户通过上传或是通过web 编辑器提交的脚本文件,存储下来用户后续可能的重复使用。 基础系统脚本和用户自定义脚本都会存储在管理机的固定位置上,在文件管理中进行管理,用户在使用的时候选择对应的脚本名称即可。 脚本也支持添加标签,方便记忆和查找。 (4) 分组管理: 分组管理也是基础功能之一,在作业系统中脚本执行和文件分发都需要有明确的服务器ip地址,而分组管理就是将这些ip地址按照特定的用户自定义的方式来命名和分类,支持添加标签,用户在选择服务器的时候可以通过搜索的方式选择到一组服务器中的一个或几个。 分组管理依赖于资源管理系统,以资源管理系统的物理机资源(管理服务是虚拟机资源)为依据,用户选择一部分服务器并进行命名或添加标签从而得到一个新的分组。 分组可以分为静态分组和动态分组两种。 所谓的静态分组指的是确定完分组后,如需变化必须手动添加或修改的分组。这类分组会占很大一部分。 而动态分组指的是可以通过对服务器资源的某种匹配而自动将其添加到某个分组中的功能,比如说某个机房新上线N台服务器,可以不需要手动,而自动的添加到某个组中。这种功能可以通过手动来实现,在技术和时间限制的情况下,可以暂时不考虑。 分组功能还有组优先级的概念,主要是结合变量管理、模板管理结合使用,这些在变量管理和模板管理里面再进行介绍。 (5) 变量管理: 变量管理主要是配合分组管理和模板管理使用,所谓的模板就是在不同的情况层显不同内容的文件,而如何呈现不同内容就是在模板中配置了相关的变量名称,而变量的具体赋值则需要在变量管理里面体现。 变量管理建议使用yml语法格式来编写,比如如下的格式:
|
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|