迷之一键部署
搞 IT 技术相关的,尤其是后端技术和分布式相关的同学,怕是不只一次听过所谓的一键部署的提法,与此相似或者相关的,可能还包括自动化部署,一键上线/回滚,以及 CI/CD 相关的持续部署,持续集成,持续交付等等概念。
这里,不谈 CI/CD,只谈作为对用户产品的一键部署,无论是叫 one-click, single-click, one-key, one-press, one-button, one-command, single-command… 还是只是对外发布的某种快速部署工具(集)。部署,俗称上线,不过细究概念,上线似乎更侧重日常功能更新,而部署的概念,更侧重首次的初始环境搭建。无论何,传统上,部署都是运维(OP)同学的日常工作。
所谓一键,大都是虚指。做过运维的同学知道,部署怎么可能是一件容易的事情。考虑到现代服务端软件集的庞大,从数据库/缓存,到后端逻辑,到前端服务,到监控系统,到报警系统,各组件相互配合,才完成最终对用户提供服务。更不用说机房服务器环境,云主机环境,现代分布式服务的多样和复杂性,导致 trouble shooting 极其复杂,哪怕是饱经事故的老 OP,也不容易。
正因有了这些复杂性,可信赖的部署工具就更显得重要。好用的工具不只为虎添翼,还给萌新在黑夜里点了盏明灯,在产品拉新的层面更有极其重要的作用。垃圾的工具,处处是坑不说,让人骂娘的心都有,且有工具还不如没有工具。没有工具的时候,OP 拿着命令行一顿敲,不也成功部署了么?
是的,关于一键部署,这里要从命令行说起。
一键部署从哪来
命令行 OP
最原始的典型服务部署过程,不过是登录到服务器,通过 scp/wget 下载到最近的软件包,解压编译,必要时候还需要下载若干编译依赖,然后修改配置,最后启动程序完成部署。
潮一点的容器部署方式,拉几个容器镜像下来,加上参数 run 起来,也是略苦逼。
是命令,就有可能出错,相信多数 OP 都有一个命令行小本本,记录着常见操作需要执行的命令。
一键部署小脚本儿
看起来传统的命令行式部署很容易自动化,把这些命令集合在一起,于是就诞生了最原始的,一键部署脚本儿。脚本丢到服务器上,一执行,漫长或短暂的等待过去,服务 ready.
而容器化部署,也可以自动化成 docker-compose 等待,外部包一个处理配置的脚本,依旧好使。
随后 OP 同学为该脚本增加了更多的命令行参数,比如软件包版本号,部署路径,配置文件的某条常修改的参数,看起来这个时候,已经可以交付外部使用了。
一键部署命令行工具集
然而多数服务端软件比以上流程复杂得多,OP 们往往面对的是一个集群,每台机器的配置或命令都有所不同,且服务的启停过程往往具有某种依赖顺序。这时候,简单的命令堆叠小脚本就不能满足需求了。
开源届倒是提供了不少解决方案,比如 Ansible, Puppet, Chef 等待,以及若干虚拟化解决方案,实现了配置,执行,部署,交付的完整流程。此外还有若干轻量工具,靠更多的人工配置环境提供更高的自由度,例如 fabric.
这时候的一键部署,可能就是某个强大工具的配置文件,描述了部署的步骤,然后加上目标机器环境的配置文件,通过执行一条命令,完成整个环境检查,环境初始化,部署应用,启动应用的全流程。
例如 ansible-playbook -i inventory install.yml 这样一条命令,加载 install.yml 描述的安装流程,然后在 inverntory 指定的服务器列表上执行这些安装流程。
但是这样的工具有一个很大的缺点,那就是运行异常可能需要工具的专家介入。专家大概是能给工具写插件级别的。以 Ansible 为例,能讲清楚机器登陆时候,不同发行版报错原因以及解决方法的人,并不多。
对于容器化部署,那当然要诉诸于各种编排工具,不在此讨论了。
一键部署 UI
严格地说,命令行也是 UI 的一种,原教旨主义会告诉你,UI 就是 User Interface,就好比 explorer.exe 也是 SHELL 一样。这里说的 UI, 特指 GUI,大概包括说有的图形应用程序,尤其指浏览器 Web UI.
之前在推上有句吐槽,“每个傻逼的后端产品 PM,都有一颗给命令行写 GUI 的心“,这话放在一键部署领域,依旧是合适无比。
做好 UI 的第一步,大概是不做 UI.
你可以认为 UI 在大部分时候是伪需求,问问自己的内心:在已经有较完善的一键部署工具集或者脚本的情况下,为什么做 UI?
其实答案很简单,UI 不是给 OP 或者一线工程师用的。它目标是为了把一件事情的门槛降低到尽可能低,低到只是恰好理解这个服务是干什么有什么要素的人,也能操作。
然而这是不可能的。所以所谓的你看到到的一众 UI 只能将大部分晦涩的配置选项隐藏起来,然后让你填写一个机器列表然后”一键“部署。然后失败了,弹出简洁的“部署失败”四个大字,或是晦涩的冗长的没人会去看的错误日志。
迄今为止,见过可以说的上能用的一键部署 UI, 可能是 Ansible-Tower,即 Ansible AWX, 但它真的只是包装了 Ansible 的命令行,所以足够简洁,足够完备。然而它的 trouble shooting 难度依旧是 Ansible 级的。除非你对 Ansible 足够熟悉,否则还是找足够经验丰富的人去追查背后到底发生了什么错误。
历史的例外
大概会有若干种特殊情况。例如大型公司的自研(或致敬某开源项目的)内部系统,例如云平台服务商的某些自动部署工具等。共同点是,受控底层环境,用户有天然身份门槛。
所以这个时候,不乏内部优秀工具或是云平台优秀工具。
一键部署现状
然而该做不该做的东西,总是要做的。所以谈谈一键部署到底要做啥吧?这里主要谈分布式系统集群的一键部署。一个应用一个二进制文件一台机器,就真没必要折腾。
Inventory 管理
这里的 inventory, 泛指一切目标资产,比如服务器,云主机或者虚拟机。其中的属性信息繁杂,和后续的部署过程有着强依赖,比如机器上的配置,例如磁盘空间,内存,CPU 时间等。通过 inventory 的自动检查和初始化脚本,获取各种信息,为部署过程提供方便。
部分支持云主机的 Inventory 管理,还包括按需动态创建主机实例。
再广义些,还可能包括外部可用的服务资源,例如公共的 redis 服务。
Credential 管理
Credential 是指登陆机器进行操作的用户权限,比如 SSH 私钥,或是机器的用户名密码,或是云平台的访问所需密钥 KEY.
应用管理
所谓应用,就是将要部署的服务(往往包含多个不同子应用),它们之间通过特定的依赖关系互联,最终对外界提供服务。除核心服务应用之外,还可能包括监控应用(含报警应用),管理应用(adminstrative dashboard),工具应用(例如备份/恢复工具)等。
应用的管理,主要是应用元信息的管理,应用之间的依赖关系管理,应用对资源的关系,应用配置管理。
应用元信息的管理,往往是描述一个应用的诸如版本,二进制等等信息,往往是部署的第一步,先准备好将要部署的应用。其中涉及到产品二进制分发的问题,则是额外的话题了。
应用之间依赖,应用对资源的依赖关系的管理,往往通过配置管理的形态实现。
配置管理
配置管理不只包括应用配置管理,往往还包括部署的配置管理,但两者之间往往存在交叉融合的地方,比如说指定某个机器的上部署的应用 A 需要一个特殊的配置项。
应用配置管理
管理各应用的配置参数,最终可能以配置文件,应用启动的命令行参数,或是应用的环境变量等方式存在。其中部分配置暗含各应用各部署目标机器之间的互联关系,往往是动态生成得到。例如
- 应用提供服务的端口号
- 应用的数据目录
- 应用的日志目录
- 某应用有两套配置,一套用于生产环境,一套应用于测试环境
- 某条配置项目按某种特定规律生成
- 某配置项目随机生成,但要求全服务集群应用的改配置项必须相同
部署配置管理
部署配置管理其实就是所部署的应用到具体的部署目标之间的映射关系。例如:
- 某台机器是监控机,需要部署所有监控模块
- 某台机器需要打开端口 80 提供服务
- 某台机器的某个目录部署应用 A
- 某台机器的某个目录做应用 B 的数据目录
部署配置管理的高级形态,是声明式。即机器声明我支持某资源,由一键部署系统自动选择依赖关系。这也稍许牵扯到高级形态的部署。
状态数据管理
应用的正常运行,不只依赖配置,往往还有若干依赖数据。传统的静态依赖数据之外,就是动态数据了,往往以数据库或是数据目录的方式存在。
状态数据的管理,是整个部署届的难题。越是庞大的状态数据,在部署,环境变更,灾难恢复,以及迁移的时候就越成为问题。
现代分布式系统一般通过底层分布式数据库的方式解决状态数据管理,然而这带来了一个鸡生蛋蛋生鸡的问题,底层分布式数据库的部署,又是一个状态数据管理问题。
是的。我们还有分布式文件系统。233。
部署管理
部署管理,即管理具体的部署操作任务。往往通过任务队列的方式实现,是整个一键部署最核心的部分。
在部署过程中,尤其要提供相对较清晰的进度展示,并输出合理的操作日志供时候追查问题。
部署往往也包含了变更管理,即应用版本或某依赖更新后,再次触发部署。所以部署不应是一次性任务,而是可重入任务。
部署任务的触发一般提供手动和自动两种模式。所谓的“一键”就是这里点击的“部署”按钮。
而自动触发,就隶属持续部署或是持续交付的范畴了,一般通过某种触发器或是任务计划实现。
监控管理
服务的正常运行,离不开监控。在一键部署系统中,监控往往作为单独的应用存在,所以将之化解为另一个应用管理的问题。
监控往往包括监控数据的收集,监控数据的查询展示,日志收集等问题。高级形态还包括动态调试等,加入了诊断系统的功能。
监控系统一般还会提供通知(notification)的功能,报警或者状态日报信息通过通知系统发送给关注者。
服务管理
服务管理相对较简单,即一个部署完成的集群,其中服务的启动,停止,删库跑路等操作。其中还可能牵扯到服务存活检测,服务自启动,服务异常自动重启(保活)等知识点。
服务管理可以作为特殊的部署操作来实现,比如设定特定的部署动作,检查环境后启停对应服务。
PM 们提出的其他管理
如上是核心功能。然后 PM 往往会提其他需求。例如:
- 权限管理:作为持久运行的变更系统,至少需要一个权限控制,尤其生成环境
- 用户管理
- 用户组管理
- 用户和用户组的权限管理
- 多应用管理:即整个一键部署工具作为通用平台
一键部署的将要到哪里去
一键部署,终将要被云平台或是云平台的容器编排消灭的吧。
但到时候,又是给容器编排做 UI 了。