“一切都自动化”是持续交付部署流水线的一种重要原则,也是提升“持续交付验证环”运转速度的一个重要影响因素,软件配置管理是成为“一切自动化”的基石。
将一切纳入配置管理
软件配置管理:在整个软件生命周期中,对生产与运行环节中相关产物的管理,包括产物自身及其唯一标识和修订历史,以及不同产物之间的关联关系等。其目标是记录并管理软件产品演化的过程,确保组织在软件生命周期中的各个阶段都能得到精确的产品配置,并提升各角色间的协作效率。
配置管理的目标
获得可追溯性和可重现性,提升软件整个生命周期管理的安全性,并提高团队协作效率。
- 可追溯性:任何在获得授权的前提下,能够找到该软件的任何变更历史
- 可重现性:任何人在获得授权的前提下,能够重现从过去到现在之间任意时间点的软件状态。
配置管理的范围
在软件的整个生命周期中,包括四类制品,即需求、源代码、软件包和环节,这些事软件配置管理的范围。
配置管理的范围
软件配置的管理原则
一切皆有版本
如果想要更快地发布软件,仅仅对软件的源代码和发布上线的软件包进行版本管理是不够的,这种程度并不充分也不全面,还需要包括:
- 操作系统层:操作系统、网络配置以及网络及系统通用管理服务;
- 标准软件层:应用程序所依赖的标准化软件包,以独立进程形式运行,并为上层的应用程序提供基础服务,如数据存储、消息通讯、网络服务、数据库软件(MySQL、Redis等)、消息中间件(RabbitMQ等)、ZooKepper等;
-
应用软件层:团队开发的应用层序,以及该应用程序运行时所依赖的第三方组件库及相关数据。
持续交付中的版本管理内容
共享唯一受信源
唯一受信源使得团队成员能够掌握任意时刻的软件状态,并确保所有人所获得的信息都是一致的,其中包括三种数据,即业务需求/缺陷、源代码和软件包。
- 需求仓库:保存有关产品的所有版本需求描述和验收条件,并且能够记录每一次团队对需求达成共识后的版本变更记录;
- 代码仓库:保存所有源代的变更历史,除了源代码,还包括软件包整个生命周期中的所有以代码形式存在的内容,如测试代码、自动化脚本以及环境配置信息、软件包构建依赖信息等;
- 软件包仓库:自动保存部署流水线生产加工出来的软件包,满足后续环节的快速取用,包括三种仓库:
- 临时产物仓库:作为团队内部在某个发布版本处于开发期间进行协作沟通的唯一的软件包受信源,避免因环境不一致或重复打包等问题引入不必要的风险和浪费;
- 正式发布仓库:保存通过质量验证,即将上线或者已经上线的所有软件包,通过在受控管理系统上通过人工标记和自动传递方式,将经过验证达标的软件包从临时仓库移到正式发布包仓库;
- 外部软件包仓库:第三方软件库的私有服务器,用于存储内部所有软件所需引用、包含或使用的外部第三方受信软件包。
标准化与自动化
基线管理:所有仓库在某一个时刻的“快照”,在创建基线时,对仓库中的当前版本一个整体标记或复制,以整体记录此阶段的成果。
软件包的版本管理
集中式包管理服务
建立企业级的统一软件包库管理系统,将所有软件包纳入其中,并且对企业内部团队提供稳定的查询、获取和申请等服务。企业既可以自己开发这样的库管理系统,也可以使用开源或商业的包管理软件,比如Nexus和Artifactory等。其优点在于:
- 统一存储,空间占用少;
- 一致性。全公司使用统一的副本,是所有软件包的唯一来源;
- 安全省心。可以对软件包进行统一的安全扫描、法律审计管理。
- 下载速度快。
软件包的元信息
需要为每个软件包设置一些信息来描述和定义软件包仓库中的每一个软件包,以便于互相引用、溯源和检索。需要包括如下信息:
- 唯一标识信息
- 来源信息,如由谁提供、源代码在哪里、现在的状态如何等
- 依赖信息,是否引用了其他软件包
包依赖管理
软件包之间的依赖关系具有“重用”和“便捷性”两大特点,为了做好包依赖管理,需要从显示声明依赖、自动管理依赖和减少复杂依赖这三个方面入手。
- 显示声明依赖:将应用程序在不同环境中所需的软件包以及相应的版本信息,通过事先约定的描述方式记录在文档中。大多数的编程语言都有与其对应的软件包构建管理工具,比如Maven和Gradle等;
- 自动管理依赖:在显示声明对软件包的依赖之后,当构建、测试或部署软件时,只要有工具能够识别依赖描述文件,即可自动从软件包仓库下载和更新依赖软件包;
- 减少复杂依赖:软件包仓库需要额外提供一种能力,可以检查每个软件包的依赖关系,发现其中的依赖问题、风险与隐患,比如依赖过多、链条过长、依赖冲突和循环依赖等。
环境基础设施管理
环境基础设施:包括基础操作系统层和标准应用层,它们是软件运行的基础上下文,具有变更频率低的特点。
环境准备的四种状态
随着业务的升级和基础设施技术的不断发展,环境准备工作内容和工作方式也不断变化,可分为四种状态:
- 以人脑+手工为代表的蛮荒状态:软件较简单、用户数量不多时,由开发人员自己搞定所有与软件部署相关的问题;
- 以文档+私有脚本为代表的规范化状态:在上线前提供上线部署文档和规范化的上线部署流程,由运维人员来负责版本的变更;
- 以办公自动化为代表的标准化状态:开始搭建自动化平台,将上线部署文档和流程在web页面上提交,运维人员按照步骤手工执行;
- 以受控式自动化脚本为代表的自动化状态:自动化平台管理自动化脚本,包括两种脚本:
- 过程式脚本:最传统的自动化脚本,通过模拟手工执行步骤的自动化命令,缺点在于,不是幂等操作,每次执行的结果可能不一致;
- 状态声明式脚本:在脚本中指定环境的目标状态,由定义该状态申明规范的平台执行这个脚本,该操作是幂等的。目前主流的状态声明式工具有,Puppet、Chef、Ansible和SaltStack等。
环境基础设施即代码
将环境基础搭建的一系列准备工作以脚本的方式描述出来,并能够通过自动化的方式来执行这些脚本,即环境基础设施即代码,好处在于:
- 无论哪类环境出了问题,都可以快速自动化地构建出一个全新的环境;
- 只要获得授权,任何人都可完成这项任务,不需要其他人帮助;
- 任何对环境的修改都可以被记录和审计;
- 对不同环境来说,只要将其代码描述进行对比,就可以了解它们的差异而无需登录到实际主机上查看。
软件配置项的管理
软件配置项:软件构建时或运行于不同环境中时,通过设定这些配置项所对应的不同具体值,软件能够产生不同的行为。
二进制与配置项的分离
一个软件包通常由二进制文件与配置项组成,对其中任何配置项的修改,都会形成由二进制文件和新的配置项集合构成的新的二元组,成为一个新的部署包。将两者分离,从而实现只需要构建一次,在部署流水线的不同阶段就可以重复使用的目的,从而确保在不同阶段所验证使用的二进制文件是完全相同的,只是由于运行环境的不同而使用取值不同的配置项。
配置信息的分类
根据配置项的内容不同,可分为三类:
- 环境配置项:与运行环境相关,比如所用到的域名或IP地址,与其他系统或服务通信的服务地址与端口号;
- 应用配置项:与信息安全控制及应用程序自身相关,比如账号密码、数据库连接池大小、初始分配内存大小、日志级别等;
- 业务配置项:与应用程序所执行的业务行为相关,每一配置项都有默认值,如功能特性开关,商品定价策略等。
配置漂移与治理
配置漂移:随时间发展,由于各种未预期原因而做出的配置修改引起计算机或软件服务偏离了我们所希望的配置状态,通常是由于人的临时修改而引起,也可能是为了缓解生产环境突然出现的某个严重问题而临时调整了某些机器的网络配置;配置漂移往往使得生产环境处于某种不确定的状态,甚至会导致重大生产事故。
配置漂移治理:构建好的软件配置管理流程,比如,将静态配置放入版本控制库中,并禁止直接登录到主机环境修改配置信息,只能提交修改到代码仓库,并通过自动化方式进行生产环境中配置的修改,避免由于人为操作遗漏造成的配置漂移;还有一种更为严格的方式,就是“不可变基础设施”。
不可变设施
不可变基础设施要求,需要对其中任何一层进行变更时,只能通过整体替换的方式进行,而不能通过对其中某一层的内容直接进行更新或修改的方式进行,需要具备三个要求:
- 系统运行环境的准备均已自动化方式完成
- 一旦完成准备工作,该基础设施的任何一个层次均不得更改
- 如果因为某种原因需要对该系统环境进行更改,则必须使用另一个不可变系统环境来替代之,而不是对原系统环境进行变更。
实现不可变基础设施
- 物理机镜像技术和虚拟机镜像技术:使用镜像工具(如Full Automatic Installer, SystemImager和ISO镜像工具)对已经安装好应用程序运行环境进行镜像备份,并将镜像文件保存到统一的镜像仓库中,可以直接拉取镜像直接部署到宿主机上,进行简单配置调整后立即投入使用。
- Docker容器技术:更轻量级的容器技术,它比物理机镜像和虚拟机镜像具有更低的成本。
优势
- 简化运维工作:可以全自动完成
- 部署流程自文档:只需要创建一个描述性文本文件说明如何正确生成应用程序的运行镜像即可,不需要详细的部署应用程序的自动化步骤。
- 持续部署不停机,故障更少:所有变更都可以由源代码管理,通过部署流水线进行跟踪,基础设施的每一项均可以以脚本形式进行,将准备好的不可变基础设施直接进行替换
- 减少错误和威胁:通过自动化替换而不是修复,可以更频繁且规律性地重新生成实例,减少配置漂移。
- 多个环境基础设施的一致性:虚拟化和容器化技术使得开发和测试环节就能够以更廉价的方式得到与生产环境类似的环境基础设施,并对其进行验证,从而减少因测试环境与生产环境过多的差异而导致的生产问题。
- 杜绝了配置漂移:整个不可变基础设施被作为一个整体使用,若需要对其中任何信息进行修改,都要重新生成镜像。
- 被测试的即是被使用的:一旦对代码或配置修改完成,就会立即生成不可变的基础镜像,经过整个部署流水线的验证,可以确保生产环境使用的一定就是被验证的。
挑战
- 为不可变基础设施建立一套自动化运维体系在初期需要较高的成本;
- 生产环境中突发问题的修复时间可能会稍长,因为禁止直接通过SSH连接到当前有问题的服务器,只能通过重新生成镜像再部署上线;
- 对大规模软件服务来说,将大尺寸镜像分发到多台宿主机上需要耗费大量的网络资源,时间耗费也会不少;
- 有状态存储的软件服务并不容易被直接替换,比如数据库实例,拥有大量的数据量。
网友评论