基于Saltstack、Artifactory打造传统模式下持续部署平台

一、 持续部署

1. 现状

由于没有建立标准的持续部署流程,导致了版本管理混乱,制品管理混乱,上线持续时间长,上线测试覆盖不全面,业务流量上升后故障较多,排查复杂。运维、测试、开发人员每次版本迭代的时候,都要可能需要经历一次通宵的历练,并且这种在上线的第二天依然会出现很多线上故障。

2. 痛点

·自动化发布体系覆盖率低。
·无标准化发布的流程。
a) 只注重敏捷、忽视质量问题;
b) 变更频繁导致故障率增加;
c) 开发语言种类多,发布制品管理混乱,发布方式复杂;
·安全问题容易被忽视。

二、 工具介绍

1. Saltstack

基于ZeroMQ的开源的配置管理工具。笔者之所以选型使用saltstack,而放弃了ansible,原因是由于ansible基于ssh通信,在管控主机超过五百台之后,基于消息队列的命令下发方式无论在稳定性还是速度上都优于ssh协议。笔直另外选在saltstack的原因是,在服务的开发团队中存在着不同的技术栈并行的状况,尤其是java和.net并存的情况下,saltstack对于windows的支持明显要优于ansible。更容易作为多平台的底层发布工具。
而基于SaltStack打造自动化部署平台主要是用grains、pillar、state三个特性,grains用于获取默认环境配置信息、pillar用于定义环境信息、state用于编排发布文件进行发布。

2. Artifactory

全语言制品仓库管理软件,有开源版及企业版两种。开源版支持maven制品管理;企业版支持全语言制品管理,支持元数据管理功能,提供高可用部署方式、匹配nvd及vulnDB数据库,提供漏洞扫描能力。

三、 针对上述痛点解决方案

1. 自动化发布覆盖率低

通过搭建兼容多平台部署统一发布工具,替换掉传统的shell脚本拷贝的方式实现发布工具标准化。通过SaltStack的state特性,实现跨平台的基础服务发布、服务启停、文件发布、配置发布、远程主机管理等90%以上手动操作。使用SaltStack的state编排文件,执行远程命令,通过Artifactory获取制品及配置,将需要的版本发布到线上。
主要方案在部署平台中,通过json格式描述发布流程,通过yaml.dump(sls_json)将json文件转换成yaml各位的配置文件,最终通过平台调度saltstack执行编排好的任务。
转换后的yaml文件格式如下:

2. 标准化发布流程

· 备份
发布任务编排的第一步就是备份,备份需采用本地备份加异地备份两种机制,本地备份用于快速回滚,异地备份用于环境重建。
·切流量(蓝绿部署)
对于服务,尤其是有状态的服务,需要在注册中心中进行节点下线,确保本节点所有处理结束后,再进行部署。
对于页面,需要在负载均衡上将节点注销,对没有流量的web页面进行部署操作。
·部署
通过saltstack的sls特性,编排部署文件,对多个部署任务进行统一进行发布。
部署时我们希望可以在部署页面查看到类似下述信息,如:部署包对应的需求id、部署包对应代码的提交信息、部署包自动化测试的通过率、部署包的代码扫描结果、部署包的安全扫描结果、部署包人工测试的结果等等。运维人员需要在发布过程中看到此类信息,来明确包是否通过了所有质量关卡、具备了上线条件,从而判断此次上线是否可以继续进行。这里我们使用了Artifactory的元数据功能,用于记录软件包诞生的整个生命周期的信息,并通过api方式对接到发布平台。给运维人员一个完整的包的信息记录。
·自动化测试
此处自动化测试主要可以理解为检测服务端口通信是否正常、回归线上功能是否可用、缺陷是否被修复、新特性是否部署完成等。同时此处需要预热服务及站点,通过自动化的测试打通业务流程。
·流量回归(金丝雀)
部分真实流量切换到已经部署完成的应用上,通过全链路日志追踪或监控指标反馈来初步判断新上线应用是否健康运行,并将此结果作为后续发布或回退的依据。
·部署补全(滚动发布)
在使用低谷时间将流量牵引到已部署完成的应用上,同时将其余应用升级。
·变更管理通告。
上线成功后需要及时的通知大家线上版本已变更,产品经理需要及时更新文档,运营人员需要及时对用户进行告知。
·回滚
任何发布都需要考虑回滚方案,对于单个应用需要回滚到一个指定版本;对于多个应用,需要明确一个回滚集,通过发布时的编排任务指定回滚的编排任务。对于数据库等更新,如果回顾复杂,则需要在升级方案制定前就明确回滚方案或在业务中做好版本兼容。

3. 建立统一的制品管理仓库

