中小型运维团队如何设计运维自动化平台

2020-07-06 00:00:00 执行 操作 业务 作业 平台

前言

我给中小型运维团队的定义是整个团队人数(所有运维工程师 + 运维开发工程师)为 20 人以下,一般这样的团队,能为自动化投入的资源也许就 1、2 个开发人员。

BAT 等大公司的 DevOps 平台功能涵盖的范围非常全面而且各种高大上,这么庞大的体系对于中小型运维团队,要靠手头顶多 2 名运维开发工程师来实现落地就懵了,不知该从何入手。所以往往大部分中小型运维团队要么传统人肉运维黑路走到底,要么指望公司咬牙上 DevOps 商业服务。

然而,仅靠购买商业服务也未必能完全解决问题,主要原因有:

1 . 历史项目成本考虑:商业平台不支持个性化,历史项目未必能直接对接商业平台,需要通过运维与业务侧均重构以适应商业平台,对接成本甚至高于自建平台,且要高速运行的业务侧停下配合也并不靠谱;

2 . 商业机密数据的考虑:商业平台会存储运维 / 部分业务相关数据,这对于安全要求较高的行业来说,自建平台的可控度更高;


然而,中小型公司的自建平台大多都算是重复造轮子,虽然各家业务情况各异,但也有可以抽象成可复用的架构体系,这也是商业自动化平台的价值所在,如果团队是 10 人以下且没专职开发人员再且业务技术历史债务不重的情况下,选择商业服务也不失为明智之举。

我们经常看到各种大厂的自动化平台一般包含且不限于以下内容:CMDB、配置中心、管控平台、数据平台、CI/CD、作业平台、容器管理、扩容缩容、辅助运营、监控中心 等等,各种高大上词汇让人目不暇接。

由于中小型团队的用人成本必须控制得极其,一般不会有太多人力资源投入到自动化平台的开发,所以必须找出核心功能,以达到快速落地投入生产环节使用为目的。我们不可能对上述功能点面面俱到,这样只会让自己无从下手。

其实核心的功能模块只有两个:CMDB(配置平台)和作业平台。我们作为中小型的运维团队,其实能把这两部分完成即可满足 80% 的业务需求,在此基础上,再根据自身业务需求再考虑开发其他扩展功能如 CI/CD、数据分析、业务监控、辅助运营等。

项目背景

需求驱动导向,大家也不会因为上线一个小项目就招人做自动化平台,在什么情况下我们才需要做自动化平台呢?

去年,随着手游项目的发展,公司业务需求处于一个飞速增长的阶段,在短时间内已经发展到将近数十个项目(含各种渠道、平台、分区),业务形态各异,包括页游、手游、站点、app 等,这样众多的项目运维管理成本非常高,传统的运维管理方式很难高效率、高质量地管理和把控如此多的产品和项目。

随着虚拟化、云、微服务等技术的发展,再加上有众多的云服务提供商(阿里云、腾讯云、UCloud 等),应用程序的底层运行环境愈发多样化,各种运维对象都需要通过一个平台进行统一的操作和管理。

为了应对以上问题并高质量完成运维保障服务,我们必须做到:

  • 通过平台统一管理所有运维对象,对项目组、对运维部门的所有操作都程序固化;
  • 实现所有项目的持续集成、自动化部署、项目组自助操作以提升发布效率和降低故障率;
  • 有一个完善的配置中心为所有运维自动化的底层数据和配置基础,驱动所有运维脚本、工具、组件正常运行;

如何达成目标

明确了目标之后,你会发现这三个目标正好对应三个运维术语:标准化、流程规范化和 CMDB。

  • 标准化:从主机名、IP、操作系统、文件目录、脚本等一系列运维对象都制定标准规范,业务部门和运维部门都遵守同一套标准,基于这套标准去建设统一的平台。
  • 流程规范化:主要是涉及 程序文件打包、开发测试线上环境管理、发布流程 等多部门协作的规范,必须落实到程序固化或者文档固化,打造 Dev 和 Ops 之间的标准交付环境。
  • CMDB:这是一切运维自动化体系建设的基石,其它如配置管理、作业执行、资产管理等需要基于 CMDB 才能形成体系,构建完善的运维对象生命周期和操作闭环。


