运维是从 IT 诞生之初就一直存在的重要角色,在 IT 类企业中,尤其是互联网企业,运维、开发和测试被称为是驱动技术进步的三驾马车。而金融、政府、医药、教育、制造、运输等其它行业,为了进行数字化转型,也纷纷建立了自己的或大或小的数据中心,并为了维持这些 IT 系统的正常运转,设立了大量的运维岗位。可以说,信息技术已经并且正在改变我们身边的一切行业,而只要有 IT 系统的地方,就有运维同学的身影和贡献。
但最近几年,云时代的到来,让很多运维同学倍感焦虑,“云计算是未来”得到了大多数人的认同。2019 年 Q1,公有云 IaaS 市场同比增长 74%。越来越多的企业,开始把自己线下的数据中心和机房搬迁上公有云。而一旦企业放弃了自建的 IT 基础设施,甚至把员工的办公电脑都搬到了云上(桌面云),由公有云厂商提供服务,那么企业是否还需要这么多运维人员呢?
与此同时,DevOps 思潮席卷全球,大家纷纷尝试“组织机构变革”,打破开发 - 测试 - 运维之间的边界,由开发人员来直接负责自动化的测试和运维工作。更进一步,从 DevOps 进化出了 AI Ops 甚至 No Ops,人工智能开始在运维领域显露身手。而云计算与 DevOps 正好是天生一对。云是 DevOps 最好的平台,而 DevOps 是云上的最佳实践。
在云计算和 DevOps 的双重压力下,运维的未来会何去何从?
1. 云时代的运维是怎么样的?
冲浪是一个非常刺激的极限运动。相比海浪的力量,冲浪者的个体力量是渺小的,每一次冲浪都是一次冒险。但智慧并且勇敢的冲浪者会仔细观察海浪的方向并调整冲浪板与海浪方向一致,当海浪抵达时,冲浪者会站起来,在海浪的冲击下急速前进,享受浪尖上的快感。
冲浪者很清楚,自己成功的关键在于找准海浪的方向。我们技术人员也一样,只有保持对新技术的敏感性,并及时调整自己,才能借助浪潮的力量快速进步。
给大家讲一个真实的故事。2009 年,阿里云刚刚成立的第二年,时任淘宝技术总架构师行癫(现任阿里云总裁)宣布淘宝网将抛弃 Oracle,转投云上的自研数据库。获知此消息后,八十多个 Oracle DBA 把当时的 DBA 负责人后羿堵在会议室里,“如果上边铁了心要干,兄弟们的前途在哪里?”还好,技术人是讲理的,一场恶斗转化成了几十个工程师坐在会议室促膝谈心。既然上云是战略,为何不顺势而为?就这样,一群 Oracle DBA,开始亲手拆毁自己安身立命的系统。2013 年 7 月,淘宝最后一个 Oracle 数据库下线。时至今日,整个阿里集团,所有的核心业务 100% 跑在公共云上。
是啊,既然上云势不可挡,我们何不顺势而为,看看云上运维是什么样子的?
首先,云上运维和传统的运维,操作的目标是不一样的。传统的运维人员,需要能够熟练的手动操作来自众多厂家的计算、网络、存储等硬件设备,而云上的运维人员完全接触不到物理设备,取而代之的是云上的虚拟资源,例如云服务器,云盘,虚拟交换机等。云厂商将对资源的操作全部抽象成了软件定义的 API 接口,并用统一风格的 SDK、命令行进行封装,提供给运维人员使用。云厂商提供的图形化的运维控制台,也不过是 API 的封装而已。
其次,云上运维是高度简化的。传统的运维,需要学习来自众多“大厂”的认证,例如,网络运维要学思科的认证,数据库运维要学 Oracle 的认证,系统运维要学 IBM 的认证,等等。而在云上,虚拟专有网络产品将网络设备的管理和运维变得统一和简单,云上数据库产品实现了智能化的数据库管理,云服务器实现了动态的扩缩容和热迁移,这些都大幅降低了运维操作的门槛。云上的运维人员不再需要感知底层基础设施的细节,更不需要考取高难度的认证。即使是创业阶段的小企业也可以拥有和大企业同等的运维能力。
但是运维简化,并不意味着运维的重要性降低,相反,在云上,运维变得比以前更加重要了。
云时代运维面临的挑战
为什么在云时代,运维变得更重要了呢?主要有两个原因,一是云上运维的范畴比以往扩大了,二是云上企业对于稳定性的要求更高了。
从范畴上看,云上运维包含了从蓝图规划,到上云交付,再到云上管理的全过程。如果我们具体到流程和阶段,包括了设计选型、资源交付、系统交付、运维调优、扩缩容、资源运营、备份容灾,安全 & 审计等等。
从稳定性方面看,通常云厂商只负责基础设施的稳定,上层应用仍由企业开发人员自主开发,同时云上应用本身的稳定性也由企业自己的运维人员负责。如果具体来说的话,企业运维人员需要负责持续发布过程中的蓝绿发布、灰度发布、分批发布、自动回滚等的实现,以及应用层的监控、事件告警体系的建设。另外,云上基础设施的稳定性不能单纯依靠云厂商,也需要企业运维人员的相互配合。例如阿里云的云服务器单台实例的可用性达到 99.975%,但仍然存在着万分之 2.5 的不可用时间。企业的云运维人员可以采用监控、负载均衡、多机热备、两地三中心等常用的高可用设计,在不是百分百可靠的基础设施上,搭建百分百可靠的应用。
具体来说,云上运维主要面临着以下挑战:
首先,运维排查问题的难度增加了。由于云上“黑盒子”的存在,当故障突然发生时,运维人员往往只能看到服务出现异常了,很难快速判定问题出在哪里?是云服务商的基础设施出问题了,还是我自己的代码出 bug 了?...... 甚至就算排查出是云服务商某个服务的问题,部分运维人员也只能打电话给客服寻求帮助,而从客服得到的回复往往难以令人满意,从而耽误了故障恢复时间。
第二,云服务发出的消息、日志、事件等难以有效处理。如果运维人员每天收到几千条短信或者邮件,一定是无法及时处理的,只能无脑忽略。但是又不能设置邮件规则将它们全部扔到垃圾箱里,因为会担心漏掉重要的通知,比如服务器宕机的通知。
第三,资源的膨胀带来了管理的复杂性。所有的资源都是软件概念,对于一个大企业来说,这些资源可能分布在全球的十几个 region,分散在几十个云产品的控制台,服务于几百种不同的负载或者在线服务。更可怕的是,这些资源一直在变化。如何有效的跟踪、审计、创建、释放并保证无浪费?
第四,云产品的频繁升级带来了运维的频繁被动变化。云产品的选择非常多,实例类型纷繁复杂,包括预付费、后付费、预留实例券,什么性能突发型、计算型、通用型、GPU 实例、专有宿主机、裸金属实例,容器服务、Kubernetes 或者 Swarm、弹性容器实例,等等。更要命的是,这些云产品还在不停地发布升级,如何选择适合自己的产品?新功能如何才能帮助到业务?...... 盲目追随云厂商的脚步不是良策。
2. 如何调整才能适应云时代的运维?SRE 可能是答案
如前面所说,企业上云之后,仍然有大量的运维需求。但此时的运维,却又与传统的运维截然不同。企业应该如何进行结构调整以适应上云后的新形势呢?
DevOps 是现在提到的很火的概念,DevOps 实践的整个生命周期是从计划 -》编码 -》构建 -》测试 -》发布 -》部署 -》操作 -》监控,再回到计划,是一个循环。其中发布、部署、操作和监控(下图的黄色部分)是属于运维领域的。
DevOps 实践打破了开发和运维之间的壁垒,开发人员可以直接负责运维。云上的运维已经和软件开发融为一体,强调高度的自动化,沉淀了一系列的运维工具和运维平台,并朝着 AIOps 和 NoOps 的方向持续演进。
而反过来,运维人员如果能掌握开发技能,结合自动化工具的使用,是否能够做的更好呢?答案是肯定的。运维人员可以转型升级为兼具开发技能和运维技能的站点稳定性工程师(SRE)。Google 最早推出了 SRE 这一概念,并使得 SRE 部门成为其承担运维职责的一个研发部门。越来越多的上云后的企业,开始把自己的运维部门改造升级为 SRE 部门。
SRE 听上去很美,但真正要做到并不容易。以阿里云为例,早年阿里云也走过人肉运维的痛苦阶段,尽管运维工程师 7*24 轮班 on call 待命,但客户仍然投诉不断,系统问题不断。后来,阿里云团队开始建设稳定性,通过监控报警将故障的平均发现时间从 1 小时缩短到 10 秒钟,同时借助 AI 预测算法,在某些情况下可以在故障发生前,提前预警并采取行动。现在阿里云每年发布上千次变更,难免会出现变更导致的故障和异常,但是 SRE 团队蓝绿发布、灰度发布、分批发布、自动回滚、热迁移等技术,实现了发布全过程无人值守。
如何才能升级成为 SRE 呢?这三点建议可能对你会有所帮助:
- 一是学习 DevOps 的实践,熟练掌握至少一种编程技能(比如 Python、Go、Java 等),从思想和技术上,保持工程师的先进性;
- 二是学习云厂商提供的各种自动化运维工具,并灵活运用,尝试帮助自己企业搭建高效率的自动化运维平台;
- 三是积极参与开源和云厂商的生态建设,伴随运维生态一起成长,如果能产生出运维平台级的解决方案产品,广泛应用于整个行业,那么个人价值和商业价值都会得到体现。
3. 自动化一切是云时代运维的首要任务
要想实现云上运维的顺利升级,首要任务就是”自动化一切“,如果列出 Top3,应该是:监控自动化、运维操作代码化、基础设施代码化。
监控自动化
先来看监控,包括了“监”和“控”两个方面。
监控的“监”
“监”,从横向划分,包含了事件(Event),日志(Log),指标(Metric),告警(Alarm)四个维度;从纵向划分,分为底层基础设施的“监”和上层应用的“监”。
横向看:事件、日志、指标和告警
什么是事件?对于云服务商来言,事件其实是资源的变化,每一次资源的变化,都是一个事件。例如云服务器的每一次状态变化都是一个事件,包括开机中(starting),运行中(running),关机中(stopping),已停止(stopped)。
什么是日志?日志是客户行为和云服务内部行为的过程记录,包含时间、操作者、内容、级别等要素。每一条事件,都可以转化成相应的日志,记录到日志服务里。因此,日志的范围,比事件更大。日志服务所提供的,不仅仅是日志的记录,更重要的是日志的聚合和检索能力。例如,运维人员可以随时查看某一个资源在过去某一个时间段的历史记录。
什么是指标?指标是资源运行时的内部属性数据,最典型的指标就是 linux 里面 top 命令所显示的数据,包括 CPU、内存、IO 数据等。这些数据不属于事件,也没有记录下来作为日志的必要,但仍然是很重要的实时数据,是运维人员需要关心的系统健康指标数据,如果一切健康,就可以忽略。
什么是告警?告警可以认为是严重级别的事件,是需要立即采取人工或者自动化动作的事件。运维人员可以根据指标设定阈值来触发一个告警,也可以在事件和日志的基础上设定报警规则,触发告警。
纵向看:底层基础设施和上层应用
底层基础设施的“监”,需要由云服务商来提供基础数据,云厂商的监控往往会提供针对基础设施的事件、日志、指标、告警,运维人员可以很方便的配置和接入。
上层应用的“监”,可选择的产品就很多了,例如阿里云的应用实时监控服务 ARMS 提供了针对上层应用层的事件、日志、指标、告警,用户也可以选择开源的 prometheus 或者 zabbix 来自建。
基础设施和上层应用之间的边界并不是绝对的,其实我们需要的往往是从下到上的全监控。
监控的“控”
“监”的目的,是为了“控”,这里的控,具体指的是对事件和告警的处理。以短信,电话,邮件等方式通知给联系人,是最简单直接的处理方式,但这种方式显然容易被人忽略,而且延时很大。因此,SRE 应该实现自动化的事件处理。
运维操作代码化
如何实现自动化的事件处理呢?程序员可能会自然想到自己写一个 Event Consumer 程序,从云监控拉事件,然后调用资源的 API 进行处理。这个做法看上去很容易,但是具体实现真的这么容易吗?
首先,对于运维自动化平台来说,可靠性非常重要,如果 Event Consumer 只有一个单点,那么一旦出现故障宕机,就无法再处理系统事件。
这时,有经验的程序员可能会说:“我可以引入消息队列服务,进而利用多进程 Event Consumer 来分布式的消费,从而避免单点故障。”
当然,这是个解决方法,但是还会有一个问题,没有任何一个分布式的消息服务,可以实现既不重复也不遗漏消息,我们只能选择不遗漏消息,而接受可重复的消息。但重复消息可能导致重复操作,这不能被运维人员接受。那么,怎么去重呢?我们只能引入分布式的 KV 数据库,比如 Redis,根据 EventID 和原子的 Redis 操作(比如 incr)来作为消息去重的工具。
另外,一个事件的处理仅仅是调用一个 API 吗?不一定的,你可能需要对多个资源进行多个 API 调用,这些调用之间彼此有依赖关系,有些甚至必须串行。为了保证多个操作的事务性,即要么全部成功,要么全部失败(需要回滚操作),这时就需要一个分布式工作流引擎。
什么?你还需要定时的任务?那么,只能再引入分布式的定时任务框架了。
......
这样一看,是不是越来越复杂?实现一个高可靠、分布式架构的运维平台,显然不是一件容易的事情。何况,运维开发与普通软件开发不同,快速开发是第一位的,因为运维开发的需求变化更频繁,开发周期更短,人力也更为紧张。若没有平台的支持,单纯靠运维人员自己从头搭建一个自动化运维系统,并保证高效稳定持续运行,难度和投入都很大。
为了保证生产系统的稳定,创造了一个运维系统,那么,谁又来保证这个运维系统的稳定呢?这是一个悖论。
如何轻松实现“运维操作代码化”呢?两个建议,一是选择一个可以快速开发的简洁的运维语言,二是选择一个可靠的事件驱动的运维平台,而不是自己从头造轮子。
在运维语言方面,脚本化的语言成为了主流,比如 YAML,JSON 等,在遇到复杂的逻辑的时候,可以借助 Python、Shell,而 C、C++ 之类的语言,运维人员用起来就有点沉重了。
开源的运维平台,我们可以选择 Ansible、Puppet、SaltStack 等等。以 Ansible 为例,其核心卖点之一是“Agentless”,运维人员安装 Ansible 之后,可以直接基于 SSH,编写 YAML 格式的 Playbook,做 Linux 集群的管。另外,各个主流云厂商也为 Ansible 编写插件,因此运维人员可以用 Ansible 管理云上的运维动作。值得注意的是,云服务商也会提供原生的运维平台,比如阿里云提供的运维编排服务 Operation Orchestration Service,简称 OOS),AWS 提供的 System Manager Automation 服务,或者 Azure Automation 服务。
基础设施代码化
云基础设施包括云服务器、云存储、DNS、CDN 等,而传统的云基础设施管理总是面临着各种各样的难题,例如咨询审批流程长、响应不及时,手工安装和配置速度比较慢、难以版本化,易出错、遗漏配置项等等。
为了规避这些问题,我们提出了“基础设施代码化”,它指的是用代码的方式管理基础设施,并且维护管理它的全生命周期,包括审计的要求。代码成为了审计很好的记录,代码变更也可以追溯到人、项目组,解决了变本、追溯和变更历史的问题。
基础设施代码化后,会给我们带来什么样实际的好处呢?
我们举一个例子,假设在阿里云上搭建一个经典的三层在线服务:前面是 SLB 负载均衡,中间是若干台 ECS 作为一个服务集群,后面再挂接一套 RDS 数据库。同时,我们为这三层各自创建了一个 VPC,通过安全组设置安全规则。
在业务初期你可能只需要两台 ECS,但很快会扩大到 3 台、4 台。这时应该怎么办呢?比较直接的办法是在阿里云控制台操作,今天创建一台,明天再创建一台。
但这种方法明显是比较笨拙的,我们能不能使用“基础设施代码化”的方法呢?当然可以。我们把资源,定义在文本文件里,做成配置项,保存到云上。比如有一个配置项叫做 ServersAmount,代表服务器数量。我们把这个配置项从 3 改成 5,ECS 数量就自动从 3 台增加到了 5 台。再把 ServersAmount 从 3 改成 2,会自动释放其中一台 ECS。代码,或者说配置,是有变更历史记录的。代码也是可以很清晰地被审查的。代码还可以很容易的被复制。
怎么实现“基础设施代码化”呢?最关键的是需要一个平台,如果选择从头开发,那就不再是造轮子了,而是在造轮船了。
那么什么样的平台是值得选择的呢?开源的 Terraform 是个不错的选择,它得到了各个主流云厂商的官方支持,用户可以直接使用。不过,Terraform 要求运维人员自己准备服务器来配置安装,还要自己维护这个平台。另外,云厂商也提供了开箱即用的云服务,例如阿里云提供的资源编排服务(ROS)。
4. 云时代运维的未来发展
正如前文所述,云时代的运维工作正从手动操作过渡到代码开发,只不过这些用于运维的代码,形式不拘一格,可以是配置文件,可以是 YAML 或者 JSON 模板,也可以是传统的 Javascript/Python/Go 等代码。那么,未来,云时代的运维会怎么发展呢?
在我看来,云时代的运维发展其实很大程度上取决于云上应用和基础设施的变化。我们可以大胆分析和预测,未来云时代的运维将会是这样的:
- 目前主流的云上应用架构是自建 API 网关 + 微服务 + 分布式 RPC+ 消息队列等,这种架构需要的云上基础设施是负载均衡 + 云服务器 + 虚拟专用网络 + 云关系数据库等,其运维方式如前面介绍的。
- 未来几年比较确定的趋势是云上应用开发会越来越多的使用 Reactive 响应式 (反应式) 编程,全异步、事件驱动,对应的基础设施则会容器化,隐藏掉服务器这一层,这预示着运维工作会越来越多的围绕容器编排,比如 Kubernetes 展开。
- 中远期的未来,函数计算这种 Serverless 的开发模式将会流行起来,对应的基础设施则会简化到连容器都看不见了。用户不再为基础设施而付费,而是为实际的计算次数付费。云服务商会利用机器学习等手段,来保证函数计算所需的基础设施是高可靠的和高度灵活的。到时,运维人员已经不需要关心资源的编排了,但是函数内业务的监控和运维动作的自动化还是需要的。
- 更长远的未来,云计算,边缘计算,本地计算,可能会统一到一起,不再区分“线上”和“线下”,取而代之的是一种无处不在,但又不被人感知的计算力。具体来说,应用开发者写完代码,保存起来,就完成了业务的更新。“基础设施”和“资源”这两个概念,将彻底消失,只留下数据本身,包括静态数据(代码 + 配置)以及动态运行时数据。而运维,并不会消失,但会从面向资源的运维,变成面向数据的运维。