大多互联网公司已经对源码仓库有了统一的管理,但对于制品依然处于一个原始的管理状况,比如使用ftp以及每种语言开源的管理仓库。这里遇到的问题是,运维人员需要投入大量的精力维护不同的包管理平台(如ftp、maven、nuget、pypi、docker镜像中心等)。浪费掉大量运维团队的人力成本之外,也极度复杂了发布流程。发布人员需要在不同的平台获取上线的包,导致发布流程混乱,发布平台配置混乱。并且大多数开源组件均不提供高可用能力,一旦硬件或软件出现故障,都将严重的影响发布效率。
为了解决这种问题,我们采用Artifactory来管理所有语言的制品仓库。与统一gitlab一个道理,我们把整个公司的制品统一管理,成为对接发布平台的唯一包来源,从而规范了发布流程。

4. 漏洞扫描

目前安全团队扫描大多是在服务部署上线后进行,这种情况下和容易造成由于版本有安全漏洞导致的整个迭代废弃,所有包需要重新编译,重新经过测试流程以及上线过程,浪费掉大量的时间,降低迭代的速度。
解决办法是将漏洞扫描步骤前置,在制品包构造编译的时候,乃至开发人员code代码的时候就对外部引用、内部公共库进行漏洞扫描,一旦匹配到高危漏洞,直接把提交或构建终端。如果一定要继续构建,那么可以将扫描结果记录到制品的元数据中,供测试人员,运维人员查看。目前JFrog Xray等安全扫描故居提供此类能力。也可以使用开源软件,如cvechecker,在编译流水线中对包进行扫描,防止由于安全漏洞造成的整个迭代失败。

四、 后期完善

1. 设置度量体系,提升发布质量

敏捷开发模式下,开发人员和测试人员往往是汇报给同一位管理人员,出于快速迭代线上功能,往往有些团队会投机取巧、将没有测试完整的包发布到线上进行测试。该种问题的直接表现是,为了解决一个bug,可能多时间多次对同一个应用或页面进行hotfix或发布新版本。这样做是十分危险的,置线上业务稳定于不顾。为了避免此类情况发生、我们可以采用一些措施或规范来约束开发团队。例如:
上线后触发新bug数量
短时间内对相同问题发布次数
由于上线原因造成的P5-P0级别故障的数量
上线后故障恢复时间
上线后回滚的次数
非上线时间内紧急上线数量

通过收集上述数据,每月或固定周期对各个团队进行考核。并对发布状态复盘,通过制定规约,评估团队的交付质量及交付能力,挖掘团队中的发布问题及痛点,从而提高发布质量,减少线上故障率。

2. 制定度量标准,进行发布质量考核

每团队初始分为100分,每月重置,每月用此分作为迭代质量的一项标准,分数不挂钩kpi考核,只用来驱动开发团队去提高效率。
评判为两个维度:项目组发布稳定性得分、服务(站点、app、微服务等)发布质量得分
·非上线时间发布hotfix(项目组减1分,服务减1分)
·代码类hotfix,同一项目每天发布超过3次(项目组减1分,服务减2分)
·hotfix发布失败或回滚(项目组减2分,服务减2分),发布是否失败,由运维团队认定。
·数据库等脚本异常或执行失败(项目组减1分)
·每月服务发布数量(取top5,服务按排序减5到1分)
·由于hotfix原因造成P2级以上的线上事故,项目组减5分,相关服务减5分
·项目组本月hotfix量如超过前3月平均值的30%,减10分

3. 变更管理

在google的SRE体系中,变更管理是DevOps体系中最为重要的一个部分。根据以往的经验,90%的线上故障是由于线上变更导致的,该变更原因包括软件、硬件、环境等所有因素。建设变更管理体系目的就是为了快速定位线上问题,止损由于变更造成的线上故障,及时通知相关人员做好故障预防工作。所以,变更管理体系也是需要我们重点去建设以及完善的。
落地方式包括但不限于下述几点:
·运维人员、对应的开发及测试人员、产品经理等微信通知
·大屏滚动播放最近的变更记录
·变更记录同步到监控系统

五、 总结

总结为一句话,虽然在敏捷开发模式下、产品、开发、测试团队都在小步快跑,但运维必须有自己的原则,一定要对整个上线流程制定规范、对DevOps工具链进行统一管理。
线上稳定大于一切!

原文地址:https://blog.51cto.com/jfrogchina/2466775

时间: 2024-11-07 20:08:00

基于Saltstack、Artifactory打造传统模式下持续部署平台的相关文章

传统模式下WebService与WebAPI的相同与不同

1.WebService是利用HTTP管道实现了RPC的一种规范形式,放弃了对HTTP原生特征与语义的完备支持:而WebAPI是要保留HTTP原生特征与语义的同时实现RPC,但WebAPI的实现风格可以是千姿百态,RESTful只是实现了其中一种风格,你也可以定义一种风格,并实现 2.WebAPI相比WebService更为轻量级.灵活.优化好的情况下,性能更有优势,但是对复杂或大型业务的描述与使用增加了无形的成本 3.WebAPI可以更好的利用HTTP与生俱来的特征,如:缓存.代理.安全.头信