标准化

标准化包含的范畴非常多,从简单的操作系统版本、主机名、IP 段、系统帐号密码到软件安装的目录、参数、配置文件等等,也许不同的公司有其特有习惯和历史遗留,所以这个没有一个全业界的统一模式。

现在只需要把贵司的习惯用文档的形式固化下来,再彻底检查生产环境的情况是否满足规范所述,不满足则按规范操作。

对于历史不是太悠久的项目要修正不会太困难,如果连这点都嫌麻烦的话,也不用谈什么运维自动化了。

简单画个思维导图,标准化的范畴主要包含但不限于以下内容:


流程规范化

流程规范化是在建立了标准化之后,为了规范运维内部以及与外部门合作的一系列复杂事件的细节做法,比如要发布新版本、上线新项目、业务扩容缩容等。

这一部分不太容易展开,因为不同公司有自己的做法和习惯,无论是怎样做,请用文档规范和约束各部门人员的行为,这样才能方便程序化和自动化,不然程序就要写多很多 if-else 语句或者需要配置化来兼容各种不规范情况,徒增开发人力消耗。

CMDB

不用赘述,CMDB 的设计肯定是运维自动化建设的重中之重,设计好的话,运维平台的开发可以有事半功倍的效果。

CMDB(Configuration Management Database)配置管理数据库,是记录所有运维对象信息的数据库,所有运维流程需要基于 CMDB 的数据进行操作,形成操作闭环,操作的结果会反馈到 CMDB 中。

此系统提供了一整套接口界面与其它任何需要信息的系统进行对接,这也是设计初衷,将信息从一个统一的、标准的源头输出给各垂直或水平业务功能系统,而运维需要做的就是维护 CMDB 本身基础数据的完整性、准确性,CMDB 与各流程系统、垂直功能系统结合之后实现信息数据一处变更,处处同步。

一个机器下架的操作:

传统方式:通过 SSH 登录到该机器,关闭所有业务程序,关机,在控制列表删除该 IP,下架,登录资源管理系统删除该机器信息。

自动化方式:在 CMDB 中编辑其状态,系统自动调用底层工具关闭服务、关机,并自动将机器信息在 CMDB 中更新状态

区别: 传统方式各个步骤都是非原子性,每一步都可能有错漏的问题,如忘记删除控制列表 IP 或者忘记更新资源管理系统信息,运维流程无法达到操作闭环。而真正的自动化方式是应该需要达到操作闭环,无需人工干预。

如何设计

CMDB 的设计有一个大的误区是想建立一个大而全的属性表,恨不得想把全部运维对象的全部属性都找出来,比如:

从零散的运维对象来拼凑 CMDB 基本都是吃力不讨好的,因为这样的设计方式根本没有从业务出发。

而真正能解决业务问题的 CMDB 必须回到业务上面来,从核心的三层关系开始组建 CMDB,这三层概念从大到小分别是:业务、集群、模块(游戏行业术语一般叫项目、分区、服务)

设计思路应该是这样的,我所运维一个业务,它有哪些集群?集群下有哪些模块?模块下有哪些机器?机器有哪些属性?各种属性之间有什么关联关系?

通过这样的思维方式慢慢把真正的 CMDB 组织起来......


当然,运维对象远不止那么少,还需要大家根据自家业务多多挖掘,这个过程比较艰辛,但不需要一步到位,先确定好核心对象,再慢慢完善补充其他对象。

配置项属性

我们把 CMDB 的某个对象称为配置项,一个典型的配置项如一台主机、一个域名、一个 IP 。

举个例子,一台主机,其属性获取的三种方式:

  • agent 获得:如 cpu、memery、disk、ethX 之类的硬件信息,一般用 python psutil 模块可以获取大部分所需要的属性;
  • 云服务商 api:有部分属性不能通过 agent 获得的如 EIP、Region、Zone 等,如果不是用云主机的就不需要这一部分;
  • 手工维护:有些属性不能自动获取,只能通过人工录入,不过这类属性还是尽量越少越好;

由点到面可以看出,配置项的属性类别基本可以分成三类:

人工录入 : 自动化系统所需的业务 - 集群 - 模块关系,每台主机运行什么服务等等。

外系统 API: 需要通过云服务商 API、Zabbix API、K8s API、其他业务系统 API 等途径。

自发现: 机器内部获得,如 python psutil、puppet fact、ansible setup 等途径。

了解属性类别可以帮助我们更好更快地完善配置项的各种属性自动获取机制,尽量避免人工干预。

再聊聊主机,主机是一个承上启下的核心对象,在它身上有很多属性会被各种功能所使用,所以我们要先理清它和其他对象的关联关系。

这里的 业务 - 集群 - 模块 - 主机 属于物理概念,是机器所在的物理层次关系,因为机器必然伴随着机房、网络、光纤之类的硬件概念,虽然说是物理层次,但是你用云服务的话,就不存在主机这个实体。

服务 是机器的一个业务属性,一个机器可以对应多个服务,作为服务的下一级别是进程,比如一个 web 服务会有 nginx、tomcat 等若干个进程,定义一个服务则需要与之关联的进程,进程的主要属性会有进程名称、起停命令、占用端口等。

作业平台

定义

作业是一系列运维操作的抽象定义,任何一个运维操作都可以分解成一步一步的操作步骤和操作对象,不论是发布变更还是告警处理,都是可以分步骤的。

命令: 一个可以独立的操作,简单的如关服、开服、执行 xx 脚本等;

文件分发: 把指定的文件分发到目标机器的目标路径;

作业: 一系列命令、文件分发的有序组合,作业的步骤可以由 “命令”、“文件分发” 以及 “执行对象” 组成;

举一个相对复杂的操作过程,如更新代码并重启服务:

1 . 对 web:关闭 tomcat (/home/tomcat/bin/shutdown.sh)

2 . 对 server:关闭业务主进程 (/home/server/bin/stop.sh)

3 . 对 web:分发新的站点文件 (scp xxx yyy)

4 . 对 server:分发服务端文件 (scp xxx yyy)

5 . 对 web:启动 tomcat (/home/tomcat/bin/startup.sh)

6 . 对 server:启动业务主进程 (/home/server/bin/start.sh)

可以看出,流程包含了一系列 “对象”-“操作” 的有序的命令以及文件分发的集合。“对象”可以是一个组、一个或者多个 IP,在执行命令时候可以在系统的页面动态指定目标对象。

作业定义时有各种增删改查操作,每个执行过的作业需要记录执行人、执行时间、结束时间、返回值等信息。

执行顺序

作业需要按顺序执行,当一个步骤成功后才能执行下一个步骤,如果执行失败需要停止运行作业,并保留执行的各种日志。

比如一个作业定义如下:

  1. 对 web 组(3 台机器):执行 stop tomcat;
  2. 对 server 组(4 台机器):执行 stop server;
  3. 对 app 组(2 台机器):执行 stop app;

执行细节是步对 web 组的 3 台机器同时发起 stop tomcat 命令,等待 3 台机器全部返回结果后,如果结果返回 0 表示命令执行成功,这时候才继续进行第二步对 server 组的流程。如果步返回结果不为 0,则提示流程执行失败,提示需要人工检查,终止后面的流程。

主要对象

下面可以大致画个图勾勒出作业平台的主要对象

作业这个概念的提出,即可以将运维工作的各种“变更”、“发布”、“故障处理”等零碎操作分解成一个个可复用、可扩展、可执行的独立操作命令,那么终平台化的自动调度将成为可能。

开发的时候其界面和操作方式可以参考蓝鲸的作业平台(bk.tencent.com/document ),我所接触过的几个自动化平台(包括商业的和网易内部的)都是应用了类似的设计方式 ,这算是一个经过众多运维团队考验的佳实践,如果没有什么特殊业务需求,基本可以按这种模式启动以提高开发效率。