基于Shard-Jdbc分库分表模式下,数据库扩容方案

本文源码:GitHub·点这里 || GitEE·点这里 一.数据库扩容 1.业务场景 互联网项目中有很多"数据量大,业务复杂度高,需要分库分表"的业务场景. 这样分层的架构(1)上层是业务层biz,实现业务逻辑封装:(2)中间是服务层service,封装数据访问:(3)下层是数据层db,存储业务数据: 2.扩容场景和问题 当数据量持续新增,面临着这样一些需求,两台数据库无法容纳,需要数据库扩容,这里选择2台-扩容到3台的模式,如下图: 这样扩容的问题(1)分库分表的策略导致数据迁移量

持续部署平台搭建

https://gogs.io/ https://drone.io/ https://goharbor.io/ gogs+drone+harbor方式构建,不哆嗦直接上 安装docker curl -sSL https://get.daocloud.io/docker | sh curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io curl -L https:/

DevOps交付模式下,软件测试的那些事

众所周知,近10年IT领域有两个关键的风向转变,传统IT向云计算转变,传统瀑布和迭代开发模式向敏捷开发模式转变.这两个转变促成了DevOps产品交付模式的出现.互联网行业竞争激烈,许多公司专注于产品和商业模式的快速迭代创新,期望通过DevOps快速交付产品,缩短产品的上市周期.华为DevOps模式下的软件测试体系的分享主要由 “测试对象的识别.测试组织与流程的演变.测试工具与技术的应用.测试管理和自动化测试”四个领域的关键内容组成.华为云近期推出了7天玩转性能&接口测试系列课程,添加小助手微信(

Jenkins持续部署-自动生成版本号

目录 Jenkins持续部署-自动生成版本号 目录 前言 目的 详细流程 获取SVN Reversion 获取需求号 设置编译前读取版本号 总结 参考文献 Jenkins持续部署-自动生成版本号 目录 Jenkins持续集成学习-Windows环境进行.Net开发1 Jenkins持续集成学习-Windows环境进行.Net开发2 Jenkins持续集成学习-Windows环境进行.Net开发3 Jenkins持续集成学习-Windows环境进行.Net开发4 Jenkins持续集成学习-搭建j

传统企业如何打造统一的持续集成平台

一.传统行业打造统一持续集成平台痛点 多团队维护多套工具链,重复任务多.运维成本高. 各团队交付流程不统一么,重复造轮子,知识经验无法共享. 各交付质量.标准不统一,难以形成统一的度量体系. 二.从零到一的解决方案 1.成立团队该团队初期视公司技术人员规模,可由虚拟组或专属devops工程师组成.该需要具备下述能力: 对需求管理.敏捷有所了解,敏捷教练最佳. 各语言研发专家,制定静态代码检测标准,负责公司技术栈选型. 测试工程师,负责测试工具选型及集成. 运维人员对资源及部署能力及流程进行把控.

AngularJS中在前后端分离模式下实现权限控制 - 基于RBAC

权限的设计中比较常见的就是RBAC基于角色的访问控制,基本思想是,对系统操作的各种权限不是直接授予具体的用户,而是在用户集合与权限集合之间建立一个角色集合.每一种角色对应一组相应的权限. 一旦用户被分配了适当的角色后,该用户就拥有此角色的所有操作权限.这样做的好处是,不必在每次创建用户时都进行分配权限的操作,只要分配用户相应的角色即可,而且角色的权限变更比用户的权限变更要少得多,这样将简化用户的权限管理,减少系统的开销. 在Angular构建的单页面应用中,要实现这样的架构我们需要额外多做一些事

基于KWIC 的关键字匹配算法(管道+过滤器模式下实现)

下面是基于KWIC 的关键字匹配算法(管道+过滤器模式下实现) 关键部分的管道+过滤器 软件体系下的实现, 在很多的关键字搜索平台都使用了这一 循环移位+排序输出的 关键字匹配算法: 具体需求如下: 1.使用管道-过滤器风格: 每个过滤器处理数据,然后将结果送至下一个过滤器,.要有数据传入,过滤器即开始工作.过滤器之间的数据共享被严格限制在管道传输 四个过滤器: 输入(Input filter): 从数据源读取输入文件,解析格式,将行写入输出管道 移位(CircularShifter filte

MVC模式下基于SSH三大框架的java web项目excel表格的导出(不依赖另外的jar包)

最近工作中碰到了需要将web页面的表格内容导出到excel表格并下载到本地的需求.以下是在利用网上资源.与同事探讨下,完成的代码. 首先我们需要有定义好的实体类.以下是截取了项目中用到的部分代码. 1 public class QyggDocuments implements java.io.Serializable { 2 3 private static final long serialVersionUID = -2543382529255041149L; 4 5 private Stri