然而,每家公司的具体业务形态决定了必然会有差异化的需求,随意列举几个吧。

  • 作业权限系统,不同角色用户可操作不同级别的作业;
  • 作业运行前确认,比如某测试同事启动作业,需要对应主程或者主策划确认才启动;
  • 等待确认超时时间,比如等待 30 分钟,未确认则取消启动;
  • 作业异常返回则报警邮件通知到运维组以及对应项目组同事;
  • 灰度执行,按作业的设置,先在测试服运行,再到正式服;
  • 作业配置克隆,快速搭建新的项目的作业配置;

差异化需求的开发可以在后期慢慢迭代改进。


作业执行情况分析

节约人力预估

因为作业平台是一个让运维定制各种线上操作,封装任意能通过脚本完成的功能,可以供自己或者项目组自助使用,尽可能做到运维无人值守,运维提供解决方案,那么其大作用就是为运维部门节约人力,杜绝重复劳动。

作业执行作为自动化平台的核心功能,必须挖掘其利用效率,比如根据执行日志统计每天、每周、每月执行次数,执行总耗时等数据,以估算出平台为运维人员节省多少人力。

使用平台前:

项目同事放下手头工作 ->通过邮件或者 IM 通知运维同事执行某项操作 ->运维同事放下手头工作,读邮件或 IM,理解项目同事的操作内容 ->执行操作 ->通过邮件或者 IM 反馈项目同事 ->运维同事返回原来工作 ->项目同事放下工作读邮件或 IM 再返回原工作

使用平台后:

项目同事操作平台直接执行某项操作得到反馈

这个过程对于项目同事和运维同事双方总共至少能节约人力 15 分钟,减少了很多沟通、理解、反馈的时间成本。

对于比较常规的普通操作则无需运维同事干预,除非执行异常才需要运维人员介入。

我们通过统计得知平台每月执行作业的总次数为 N,每次预计节约人力资源 15 分钟(0.25 小时),则每月总节约人力为 0.25*N 小时,假设 N 为 1000,则每月节约运维部门 250 个小时的人力资源。

一个运维人员一天也就工作 8 小时(不加班的话~),一个月为 21*8=168 小时,那么节约 250 小时则约等于 1.5 个运维人员的月工时。

由此可见当作业平台的执行次数越大越能形成规模化,对人力资源的节省效果越有利,假设当 N = 10000 的时候,相当于节约了近 15 个运维人员的月工时,效果还是相当可观的。

平台的执行数据可以利用 echarts 做报表,让运维同事实时查看历史执行次数和预计节约人力。

图表解析:X 轴是时间,以每个月作为一个时间区间,统计该月一共执行了多少个作业。Y 轴的是作业的执行总次数(蓝色轴,单位次),然后假设每个作业约节约人力 15 分钟,终计算出每月节约人力总时间(红色轴,单位小时)。

作业异常分析

作业平台可以让运维人员解放了很多劳动力,但是我们也不可能保证每个作业都能正常运行,若在执行异常的情况下,我们可以为异常的原因打上标签,打标签可以根据错误输出关键字匹配自动分类或者人工归类,然后统计各种异常情况的比例,再重点分析并处理异常比例高的情况。


图表解析: 由上图可以看出这是各种异常的数量分布情况,异常的分类是需要运维预先定义并且有足够的区分度。然后根据作业在一个时间区间内统计出各种异常的比例,再利用饼状图可以方便找到比例高的若干项,如上图是【运维脚本 bug】和【业务代码异常】比例高,再着重分析解决这类异常的原因来降低运维操作故障率。

总结

运维自动化平台的建设本质是运维团队服务化能力的变现过程,它让我们从大量重复无规律的人肉操作中解放出来,专注于运维服务质量的提升。由于文章篇幅所限,未能和大家全面介绍整个自动化平台的设计思路,按系统的核心程度来划分,核心的是 CMDB 和作业平台,当完成这两部分之后,次核心的 CI/CD、数据平台、监控平台也可以投入开发,后面的运营辅助、故障自愈、智能扩容缩容甚至 AiOps 等也需要 DevOps 团队继续探索。

相关文章