持续交付

持续交付

灵雀云获邀加入CDF(持续交付基金会),成为中国区三大创始成员之一

灵雀云 发表了文章 • 0 个评论 • 498 次浏览 • 2019-03-14 10:55 • 来自相关话题

3月12日,在加州Half Moon Bay举行的开源领导者峰会(Open Leadership Summit 2019 )上,CDF(Continuous Delivery Foundation )持续交付基金会正式宣告成立。灵雀云以全球首批创始成员身份获邀 ...查看全部
3月12日,在加州Half Moon Bay举行的开源领导者峰会(Open Leadership Summit 2019 )上,CDF(Continuous Delivery Foundation )持续交付基金会正式宣告成立。灵雀云以全球首批创始成员身份获邀加入,也是中国区三大创始成员之一,另外两家为华为和阿里。



CDF.png




CDF基金会隶属于Linux基金会,Linux基金会是一个通过开源实现大规模创新的非营利组织,为多样化的持续集成和交付(CI / CD)领域奠定了新的基础。CDF基金会将作为一个中立的家园,为最重要的开源项目提供持续交付和规范,以加快发布流程。

CDF创始成员包括灵雀云、阿里巴巴、Anchore、Armory.io、Atos、Autodesk、Capital One、CircleCI、CloudBees、DeployHub、GitLab、Google、HSBC、华为、IBM、JFrog、Netflix、Puppet、Rancher、Red Hat、SAP、Snyk和SumoLogic等。


640.jpg



入驻CDF基金会的第一批项目将包括Jenkins、Jenkins X、Spinnaker以及Tekton。其他项目将通过即将成立的技术监督委员会(TOC)加入CDF基金会,其重点是将CD持续交付生态系统整合在一起,以围绕可移植性和源代码库建立规范和项目。

CDF基金会将促进行业顶级开发人员,最终用户和供应商之间的协作,以传播CI / CD方法论,定义/记录最佳实践,并创建培训材料,以使全球任何软件开发团队能够实施CI / CD最佳实践。

灵雀云是以容器技术为基础的新一代PaaS平台领军企业,是国内推动云原生落地的重要力量。围绕应用的全生命周期管理,帮助企业客户快速构建云原生应用,实现微服务架构改造及 DevOps 落地。在云原生DevOps领域,灵雀云致力于打造开放式的DevOps工具链集成与编排平台。平台可以灵活兼容客户的工具选型,通过集成将各类工具串联起来,形成一套工具链,通过编排实现DevOps工具链与容器平台联动,形成一个完整系统。同时,不断结合自身的经验,提炼DevOps落地最佳实践,将最佳实践自动化,作为服务进行输出。



灵雀云CTO陈恺表示:“寻求持续创新的现代组织需要高度自动化、灵活性和一致性的软件交付流程。我们很高兴看到CDF基金会的成立。它将培育一个充满活力的社区,促进文化转变、方法论、最佳实践以及工具链生态的建设,使组织能够持续地交付价值。我们期待为这一使命作出贡献。“

DevOps“五宗罪”,这样向DevOps过渡注定会失败

灵雀云 发表了文章 • 0 个评论 • 853 次浏览 • 2018-05-31 11:19 • 来自相关话题

云计算提供的速度响应、敏捷性和规模效应,契合了如今不断变化的数字商业环境。企业基于最新的IT技术,重构IT架构,加速产品创新和服务交付的速度,从而提高运营效率和市场占有。 不过,企业IT管理者在利用云计算进行数字化转型时,往往会面临两 ...查看全部
云计算提供的速度响应、敏捷性和规模效应,契合了如今不断变化的数字商业环境。企业基于最新的IT技术,重构IT架构,加速产品创新和服务交付的速度,从而提高运营效率和市场占有。

不过,企业IT管理者在利用云计算进行数字化转型时,往往会面临两方面的挑战:一是技术,一是企业固有的流程、文化和组织架构。许多公司仍然运转于各个“信息孤岛”,陷入依赖“瀑布式”软件开发的泥潭中,这与技术本身提供的巨大灵活性背道而驰。

在数字化时代,速度和敏捷性是企业领跑和打造核心竞争力的关键。DevOps通过打破开发与运维之间的隔阂,大大缩短软件的开发周期,并快速部署到生产环境,对企业的数字化转型至关重要。

DevOps就像一座现代软件开发的圣杯。许多人都在积极寻找,有些人声称已经找到,而更多人还在寻找中。
由于每家公司都有其独特的运营方式,通往DevOps成功之路上,没有一步步的标准化指导。但是,可以肯定以下这5种方式是无法过渡到DevOps的,DevOps不应该做什么,希望本文能够给企业客户以启示。

不确定DevOps对企业的业务意味着什么

DevOps并没有严格的定义,它为什么会出现,采用DevOps可以解决什么问题,有多种解释。从2010年起,DevOps运动的创始人之一斯蒂芬·尼尔森·史密斯(StephenNelson-Smith)就发布了一篇有关DevOps的很漂亮的帖子。清楚地说明了,开发、运维和QA团队的所有成员应该就DevOps对他们各自意味着什么达成共识。回答这些问题有助于:

团队如何定义DevOps流程?应该在任何流程变化发生之前达成共识,否则会出现不必要的紧张情绪。团队要做的是开展工作,而不是花时间确定什么必须做,什么不该做。

团队成员愿意失去哪些特权?他们愿意钻研哪些任务?如果开发人员不想参与测试和基础设施维护,Ops工程师不急于开始编写代码,QA团队更喜欢手工测试,而并非编写自动化单元测试代码——这样的人将无法在一个健康的、有竞争力的DevOps团队中脱颖而出。

新成立的DevOps和其他部门之间会有什么界限?向DevOps软件交付方式的转变不可能在一夜之间发生,这需要大量的时间和资源投入。在此期间,试点DevOps的团队应该在所谓“卓越中心”的主要业务工作流程之外独立开展工作。

没有遵守DevOps文化
DevOps方法论实际上只有大约25%的比例使用了DevOps工具,诸如Ansible,Kubernetes,Salt,Puppet或Terraform等。75%的客户,他们的DevOps方法依赖于组织内部的文化变革,正如我们在另一篇文章中所描述的,“为什么说DevOps文化是人类的一大步?”。


DevOps的理念非常简单: 提供持续集成、持续交付和基础设施即代码。这意味着DevOps工程师不仅要熟练使用多个DevOps工具进行代码开发、构建、测试和部署;还应该为代码交付自动化测试,并维护生产基础设施,因此,任何有可能出现的问题,都可以由团队中的任何成员来解决掉。

成功采用DevOps范式的最后一点,是将基础设施作为代码构建,尽管是最后强调的一点,但这并不代表它不重要。当企业基础设施迁移到私有云或混合云之后,将有可能实现。当所有基础设施参数可以由每位团队成员通过轻松访问和修改文件进行配置时,就不存在瓶颈和过度的运营成本。这正好对应了“你构建,你运行”的范例,形成了DevOps方法论的核心。

从单一任务和责任到统一的团队,拥有通用的工具集和技能集,以及共同的思维方式,对于培养可行和持久的DevOps团队至关重要。最重要的一点,这不可能作为一项基层行动而发生,它必须得到企业里C-Suite和经理们的全力支持。然而,这点引起了企业内部对治理和安全的关注,应该加以解决。
无法重组组织结构和治理
向DevOps迁移的原因之一仍然是,在企业业务中,错误的成本太高。这意味着错误的决策可能会让经理们失去他们的位置,这也是为什么他们真正抵制变化的原因。“如果它行得通的话,为什么要改变它呢?” 然而,在现代快节奏的世界里,遵循传统惯例并不是很有效,因为没有按时交付价值意味着没有交付价值。

因此,为了加速软件开发,尽可能多地从交付流水线中去除管理开销。但是,不需要多个审批并不意味着不需要遵守安全和合规性限制。这仅仅意味着DevOps应该对其行为的后果负责,并且如果失控,有能力纠正错误。

正确的做法是在,DevOps团队的软件交付流水线上复制审批功能,同时将最后的消息留给管理人员。通过这种方式,管理人员可以让DevOps在软件部署和基础设施更新方面做出决策,同时根据需要,也可以取消它们。如果缺乏这种控制,整个企业的软件部署和基础架构的统一结构就可能会变成杂乱无章的混乱。

DevOps工程师只有开发出稳定的和能够检验错误的工作流程,使所有更新顺利进行,DevOps才可以自行开展工作。任务和职责的这种渐进式过渡,应该发生在整个企业中。这有助于建立一支强大自信的团队,自主展开工作,同时遵守安全和治理法规。
无法评估风险
持续交付、自动化测试、持续集成,构建不可变基础设施即代码—DevOps这些诸多优势都将会大大缩短上市时间和反馈循环。但是,如果出现差错,同样的行为会导致重大损失。因此,DevOps工程师应该接受培训,尽可能地移除错误产生的因素。


这通常意味着自动化测试过程,俗话说:“如果可以自动化,就必须自动化”。软件交付最近的阶段如果出现错误,那么成本对业务来说是相当高的,这会给 QA 和 DevOps 团队带来消极影响和倦怠状态。


为了避免这种结果,最好在DevOps中投入大量的精力来编写自动化单元测试,并锻炼使用Ansible和Terraform等配置管理工具,掌握Docker技能,实现快速部署测试和环境搭建,发布滚动更新,并在需要时快速回滚到以前的版本。从而降低风险,并提供稳定、不间断的服务。
无法提供可测量的统计数据
任何企业的核心目标都是一样的:赚取利润。因此,对企业来说,每一个变化首先应该是可行的,并得到高管们的认可。虽然 DevOps 有助于加快服务和软件交付流程,但它应该满足某些KPI,从而证明其实施的合理性。


这些 KPI 将根据行业、传统基础设施的状况以及其他因素有所不同,但有一点是一样的:DevOps的采用应该解决问题并证明切实的结果。为了达到这些结果,管理层应审核整个企业使用的遗留基础设施,系统和流程的状态。从而确定效率和性能的大致水平,例如,从新特性的发布到发布这项功能的天数等。


一旦确定了上面这些参数,衡量成功就变得相当简单了。不过,这不是一个月、两个月就能达成的任务,部署全面的DevOps模型需要一年之久,这取决于企业的规模和重组工作流所需的工作量。密切关注DevOps团队的表现,并将其与常规团队进行比较,有助于评估向DevOps过渡的进展和效率。
结论
向DevOps过渡绝不是一时之功就能实现。它需要打好基础,获得企业整个管理层的支持,投入大量的时间和资源。这一转型的结果通常会给企业带来切实的好处,正如Puppet关于DevOps的报告所论述过的。



本文抛砖引玉,如果你有DevOps方面的任何见解,欢迎后台留言与我们交流~~

新一代 CI 持续集成工具 flow.ci 正式开源

flowci持续集成 发表了文章 • 0 个评论 • 1698 次浏览 • 2017-12-06 12:07 • 来自相关话题

很高兴地宣布 flow.ci 在 Apache-2.0 协议下正式开源了。flow.ci 是国内首套开源持续集成(CI) 解决方案,帮助企业团队实现开发流程(build-test-deploy)自动化,快速持续交付高质量软件。 官方网 ...查看全部
很高兴地宣布 flow.ci 在 Apache-2.0 协议下正式开源了。flow.ci 是国内首套开源持续集成(CI) 解决方案,帮助企业团队实现开发流程(build-test-deploy)自动化,快速持续交付高质量软件。

官方网站:https://flow.ci
>开源地址:https://github.com/flowci



以此,你可以将功能完整的 flow.ci 持续集成服务部署到内网使用。在使用过程中有任何 bug 反馈或功能建议,可直接在 github 提 issues,或者通过 pull request 贡献代码。

关于 flow.ci 新特性

# 支持 Docker 一键部署,分分钟创建一套CI系统
flow.ci 在 Docker Hub 上提供了最新的镜像,用户可以方便地获取 Docker 镜像,快速启动 Agent.具体文档请查看 FlowCI/docker.

# 支持 YML 配置文件,快速创建工作流
flow.ci 支持通过配置 yml 方式创建工作流,我们提供了iOS & Android 项目的 yml 模板,用户可自行调整配置 Agent 工作环境&参数,构建环境&参数等,具体可参考文档:FlowCI/templates.

#几行脚本,极速上传 fir.im
在 yml 工作流中配置以下脚本(基于Docker),可一步生成 fir.im 应用短链接,快速进行应用内测。

```
  • name: fir_publish
script: | array=$(find ${IOS_IPA_DIR} -name *.ipa 2>&1) for file in ${array[@]} do fir publish $file done```# 新设计 UI/UE,只为简单高效在「产品功能」和「流程界面」上,flow.ci 拥有全新的 UI/UE,使用上更加简单高效。### 1.一个界面,聚合常用功能,全面把控构建任务
  • 可快速搜索、创建、切换 Flow
  • 查看 Agent 构建状态
  • 查看构建历史记录
  • 查看构建详情(日志)
### 2.管理员控制台可轻松管理所有配置这些配置包括,Flow 管理、Agent 管理、成员管理、证书管理、消息通知管理、插件管理等等。# 全新技术栈,保证高效稳定构建flow.ci 开源版采用了全新的技术栈,更看重「构建效率」「高可用」「扩展性」。
  • 基于 Java 语言编写,在效率、性能、稳定性、跨平台有着很好的平衡性
  • 采用 ZooKeeper 分布式服务框架 ,调度 Agent 任务更佳灵活
  • 支持 Docker 一键部署,简化部署流程
  • 使用 React.js 前端框架,性能优越
# 强大灵活的插件系统flow.ci 的每个 flow 由插件和触发器构成,根据不同的语言和环境提供对应的丰富的插件,更加灵活。
  • 完全可视化的插件操作
  • 插件样式可自定义
  • 更佳适应脚本爱好者
P.S.更多的插件,正在准备中… flow.ci Roadmap未来 flow.ci 将上线以下功能:
  • 插件系统,支持自定义脚本/ 自定义CSS
  • Pipeline,多 Job 串并联与容器云平台集成
  • 产物存储,统一管理历史存档
  • 数据统计分析,构建成功率分析并形成报表等
  • 日志分析,精准定位构建失败的原因
  • 与 IDE 集成
  • ……


以上功能已加入 flow.ci Roadmap,如果你有其他功能需求请在 github 提 issues,或通过 pull request 的方式参与 flow.ci 迭代开发。


结语
我们希望通过 flow.ci 的开源,能够惠及更多的企业级开发者,让他们不再因为配置复杂度而对 CI 产生畏惧;同时希望聚集社区力量,做符合国情的、好用的 CI 工具。

感谢支持 :)


--

flow.ci 团队

快速指南:在DevOps中实现持续交付

望出扶风 发表了文章 • 0 个评论 • 2736 次浏览 • 2017-09-05 22:30 • 来自相关话题

【编者的话】时至今日,以几乎相同的步调实现开发与交付已经成为一种必需。本份快速指南将帮助大家弄了解持续交付概念中的那些“良方”与“毒药”。 【烧脑式Kubernetes实战训练营】本次培训理论结合实践,主要包括:Kubernetes架 ...查看全部
【编者的话】时至今日,以几乎相同的步调实现开发与交付已经成为一种必需。本份快速指南将帮助大家弄了解持续交付概念中的那些“良方”与“毒药”。

【烧脑式Kubernetes实战训练营】本次培训理论结合实践,主要包括:Kubernetes架构和资源调度原理、Kubernetes DNS与服务发现、基于Kubernetes和Jenkins的持续部署方案 、Kubernetes网络部署实践、监控、日志、Kubernetes与云原生应用、在CentOS中部署Kubernetes集群、Kubernetes中的容器设计模式、开发Kubernetes原生应用步骤介绍等。

开发人员总是面临着软件发布规模与速度层面的种种压力,而这亦促使其采用各类新型概念和工具。但是,令人困惑的术语混淆了真正的技术和商业利益,特别是考虑到供应商也拥有自己的倾向与诉求。如果您需要的是真正的技术手段而非营销口号,大家往往会发现自己很难为持续构建与交付的实现找到最佳方法。本文将为大家带来与持续交付相关的基础知识,希望能够为各位带来一点启示。

首先,以下术语适用于同一生产流程的不同部分,而各个部分的自动化程度皆不尽相同。

* 持续集成(Continuous integration)是指频繁将代码合并至中央储存库中。“频繁”通常具体指一天多次。每次合并操作都会触发一个自动化的“构建与测试”实例,这一过程也会被称为持续构建。但是无论具体表达如何,持续集成和持续构建都无法直接实现交付和部署方面的工作——其只负责代码层面的管理,而不涉及其它具体事务。

* 持续交付(Continuous delivery)是指软件交付过程中的自动化机制,其中包括一部分需要开发人员亲自动手的操作。通常来讲,开发人员都会允许和启用自动部署,不过同时也会配合其他一些手动的步骤。

* 持续部署(Continuous deployment)是指不需要开发人员以手动方式操作的持续交付机制。整个流程皆自动实现,而不需要人为参与。

Marko Anastasov在一篇博文中解释称,利用持续部署,“开发人员的工作通常集中在检查同事们提交的合并请求,并在将其合并到主分支上后即宣告完成。”持续集成/持续部署服务在这里接管后续工作,包括运行一切测试案例并将代码部署到生产环境中,而后通知相关团队每一个重要事件的对应结果。

然而,仅仅了解术语和它们的定义并不能帮助大家确定应在何时、何地对其加以运用——毕竟每种技术都拥有着自己的优势与劣势。

当然,如果市场能像对待DevOps一样清楚地区分这些概念、工具及其对应受众,自然可以带来完美的成效。然而……

“DevOps是一种概念,一个想法,一类生活哲学。”软件交付自动化厂商XebiaLabs公司首席营销官Gottfried Sehringer指出。“这并非一种特定工序或者工具集,也不是一种技术。”

遗憾的是,行业里的术语很少配有简单明了的表述,也没有提示能够告诉人们如何以及何时使用这些技术。因此,这份指南旨在帮助大家了解何时适合使用哪种技术。
#根据你对速度的需求来选择加速方案
等等,速度难道不是所有软件开发的关键吗?现如今,公司通常都会要求开发人员每天,每周或是每月进行软件更新或者添加新的功能。这在过去,甚至在敏捷开发时代下都是闻所未闻的严苛要求。

不止于此,一些公司还会追求更快的软件更新速度。Sehringer说:“如果你在亚马逊工作,那很可能每几秒钟就需要进行一次更新。”

不论你是软件漏洞的行家,或是开发人员又或是运维专家,当必须快速完成构建与发布任务时,大家该如何提供高质量且“不破坏任何既有成果”的代码呢?面对这样的问题,每个人都有自己的妙招。“敏捷开发”,“持续构建”和“持续集成”则是其中呼声最高的三种方案。

下面让我们对其进行概括说明。

软件服务供应商Nexient公司资深交付主管Nate Berent-Spillson指出,“你可以把持续性看成是‘自动化’。它降低了开发和部署的成本与时间。”

那为什么不直接使用自动化作为专业表达?

自动化概念的加入、持续构建、持续交付以及任何与持续性相关的因素,都属于DevOps的核心范畴,而我们其实陷入了文字表述的误区。下面,我们将带大家共同理清思路。
#自动化DevOps的三要素
持续构建的本质在于“通过小步骤进行构建。”每个小的步骤都是为了把软件以持续性方式集成到生产环境中这一目标而服务。

尽管部分实践者会对“持续集成”概念作出进一步细分,但“持续集成”这一标签仍常常被指向同一类事物。持续构建属于持续集成的组成部分:在持续构建的过程中,开发者只需编写代码,并将其与仓库中现有的代码合并,之后就可以让自动化来接管构建和测试合并后的代码。这样开发者将不必浪费时间在手动编译和测试上,而是把更多时间投入到代码编写与创新实现身上。

但是,仅仅利用部分自动化工具并不意味着能够提升整个发布流程的速度表现。毕竟代码本身还没有部署完成——而部署工作可能需要手动操作,也可能因为开发人员忙不过来而被推迟。

作为OutSystems(面向企业的移动和网页应用的快速交付平台)公司的首席技术布道者,Dan Juengst解释说:“随着持续集成的运用,组织能够从以笨重的整体式应用(monolithic application)为核心的思维模式升级到一种能够支持并鼓励轻量化且高频度软件更新的方案。”

然而,在更大规模的持续集成过程中,与其说持续集成是一个独立的步骤,不如将它看成是一种并行的步骤。InfoZen公司首席转型官Susan W.Sparks说:“不同于仅仅提供了一种可持续且低风险代码部署方案的持续交付机制,持续构建在持续集成当中负责定期合并新代码并实施构建。”

正如Sparks所言:“通过持续集成,你也可以实现持续交付。”当然,前提条件是大家的代码具备可部署性。

另外,大家还需要把创新团队放在首位。前雅虎首席技术官,现任Cybic首席技术官的Mike Kail说:“将DevOps落地的第一步通常就是采用持续集成。这为开发人员提供了更加协调的环境,有利于提高代码质量。”
#何时使用持续集成vs.应用程序的自动化发布
那么持续集成是否就是应用的自动化发布(ARA)——这两种称为是否代表着同一事物?答案是否定的,正如Sparks所言:“它们是同一框架下的两种不同组件。”

持续集成的运用集中体现在使用公共源代码库(如GitHub)的应用开发人员上。Sparks说,每当开发人员更新软件时,他们的代码都将被重新整合到整个应用中。换句话说,持续集成工具检查所有的源代码,构建所有成果(例如编译软件),运行所有的单元测试,同时立即作出结果反馈。

另一方面,应用的自动化发布是指对集成后的代码进行打包,并在开发结束后将代码自动转移。

Sparks说:“举个例子,开发始于代码。当实现了所有功能并通过了所有测试之后,你就可以利用应用程序自动化发布来将代码包移动到下一个环境,例如测试环境。”

从另一个角度来看,就像Sehringer说的:“持续集成是内容,而应用的自动化发布则是运用工具的过程,二者属于同一事物的不同侧面。”
#冲洗。重复、重复、重复、重复(DevOps中的自动化)
自动化机制拥有理想的投资回报。Sehringer指出:“如果在前期制作阶段能够确保产品的万无一失,那你就能立即把它推向生产而不破坏任何原有成果,之后只要重复这一过程就可以了。”

换句话说,您可以通过结构化、可重复的自动化方式来实现所有的交付步骤,从而降低风险并提高发布和更新的速度。

“在最理想的情况下,你只需按下一个按钮,就可以做到每几秒钟就进行一次发布。”Sehringer说。“但现实世界没那么理想化,还是需要人工插手来把整个流程对接起来。”

公司可能需要法务部门的批准才能对应用做修改。Sehringer指出:“一些受到严格监管的公司甚至需要额外的手段来确保合规性。因此,了解瓶颈的具体所在是很重要的。”ARA软件应该提高效率,并确保应用能够按时发布或更新。

Sehringer 还说:“开发人员对持续集成更为熟悉,而应用的自动化发布则属于较新的概念,也因此导致理解程度普遍不高。”
#整合,而后加以尝试
首先,要了解你的承诺、风险在哪里以及目标是什么。

Berent-Spillson表示:“持续构建、持续集成和持续交付只能算是基本底限,持续部署才是更为深入的步骤。”

他补充称:“利用持续部署,您可以承诺在不需要人工参与的情况下来部署每一行新代码,而不再以人为方式一次性将代码发布出去。当新代码提交到存储库时,其将自动接受构建、集成、测试和暂存(stage)。其中的核心变在于对主线开发作出的承诺。”

这些概念的差异之处表现为自动化程度的区别,但它们都适用于一套更为宏观的开发框架。整个流程可以总结为:首先进行持续集成,而后是持续交付或持续部署。我们可以把持续部署看作是持续交付的升级版。但是在集成、构建和测试完成之前,不会有任何代码被实际部署——这就是为什么我们要将持续集成放在首位。

专家们对于把这些概念付诸实践的最佳建议是从小处着手,然后在每一次迭代中作出小范围改进。最终,大家将不再专注于单个问题,而是构建起一套能够通过自动化机制实现速度与安全性保障的架构。

Berent-Spillson的建议是,“从持续构建开始,然后提交给自动化测试(测试金字塔),并开始进行持续集成。随着你对持续集成的效果愈发满意,同时不断改进你的自动化部署方案,最终需要确保回滚的无缝化实现能力。”

他解释称,因为回滚难度有所下降,这种方法将使得持续部署变得更容易。“在遇到错误的时候,大家可以进行回滚,然后问自己,‘我们能够如何利用自动化、感知化或测试手段来防止这一问题的发生?’”
#给领导者们的经验教训

* 如果您所做的只是持续构建和持续集成,那么您很有可能会造成瓶颈并减缓整个部署过程。我们的目标是实现频繁发布,这意味着您需要更高水平的自动化机制以更快地进行版本发布。
* 在每次迭代中进行部分自动化或改进,直到您最终达到全面自动化。大家可以列出一张清单或一张图表,从而确保相当努力能帮助自身朝着目标稳步前进。
* 在持续集成之后,使用持续交付。只有在解决了持续交付中的合规性与管理问题、并且能够实现无缝回滚之后,您才可以进一步尝试持续部署。持续部署应是软件发布当中人为介入程度最低的自动化阶段。

原文链接:The quickie guide to continuous delivery in DevOps (翻译:马申君)

===========================================
译者介绍
马申君,代尔夫特理工大学计算机专业的研究生,研究方向是云资源的弹性伸缩和workflow的调度。

持续部署的发展之路

精灵云 发表了文章 • 0 个评论 • 1408 次浏览 • 2017-09-05 17:50 • 来自相关话题

我们无数次听到这类的抱怨:管理层不会去做、代码太过混乱、项目太大、有太多的监管障碍。由此种种,对于许多企业来说,在持续集成/持续部署的道路已步履蹒跚,但不得不说,仍有一部分企业做到了。 以Michiel Rook在2016 年的D ...查看全部
我们无数次听到这类的抱怨:管理层不会去做、代码太过混乱、项目太大、有太多的监管障碍。由此种种,对于许多企业来说,在持续集成/持续部署的道路已步履蹒跚,但不得不说,仍有一部分企业做到了。

以Michiel Rook在2016 年的DevOps大会上的演讲为例,一起来看看关于持续部署的发展之旅。他们的项目被称为“San Diego Project”,但他们公司内部却被称为“大泥球”,因为它的代码库相当地混乱。

下图是实施持续部署前的状态:

1.jpg



该项目的压力很大。皆来源于它纯手动发布,脆弱的测试,频繁的宕机以及问题不断。这个项目团队大约由16人组成,但他们对修改现有代码并没有什么信心。

他们知道需要做什么,所以他们设定了以下目标:

 减少问题
 减少周期时间
 提高生产效率
 提高积极性

他们采取的方法是:整体修改,建立一个代理并添加一个服务,然后不断地增加服务,直到这个整体被取代。


2.jpg



他们以如下原则来指导这次持续部署之旅:

 应用strangler模式
 使用API的第一个方法
 为每个domain设置一个服务
 迁移单个页面
 建立负载平衡器后的服务
 访问遗留数据库
 实施持续部署
 运用docker
 开发前端作为服务

从持续集成开始:开发和构建/测试,每次都产生一个工件。持续交付:从构建/测试到验收再到生产; 进入生产阶段是一个手动的过程,但代码是可部署的。最后,当整个流程实现自动化时,就达到持续部署的目标了。

关于持续部署的优点有以下几点:

 小步推进
 早期反馈
 减少循环时间
 风险减低
 实验室环境


3.jpg



Michiel的项目落地后,他总结了几个实现持续部署的关键方面,如下:

 直接提交到Master。没有分支。我们都不希望延迟集成,且滥用版本控制功能分离。另外,分支上的所有内容都会增加冲突和延迟集成的风险。
 每一次提交都要投入生产。
 使用配对编码进行代码审查。这需要约束,但所有的开发人员都需要成对进行,混合搭配有经验的开发人员。
 严把质量关。确保大量测试和代码覆盖率。
 功能切换和A/B Test。确保一部分开发人员可以看到版本信息,一部分人不能看到,并促进A / B测试。但一定要把人员数量保持在一个合理的范围内。
 Dashboards。显示是部署的关键,通过它我们可以获取很多信息,比如KPI、构建时间、页面加载时间、访问者数量、A/B Test结果,等等。
 DevOps。心态是一种文化;dev和ops之间并无太多隔阂。团队内部都拥有所有权,但这并不意味着每个人都知道所有事。
 自动化可重复的事。如果同样的事你需要做两次,那说明你已经浪费了时间。
 连续测试。使用单元测试和冒烟测试来查看服务是否存在,并持续监控。探索性的测试很重要,因为你将继续测试最关键的路径。


4.jpg



 管道作为代码。自动化流水线。最后,部署起来是这样的:

5.jpg



 反馈 –及时的反馈很重要,因为DevOps是在此基础之上建立的。举个例子,Michiel这个项目上有一个闪烁的红光,这表示失败。所以不管什么时候,及时反馈都是工作中的第一要事。

Michiel的项目时间跨度有一年之久。最终,他们将每个服务的构建时间减少到不到10分钟,显著改善了页面加载时间,同时他们自己也增加了自信心和加快了速度等。明白了团队需要接受和改变的重要性的真理。同时,他们还了解到,与业务优先级一致是关键,确保拥有一定工作经验的员工亦是至关重要,限制功能切换同样至关紧要。

总的来说,Michiel和他的团队实现了持续部署。在他的演讲结束时,Michiel也提到了他的无奈,想要取代的遗留系统仍在服务中。所以持续部署这条路还很长,但值得去做。


推荐阅读:
如何为微服务选择正确的数据库
为什么你的DevOps会失败?


关于Ghostcloud
Ghostcloud(中文名:精灵云)坐落于成都天府软件园,是成都高新区重点扶持企业,国内首批从事容器虚拟化研发的企业,是西南地区唯一一家基于Docker的云计算服务商,为企业级行业客户提供针对互联网化、私有云管理平台、大数据业务基础架构的平台服务。
Ghostcloud因容器技术而生,以最新容器技术Docker为基础,为适应不同行业客户需求,全自主研发了一套调度引擎框架Newben,且全方位适配Kubernetes主流开源调度引擎,也是国内率先实现双调度引擎的企业,是一流的企业级容器云服务专家。Ghostcloud推出了企业级容器云PaaS/CaaS平台,命名为EcOS(EnterpriseContainer Operation System)。Ghostcloud将EcOS平台与微服务/DevOps相融合,运用至企业IT系统的全生命周期的开发、测试、运维及发布流程中,致力于为多个领域企业向“互联网+”转型提供针对互联网化、私有云管理平台、大数据业务基础架构的平台服务,帮助企业级客户降低成本、提升效率、简化运维及产品部署,并提升系统的可靠性和安全性。

Kubernetes之健康检查与服务依赖处理

张夏 发表了文章 • 0 个评论 • 6541 次浏览 • 2017-08-13 23:09 • 来自相关话题

【编者的话】对线上业务来说,保证服务的正常稳定是重中之重,对故障服务的及时处理避免影响业务以及快速恢复一直是开发运维的难点。Kubernetes提供了健康检查服务,对于检测到故障服务会被及时自动下线,以及通过重启服务的方式使服务自动恢复。而对于服务依赖,无论资 ...查看全部
【编者的话】对线上业务来说,保证服务的正常稳定是重中之重,对故障服务的及时处理避免影响业务以及快速恢复一直是开发运维的难点。Kubernetes提供了健康检查服务,对于检测到故障服务会被及时自动下线,以及通过重启服务的方式使服务自动恢复。而对于服务依赖,无论资源描述文件是pod, rc或deployment, 对应yaml文件中描述仅是container启动顺序而非Container中服务启动顺序,Kubernetes提供了的Init Container,可处理服务之间依赖。

【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:持续集成与持续交付(CI/CD)概览;持续集成系统介绍;客户端与服务端的 CI/CD 实践;开发流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及实践经验分享等。

简单例子说明什么是健康检查以及服务依赖,比如一个应用分别有A、B、 C 3个服务,健康检查就是如何确定A、B与C所在的Container处于运行状态且服务工作正常;而对于服务依赖,假设服务A必须在服务B成功启动之前启动,而服务B必须在服务C成功启动之前启动,即启动顺序为A->B->C。
#健康检查
k8s_healthcheck.png

##使用Liveness及Readness探针

  • Liveness探针:主要用于判断Container是否处于运行状态,比如当服务crash或者死锁等情况发生时,kubelet会kill掉Container, 然后根据其设置的restart policy进行相应操作(可能会在本机重新启动Container,或者因为设置Kubernetes QoS,本机没有资源情况下会被分发的其他机器上重新启动)。
  • Readness探针:主要用于判断服务是否已经正常工作,如果服务没有加载完成或工作异常,服务所在的Pod的IP地址会从服务的endpoints中被移除,也就是说,当服务没有ready时,会将其从服务的load balancer中移除,不会再接受或响应任何请求。
##探针处理Handler类型无论对于Readness或Liveness探针,Handler均支持以下3种类型:ExecAction, TCPSocketAction, HTTPGetAction。每种类型说明与举例如下:ExecAction:Container内部执行某个具体的命令,例子。TCPSocketAction:通过container的IP、port执行tcp进行检查, 例子。HTTPGetAction: 通过container的IP、port、path,用HTTP Get请求进行检查,例子。##探针检查结果探针检查结果分为3种情况:[list=1]
  • 成功(Success):通过检查。
  • 失败(Failure):检查失败。
  • 未知(Unknown):检查未知,需要人工干预。
  • ##健康检查总结
    探针类型          说明                                 通过健康检查标准 ExecAction       container内部执行shell命令            shell命令返回0TCPSocketAction  通过container的IP、port执行tcp进行检查  port是否打开HTTPGetAction    通过container的IP、port、path,       200<=返回值<400                     用HTTP Get请求进行检查
    ##服务可用性与自动恢复 1. 如果服务的健康检查(readiness)失败,故障的服务实例从service endpoint中下线,外部请求将不会再转发到该服务上,一定程度上保证正在提供的服务的正确性,如果服务自我恢复了(比如网络问题),会自动重新加入service endpoint对外提供服务。[list=1]
  • 另外,如果设置了Container(liveness)的探针,对故障服务的Container(liveness)的探针同样会失败,container会被kill掉,并根据原设置的container重启策略,系统倾向于在其原所在的机器上重启该container、或其他机器重新创建一个pod。
  • 由于上面的机制,整个服务实现了自身可用与自动恢复。
  • ##使用建议:[list=1]
  • 建议对全部服务同时设置服务(readiness)和Container(liveness)的健康检查
  • 通过TCP对端口检查形式(TCPSocketAction),仅适用于端口已关闭或进程停止情况。因为即使服务异常,只要端口是打开状态,健康检查仍然是通过的。
  • 基于第二点,一般建议用ExecAction自定义健康检查逻辑,或采用HTTP Get请求进行检查(HTTPGetAction)。
  • 无论采用哪种类型的探针,一般建议设置检查服务(readiness)的时间短于检查Container(liveness)的时间,也可以将检查服务(readiness)的探针与Container(liveness)的探针设置为一致。目的是故障服务先下线,如果过一段时间还无法自动恢复,那么根据重启策略,重启该container、或其他机器重新创建一个pod恢复故障服务。
  • #服务依赖##理解Init Container一个pod中可以有一或多个Init Container。Pod的中多个Init Container启动顺序为yaml文件中的描述顺序,且串行方式启动,下一个Init/app Container必须等待上一个Init Container完成后方可启动。例如,Init Container1-> ... -> Init Containern -> app Container[1-n]。Init Container1成功启动并且完成后,后续的Init Container和app Container才可以启动,如Init Container启动或执行相关检查失败,后续的init Container和应用Container将不会被执行启动命令。因此可利用Init Container来判断app Container中被依赖的服务是否成功启动。如被依赖的app Container服务启动失败,那么利用Init Container启动失败可以阻止后续app Container服务的启动。由于Init Container必须要在pod状态变为Ready之前完成,所以其不需要readiness探针。另外在资源的requests与limits上与普通Container有细微差别,详见 Resources,除以上2点外,Init Container与普通Container并无明显区别。##Init Containers用途[list=1]
  • 前文已经提及,由于Init Container必须在app Containers启动之前完成,所以可利用其特性,用作服务依赖处理。比如某一个服务A,需依赖db或memcached,那么可以利用服务A pod的Init Container判断db/memcached是否正常提供服务,如果启动服务失败或工作异常,设置Init Container启动失败,那么pod中的服务A就不会被启动了。
  • 应用镜像因安全原因等没办法安装或运行的工具,可放到Init Container中运行。另外,Init Container独立于业务服务,与业务无关的工具如sed, awk, python, dig等也可以按需放到Init Container之中。最后,Init Container也可以被授权访问应用Container无权访问的内容。

  • ##Init Container处理服务依赖应用举例
    serviceA服务依赖serviceB,而serviceB采用上文提及Readness探针的HTTPGetAction Handler。
    spec:
      initContainers:
      - name: init-serviceA
        image: registry.docker.dev.fwmrm.net/busybox:latest
      command: ['sh', '-c', "curl --connect-timeout 3 --max-time 5 --retry 10 --retry-delay 5 --retry-max-time 60 serviceB:portB/pathB/"]
      containers:

    如果启动serviceA Pod时,serviceB还没有ready,通过kubectl get po -o wide查看pod处于Init状态
    NAME                        READY     STATUS    RESTARTS   AGE       IP          .l  NODE
    serviceA-3071943788-8x27q 0/1 Init:0/1 0 20s 10.244.1.172 bjo-ep-svc-017.dev.fwmrm.net

    通过kubectl describe po serviceA-3071943788-g03wt查看,可以看出app Container的启动时在init Container启动并成功完成后:
    Events:
    FirstSeen LastSeen Count From SubObjectPath Type Reason Message
    --------- -------- ----- ---- ------------- -------- ------ -------
    25s 25s 1 default-scheduler Normal ScheduledSuccessfully assigned serviceA-3071943788-g03wt to bjo-ep-dep-040.dev.fwmrm.net
    25s 25s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net Normal SuccessfulMountVolume MountVolume.SetUp succeeded for volume "serviceA-config-volume"
    25s 25s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net Normal SuccessfulMountVolume MountVolume.SetUp succeeded for volume "default-token-2c9j1"
    24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Pulling pulling image "registry.docker.dev.fwmrm.net/ui-search-solr-data:latest"
    24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "registry.docker.dev.fwmrm.net/busybox:latest"
    24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Created Created container
    24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Started Started container
    20s 20s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Pulling pulling image "registry.docker.dev.fwmrm.net/infra/is:latest"
    20s 20s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Pulled Successfully pulled image "registry.docker.dev.fwmrm.net/infra/is:latest"
    20s 20s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Created Created container
    19s 19s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Started Started container

    查看docker Container log,init Container正在按照预先的设定,每3秒轮询验证serviceB健康检查点serviceB:portB/pathB/
    docker logs 4fd58bf54f76
    waiting for serviceB service
    waiting for serviceB service
    ... ...


    等待一段时间后,再次通过kubectl get po -o wide查看pod处于Running状态
    NAME                        READY     STATUS    RESTARTS   AGE       IP          .l  NODE
    serviceA-3071943788-g03wt 1/1 Running 0 1m 10.244.2.68 bjo-ep-dep-040.dev.fwmrm.net


    如果pod重启了,所有init Container都需重新运行。Kubernetes禁止Init Container使用readiness探针,可以使用Pod定义 activeDeadlineSeconds 和 Container的 livenessProbe 防止 init containers 一直重复失败. activeDeadlineSeconds 包含了 init container 启动的时间。

    ##参考资料
    Container Lifecycle Hooks: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/
    Attach Handlers to Container Lifecycle Events: https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/
    Init Containers: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
    Init Container and Probe: https://blog.giantswarm.io/wait-for-it-using-readiness-probes-for-service-dependencies-in-kubernetes/
    Configure Pod Initialisation: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container
    Debug Init Containers: https://kubernetes.io/docs/tasks/debug-application-cluster/debug-init-containers/
    Delaying the deployment of our stubborn service: https://blog.giantswarm.io/wait-for-it-using-readiness-probes-for-service-dependencies-in-kubernetes/

    欢迎转载,请注明作者出处:张夏,FreeWheel Lead Engineer,DockOne社区

    持续交付的实践与思考

    尼古拉斯 发表了文章 • 0 个评论 • 2222 次浏览 • 2017-07-26 08:31 • 来自相关话题

    【编者的话】一直以来都在做团队里的基础性工作,直到最近,成果开始慢慢展现,尤其是上周刚看完《持续交付》这本书后,总结已经做的工作,又有了些新的感悟。 【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于D ...查看全部
    【编者的话】一直以来都在做团队里的基础性工作,直到最近,成果开始慢慢展现,尤其是上周刚看完《持续交付》这本书后,总结已经做的工作,又有了些新的感悟。

    【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:持续集成与持续交付(CI/CD)概览;持续集成系统介绍;客户端与服务端的 CI/CD 实践;开发流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及实践经验分享等。

    过去一段时间,我都是围绕着 Gitlab 的一些功能来开展的,从最开的代码与应用配置管理,然后到 CI 系统,提升代码质量,到最后完整的持续交付流程提升团队工作效率。

    那么我就结合《持续交付》这本书的内容,正文开始。
    #为什么要有持续交付

    1. 不敢发布新功能:每次发布都会心惊胆战,因为一下子发布了太多功能,测试又没做好,而这时候产品催着要上线。另外按照以往的经验,由发布而出问题的的概率最高;
    2. 线上事故处理时间长:每次出线上事故,不能很快定位问题,如果是由于同事线上改动了什么,就更难定位问题了,而在之后大家可能会狠狠责怪那个同事,事实上,他也很无辜,因为没有人告诉他什么能做,什么不能做,或者该怎么做;
    3. 发布周期太长:由于每次功能完全开发完之后才会发布上线,而如果涉及到数据库更改或者迁移,发布周期可能会拖得太长;
    4. 协作问题:比如新人来到团队时,由于被限制了各种线上的权限,尤其是发布权限,会导致很多工作开展不顺利,而每次发布求助于其他同事的话,会造成沟通问题,进一步造成了协作上的问题。另一个,往往由于习惯于口头上说下要发布了,然后发布过程对其他人而言是不可见的,若是线上还需要操作些什么的话,几乎对其他人是更不可见的;

    #持续交付能做到什么

    1. 让软件构建、部署、测试和发布过程对所有人可见:由此,大家可以学习过程,了解其他人做了什么,在一个规范的流程中工作,促进协作;
    2. 改善反馈,更早发现问题:在一个完整的流水线中,可以设置多个『检查点』,简答来说,就是加入多个测试环节,保证代码质量,而在这个过程中,越早发现问题,修复的成本越低;
    3. 通过一个完全自动化的过程在任意环境上部署和发布软件的任意版本:在陈浩大神的 《从 Gitlab 误删除数据库想到的》 这篇文章里,提到: 人管代码,代码管机器,其实持续交付就能达到这个效果。并且在一种极端情况下,假如你使用的云服务商挂了,你也能在其它云服务商上面快速重建你的整个线上系统(当然,没那么简单)。

    #持续交付的几个原则

    1. 为软件发布创建一个可重复且可靠的过程:一键发布与回滚,如果发布出了问题,你几乎可以确定不是发布脚本本身的问题,因为这个脚本已经经过多次检验;
    2. 将几乎所有的事情自动化:手工发布及漫长又不可靠,采用自动化脚本,节省时间,节省精力;
    3. 把所有的东西纳入版本控制:采用变更管理,方便审计,将所有的变更都在掌控之中,出问题可以快速定位问题;
    4. 提交并频繁做让你感到痛苦的事情:小步快走,分散痛苦与风险;
    5. 提高内建质量:越早发现问题,修复成本越低,等 QA 或者用户告诉你应用有问题的时候,修复成本非常高,也增加了你计划外的工作;
    6. 『Done』意味着『已发布』:没有完成百分之多少这种说法,反推着你将任务分解,将功能尽快发布到生成环境中去,减少了产品反馈时间,提高了竞争力,也减少了风险;
    7. 交付是每个成员的责任:流程标准,每个人都可以参与到流程的每一个部分,促进协作,也帮助新人适应与提高;
    8. 持续改进:不断演进,改善发布流程,这个流程需要持续的改进,提高吞吐,增加产量,提高质量;

    #持续交付的实践
    在目前的团队持续交付流程中,我们在每个环节的实践如下:

    1. 提交:单元测试 Mocha/AVA,以及测试覆盖率 nyc;
    2. 编译打包:即打包 Docker 镜像,推送到 Registry ,目前还没有完全引入 Docker 集群,因此部署过程省略;
    3. 部署文档:用 Ansible 脚本自动将 API 文档以及测试覆盖情况部署至静态网页文档服务器,这个时候可以直接将分支对应的文档给客户端开发,还可以直接查看测试覆盖率情况,确认与改进单元测试;
    4. Review:即提交 Merge Request,大家一起 Code Review;
    5. 部署应用:需要 Review 通过后,将代码合并至 master 分支,然后手工点击按钮部署;
    6. 回滚:假如应用出问题,可以点击按钮一键回滚;

    可以看到,目前主要是缺失预发布环境,这一步还需要将环境搭建脚本完善之后才能做到,而目前公司运维团队还是与我们开发团队分离的,因此达到相要的效果还是得做些努力。
    #总结
    目前我已经做到:将应用配置单独管理起来,以及部署相关的脚本都已经实现,因此才能很快地将持续交付流程跑起来。其实可以这么说:应用配置管理与自动部署脚本是持续交付流程的前提与基础。

    而持续交付流程一旦完善了,能极大改善我们开发团队的交付能力,甚至倒逼产品与运维团队提高他们的效率:

    * 对于产品团队,我们能要求他们将需求拆分尽可能的细,一旦开发完成我们能快速部署,于是他们能更快得到反馈,从而提高产品的试错能力。
    * 对于运维团队,我们已经将部署流程优化了,于是他们能更专心于基础设置的维护与改善,同时也可以促进协作,推行全面的配置管理。

    #Reference

    * https://about.gitlab.com/direction/
    * https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/
    * https://github.com/everpeace/concourse-gitlab-flow
    * https://docs.gitlab.com/ce/ci/environments.html
    * https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/

    原文链接:持续交付的实践与思考

    fir.im 持续集成技术实践

    flowci持续集成 发表了文章 • 0 个评论 • 1743 次浏览 • 2017-05-11 16:59 • 来自相关话题

    互联网时代,人人都在追求产品的快速响应、快速迭代和快速验证。不论是创业团队还是大中型企业,都在探索属于自己的敏捷开发、持续交付之道。fir.im 团队也在全面实施敏捷,并推出新持续集成服务— flow.ci ,以帮助企业将开发测试流程自动化,更快速地交付产品。 ...查看全部
    互联网时代,人人都在追求产品的快速响应、快速迭代和快速验证。不论是创业团队还是大中型企业,都在探索属于自己的敏捷开发、持续交付之道。fir.im 团队也在全面实施敏捷,并推出新持续集成服务— flow.ci ,以帮助企业将开发测试流程自动化,更快速地交付产品。

    4月15日,fir.im CTO 郭扬在“光环国际·2017敏捷春季峰会”带来了《敏捷工程实践的基石——持续集成》的技术实践,从敏捷方法论的角度分享了持续集成流程的质量实践与 fir.im 团队的 CI 技术实践。演讲实录整理如下,希望能带给你一些思考。




    郭扬,fir.im CTO,曾就职于奔驰戴姆勒创新实验室,Thoughtworks,索尼移动通信,网易等公司,担任 DevLead,负责组建技术团队,管理项目进度与项目风险,软件及 DevOps 的架构设计、高并发条件下的性能调优、敏捷教练等工作。



    # 持续集成做什么
    持续集成的概念出现在 2001 年,它其实是一个 XP 极限编程的工程实践。那么持续的是什么,集成是什么呢,非常简单就是“一直不停地集成代码”。

    持续集成是把代码频繁的合并到主干,通过自动构建的方式验证软件的质量,让团队快速的响应质量,快速的修复问题,快速的给客户解决问题,快速地交付更好的软件质量。

    # 我们为什么要做持续集成

    开发人员对下面的软件开发场景很熟悉,比如:

    • 场景一:开发了新功能,老功能产生新的 bug;
    • 场景二:修好一个 bug,又产生其他 bug,甚至出现连环 bug;
    • 场景三:出现的 bug 比较多,修改代码要很谨慎,不熟悉的模块一般不敢动,怕引起问题;
    持续集成是如何缓解这个问题,Martin Fowler 大师曾经说过:

    “Continuous Integration doesn’t get rid of bugs, but it does make them dramatically easier to find and remove.” — Martin Fowler

    如上面所说,持续集成不能消除 bug ,但能更容易地发现 bug,更快速地修复,提升产品质量。那么,持续集成能给我们带来哪些价值?从这张图上可以看到,持续集成形成一个完美的闭环。通过持续的集成进行不断地检查、调整,同时,项目的透明性也得到了最大的体现。# fir.im 如何进行持续集成实践这是一个常见的持续集成流水线:在日常的开发过程中,程序员在本地提交代码,持续集成流水线要求先做一次本地集成,在本地进行验证后提交到源代码管理仓库中,之后源代码工具会发出 webhook 触发到持续集成系统中。当构建/测试完成后,会及时通过钉钉或邮件通知团队(测试/研发/boss/产品经理)集成状态,产品经理或项目经理收到通知后会在测试环境做验收测试,这是一个比较完美的反馈环。假如测试通过验收完毕后,持续集成系统会自动触发部署到类生产环节或测试环境,或由专人手动部署到生产环境。## 为什么要做本地集成首先,代码在远程进行管理,每个人都会提交代码,远程的代码仓库会产生变化,所以在本地集成的时候要求进行代码合并,以免出现分支冲突和代码冲突。其次,不要依赖于持续集成系统给你结果,可能需要 30 分钟的时间,不要让开发人员等待,一定要先做本地集成。## 如何做版本提交再说一个提交的问题,我们尽量保证每一次提交都是一个完整的提交,也就是原子提交。

    当代码变动你想创建提交时,这个提交应该尽可能的小量,并且包含一个不可分割的特性(feature)、修复(fix)或优化(improved)。

    拿每个产品开发都会遇到的 login 功能开发举例,当填完的用户名和密码传到数据库,做完验证后给用户返回一个结果。那什么是一个原子提交?比如,提交验证一个用户名,这是一个完整的 feature ;验证密码是否符合格式(6位/8位),这也是一个完整的 feature ;当我验证完用户名和密码后再传到数据库之后,查询正确与否,这也是一个完整的 feature ;保证每次提交是一个完整的 feature 或修复了一个 bug,不要代码写成半截。## 持续集成系统这里讲的是狭义的持续集成系统,通常的 CI 系统收到提交之后会触发构建,构建会有信息返回比如 commit id 、commit 信息、代码变更等,收到代码提交后会触发自动构建,接着安装依赖进行编译,并触发质量保证流程,也就是说自动化测试集。自动化测试集包括代码静态检查-单元测试-集成测试-验收测试-性能测试,也会有压力测试、回归测试、monkey test等等一系列的测试。 接下来,我们具体讲一下 fir.im 团队如何进行持续集成实践的。## fir.im 的敏捷环境fir.im 是一个内测分发平台,我们也做了一个持续集成 CI 产品-flow.ci。先来看一下我们正在使用的敏捷环境:
    • Trello 看板;
    • 三个环境(类生产环境,测试环境,生产环境);
    • CI 工具(Jenkins/flow.ci
    ## 说一下 Git 分支管理我们在应用 3 个分支 —— master/develop/feature 分支,对 feature 命名会有一些要求,持续集成系统一定会反馈到 trello 的 kanban 里,所以对于 feature 分支我们也有这样的命名 feature/fci-{card number} 以方便区分。多分支如何做频繁地持续集成?master 分支,即线上分支。线上通常会有一些 hotfix, 任何产品都不可能避免线上的 bug ,这些 bug 需要在 master 分支进行修复,修复完成后持续集成系统会告知已上线,收到团队反馈,这些代码会要求更新在 develop 分支上,之后所有团队也会收到相关通知,那么 feature 分支会有变化吗?答案是肯定的,因为频繁的集成可以防止代码偏离。这就是我们多分支构建的策略。还有一个策略——不同的分支不同的构建,持续集成系统跑完整个流程会很长,所以在 feature 分支频繁度会比在本地构建要高一些,但是也没有那么高。为了保证持续集成系统能快速地收到反馈,需要在 feature 分支上做一些定制的 workflow ,所以我们做了代码静态分析和单元测试。当 feature 分支的 card 做完之后(scrum 中 done 的含义是指测试验收完毕),集成到 develop 分支,develop 分支会自动部署到测试环境,会跑一个整个自动化测试集,为什么是这样的构建策略呢?

    我们会做代码 review ,当 feature 分支提 pr 到 develop 分支上,这样 develop 分支的构建条件是:当收到 pr 之后,开始跑持续集成。假如部署完成整个测试跑过了产品经理验收之后,没毛病了,终于可以发布了到 master 分支。

    整个团队的构建频率可以看下这张图:本地集成的频率非常高,远程构建对应的是 feature 分支,会相对低一下。QA 环境对应的是 develop 分支的构建粒度。这样的构建每天都会产生,所以做完之后不要积压,一定要保持上线节奏。kanban + scrum 结合的方式构成我们每日构建,这是一个整体的构建策略和上线频率。## fir.im 的持续集成系统演变过程罗马不是一天建成的,持续集成不是一开始就是完美的。每个开发者心中都有一个比较理想的自动化工作流——持续部署,大概会经历这几个演变阶段:
    • 最初阶段:提交代码-自动部署;
    • 一般进阶:提交代码-代码静态分析-自动部署,最简单先再加入代码静态分析;
    • 高级进阶:提交代码-代码静态分析-自动化测试集-自动部署;
    这是我们在用的自动化测试集,下面分别说下静态检查分析、单元测试、验收测试、性能测试的具体用途。### Step 1. 静态代码分析每个公司都会有自己的代码规范,代码静态分析工具能够保证代码质量,现成的工具有 java 的 FindBugs,ruby 的 rubocop 等。利用代码检查工具可以帮助团队发现可重构的地方,输出产出 – HTML 报告,也会发现潜在 bug;有的代码检查工具还会检查出一些安全漏洞。这三点是代码静态分析最重要的作用。这里也分享一个 GitHub 地址,列出一些主流语言的代码分析工具,可以参考一下。### Step 2. “单元测试”这里的 “单元测试”也加上了集成测试,毕竟创业公司要求资源最大化。程序员一定要写单元测试,要克服开发的惯性思维,不要甩锅。下面有一些注意的点和大家分享:
    • 测试异常——不仅仅测试正确情况,也要主动测试异常;
    • 减少耦合——保证独立的可测试性;
    • 功能分离——单元测试流太长,超过 20 分钟的话要详细想一下如何将功能单独拆开,效率更高;
    • 测试=需求——从测试代码看到每个 class 是干什么的,同时出现 bug 时,第一时间是看测试,想想如何从测试中复现;

    ### Step 3. 验收测试

    验收测试是端对端的测试,从收到用户名密码到返回结果,是不是我们所期望的一个值,这是验收 Acceptance Test,其实是验收了整个功能。代码静态检查和单元测试,保证了我们如何怎么去写代码,验收测试保证了写正确代码,符合开发需求。

    flow.ci 做验收测试比较多,用的是比较流行的框架 Cucumber + Selenium WebDriver,目前支持 3 种数据库,5 种 git 仓库,7 种 开发语言跑在 docker 容器云上,支持 iOS 构建跑在 mac 机器上,要保证这些排列组合正常运行,这是 flow.ci 做验收测试最核心的价值。



    其实,持续集成是一个工作流,当 push 代码的时候才会 run 起来,但是 flow.ci 本身系统也有外部依赖的特殊性,会依赖一些第三方的 sevice(比如 GitHub/GitLab 等),验收测试应该一直保持不断地运行,也可以叫持续测试吧。因为我们永远不能保证第三方的 api 会不会改变:)

    ### Step 4. 性能测试

    我们的性能测试做的比较简单,主要测试 api.因为 fir.im 做 app 的内测分发,我们需要性能测试保证 app 上传下载的正常稳定。性能测试是单用户的,压力测试是多用户的,这是两者之间的区别。

    性能测试会有一些不确定性,有很多系统会产生缓存。flow.ci 的性能测试跑在 docker 上,是一个干净独立的环境,需要让系统预热运行一下。Locust/JMeter/LoadRunner是目前比较流行的性能测试工具。
    flow.ci 目前用的是 locust,可以参考一下。


    ## 持续集成的可视化、数据分析

    我们认为一个好的持续集成系统也要做到项目进度的透明化,最传统的方式是发送相关的邮件,但实质上有几个人去看呢?为此我们采购了一个大的屏幕来解决这个问题,用来时刻提醒团队的某个构建结果。当然也可以用闪烁灯或音频的方式。




    说到数据统计分析,整个 ci 流程跑下来产生的很多数据也非常有挖掘的价值。比如,对于代码静态分析有多少 Offence、Risk、Bug,对于单元测试有失败率、测试覆盖率;对于验收测试或性能测试有多少的失败率,这些数据都有可能成为衡量一个程序员的标准。



    ## 结语
    CI 就像盖楼房的脚手架一样,没有脚手架就没办法盖出一个足够高的楼,没有 CI 就无法交付质量足够好的软件!

    欢迎分享你的观点。

    ___
    P.S.想要现场 slide 的同学,请扫码下图关注公众号flow_ci,并回复关键词「ci实践」即可获得 :)

    案例分享〡三拾众筹持续交付开发流程支撑创新业务

    163cloud 发表了文章 • 0 个评论 • 1974 次浏览 • 2017-02-10 10:58 • 来自相关话题

    本文来自三拾众筹系统架构师陈晓辉的演讲,题为“持续交付开发流程支撑创新业务”,介绍了三拾众筹基于网易蜂巢的系统开发实践。现将分享内容整理如下: 三拾众筹项目介绍 三拾众筹是一个创新型的业务,我们的理想是做不一 ...查看全部
    本文来自三拾众筹系统架构师陈晓辉的演讲,题为“持续交付开发流程支撑创新业务”,介绍了三拾众筹基于网易蜂巢的系统开发实践。现将分享内容整理如下:

    三拾众筹项目介绍

    三拾众筹是一个创新型的业务,我们的理想是做不一样的众筹平台:

    1. 基于内容产品提供众筹服务
    2. 专注探寻最有创意的想法、最有温度的故事
    3. 深耕影视、游戏、音乐、传媒、动漫等泛文娱领域

    1.png


    从2016年7月份项目筹备以来,经过两个多月的开发,10月份平台正式上线运营。目前的团队规模不大,属于内部创业的状态,但是我们的口号是:再小的力量,也能掷地回响。

    2.jpg


    今天的分享是从技术角度介绍一下我们如何构建这个持续开发的流程,来支撑我们的创新业务。

    在运行一个创新业务的时候,我们的技术会面临很大的挑战,这和我们创新业务的特点是相关的:

    1. 业务是快速变更的,不可能想好所有的事情才开始启动我们的项目,所以刚开始的时候,所谓的创新更多的是在试错。我们希望项目在做的时候,不断地收集反馈,不断地调整方向,最终找到突破点。而在不断调整方向的过程中,技术必须做到及时响应。当业务需要技术提供弹药的时候,技术不能说我们还在调研,我们还在建厂房,功能不能变更。
    2. 业务爆发式地增长。前面我们说去找方向,那什么是正确的方向,其实很难去判断,但是至少我们不是为了维持某种状态去做的,因为我们是一个从无到有的过程。一旦我们找到了正确的方向,接下来业务就会出现一个提升或者扩张,但是时间是无法预期的,往往是爆发式的,很难线性地去判断。但是对于技术来讲,如何能够不拖业务爆发的后腿,是一个棘手的问题。当业务有很大流量导入的时候,我们的系统不能撑不住,挂了。
    3. 资源成本投入。所有的创新项目资源都是有限的,如果资源很多,往往就没有了创新的土壤。资源不多就必须将有限的资源用在刀刃上。

    3.png


    面对这三项挑战,我们的技术团队必须具备三项技术能力:

    1. 快速迭代:产品要快速交付,快速部署。
    2. 可扩展:系统能够通过横向扩展的方式,支撑更大的流量。
    3. 技术有按需的能力,只扩展应该扩展的模块。

    这让我们这个创业团队想要借助云的力量,借助网易云容器平台的力量。

    对于云来讲,按需的能力是天然的,在网易云上,我们是按需按时分配的;而快速迭代和可扩展,是云的潜力,使得我们不需要采购机器,安装系统,部署环境。

    那三拾众筹如何才能发挥云的潜力,如何设计我们的系统,使用什么样的开发过程,才能让云真正的帮助我们的业务?

    这里有一个重要的概念,就是 Cloud Native。之前有人翻译为云原生应用,我觉得比较直白,我起了一个小清新的名字,叫做向云而生。

    这表示我们的应用应该设计为面向云和容器平台去应用的。

    #设计目标

    - 使用标准化流程自动配置(declarativeformats for setup automation),从而使新的开发者花费最少的学习成本加入这个项目。

    - 和操作系统之间尽可能地划清界限,在各个系统中提供最大的可移植性。

    - 适合部署在现代的云计算平台,从而在服务器和系统管理方面节省资源。

    - 将开发环境和生产环境的差异降至最低,并使用持续交付实施敏捷开发。

    - 可以在工具、架构和开发流程不发生明显变化的前提下实现扩展。

    #另外还有12原则

    三拾众筹非常相信12原则,把整个系统按照12原则进行设计。

    12 Factors
    I. Codebase-One codebase tracked in revision control, many deploys
    II. Dependencies-Explicitly declare and isolate dependencies
    III. Config-Store config in the environment
    IV. Backing services-Treat backing services as attached resources
    V. Build, release, run-Strictly separate build and run stages
    VI. Processes-Execute the app as one or more stateless processes
    VII. Port binding-Export services via port binding
    VIII. Concurrency-Scale out via the process model
    IX. Disposability-Maximize robustness with fast startup and graceful shutdown
    X. Dev/prod parity-Keep development, staging, and production as similar as possible
    XI. Logs-Treat logs as event streams
    XII. Admin processes-Run admin/management tasks as one-off processes

    系统架构

    如图是三拾众筹的系统概览,也是我们当前系统的部署架构

    4.png


    三拾众筹的架构采用的是服务化的架构,是由一系列相互协同的服务组成的。服务之间有协作的过程,服务对外也提供了统一的界面。每一个服务本身有自己的存储,有自己的缓存。

    所有的服务分两个区域,也即服务分两种类型。第一是应用的服务,第二是基础服务。

    在应用服务里面,对外有一个主站服务,同时承担了 API网关的职责。它会把前台的请求分发到后台,并且根据规则进行路由。

    服务与服务之间都是通过 Restful API也即 HTTP的方式,服务之间会有明确的依赖关系,而且依赖关系的强弱在这里用实线和虚线做区分。通过这些依赖关系来构成和编排我们的服务。

    我们最初上线的平台也不是这样的,而是只有一个众筹平台。是随着功能的丰富,应对更快的变化,而逐渐拆分的,例如对于支付模块,当我们需要接入更多的支付方式,针对支付有更多的优化需求的时候,我们需要独立出一个收银台的模块,进行服务拆分。包括会员,包括订单的部分。

    为了支撑应用服务的环境,我们还有一些基础设施服务。

    比如注册中心,服务之间有自动的服务注册与服务发现的机制。我们的所有服务是通过注册中心进行相互关联的,不需要人工的编排,是可以自动地发现服务。

    我们可以通过服务的控制台去管理服务。我的服务状态是什么,对应的版本就是什么。

    每个应用都涉及到一些配置参数,如果配置参数扔在每个服务上的话,对于运维来说代价就比较高了。对于微服务架构来讲,必然需要一个集中化,可分发的配置中心,也是在基础服务中的。

    我们会使用 Git仓库作为配置的后端,通过配置中心去分发 Git仓库中的配置,同时后面我们还会提到,有一个流程来管理整个过程。

    在这个架构里,所有的组件都在容器里面。每个服务构建的结果就是镜像,在运行期就体现为容器。

    这里面的每个服务都使用的是网易云的无状态服务,除了构建服务。构建服务是从代码构建为镜像,是在我们自己的服务器上运行,也是一个容器。

    设计要点

    接下来我分享一下我们设计时的考虑及实现要点:

    #Cloud Native的设计

    1. 从设计开始,我们就隔离了基础设施和后端服务依赖,这个隔离一方面是由容器来做的,隔离了应用和服务器之间的关系。另一方面,应用层我们用了很多的框架,例如后面提到的 springboot和 springcloud,我们使用公共的开源框架和工具,把一些面向服务化,容器化的基础功能进行实现,对于应用本身不需要关心这些过程,只需要关注中间层,根据 spring的规约来进行开发。

    1. 从一开始,就把配置和代码进行分离。将配置和镜像进行分离。

    1. 对于编排的问题,通过 springcloud和 consul进行服务发现的功能,来实现服务的自动编排。

    1. 我们实现了持续集成和持续交付的开发过程,显式地分离了构建,发布,运行的整个过程。这也是今天分享的一个主题。

    #容器化的实践

    1. 广泛使用了容器,在我们看来,容器就是服务。当我们实现一个新功能的时候,首先要考虑需不需要单独拆分为一个新的服务。
    2. 通过提供一批基础镜像,来简化服务的开发,可以说是应用开发的模板
    3. 使用了网易云基础设施平台,因为他非常开放,技术导向,对程序员友好。提供了丰富的 API,通过这些 API可以实现自动化,实现自动交付。另外蜂巢提供了很多基础 PaaS服务,包含数据库,缓存,CDN,对象存储,负载均衡等,降低构建服务的难度,提高开发效率。我们几乎用了所有的 PaaS服务,使得我们不必过多关心平台层面的东西。

    #微服务基础设施

    1. 服务的注册,发现和负载均衡机制。这个机制目前是通过 spring cloud来做的。Spring cloud是一个非常完整的微服务开发的框架,他的主要作用是在应用和设施之间提供一个抽象层,让我们用一致的 API去使用不同的服务发现机制,比如基于 Java开发的 eureka,包括我们使用的 consul。

    1. 我们实现了配置中心

    1. 我们实现了服务控制台,可以查看各个服务的状态,以及获取服务状态变更的消息通知,还有对于服务端点 Endpoint本身进行管理。对于微服务架构来说,每一个服务的端点 Endpoint应该更加智能,这是和 SOA的区别。我们也是这样的,对于每一个服务,我们借助 springcloud提供的一系列管理端口,我们的服务控制台可以通过这些管理端口去控制它,包括去查看和修改某一个服务节点的配置,查看某个节点的日志,这都是可以通过服务控制台去实现的。
    2. 持续交付的过程,后面会详细描述协作流程和自动化交付的机制。

    #技术清单

    蜂巢
    • 集群和容器、镜像仓库
    • RDS、缓存
    • 负载均衡、对象存储

    服务模板
    • consul
    • spring boot/cloud
    • Rest RPC: spring mvc, feign, ribbon,(客户端的负载均衡)
    • nginx (外部 HTTP请求的转发), consul-template (配置和配置中心打通)
    • dumb-init (Docker里面运行服务的工具)

    持续集成
    • Gitlab-CE (私有代码仓库,协作流程和配置管理的入口)
    • docker、maven
    • flyway, junit, h2, mockito, spring test (持续集成的关键点是自动化的验证)

    镜像构建

    为了尽量降低服务本身和基础设施之间的关联,在构建基础镜像的时候,分成几个层次去考虑。

    1. 最里面的一层,是OS和系统工具的一层,我们是基于 Debian系统进行构建的。
    2. 应用环境的部分是和应用分离开来的,包括 JDK,consul服务发现的机制等,这里有个小工具 dumb-init,可以在一个 Docker里面实现多进程。如果在 Docker里面使用多进程会有一个比较大的坑:如果某个进程死掉,他的子进程就会变成僵尸进程,没有办法收回,导致我们关闭 Docker容器的时候是需要强制杀掉的。这对于程序需要优雅关机来说是很有问题的,Dumb-init可以解决这个问题,另外 dumb-init还可以实现信号的重写。比如有些应用是需要接收一些信号,比如 ctrl C才能结束的,为了响应 SIGINT信号,可以通过 dumb-init进行转发。
    3. 在应用层的 Dockerfile会非常简单,选择一个正确的基础镜像,然后把包打进去就可以了。

    5.png


    基于 Gitflow代码管理和协作流程

    Gitflow是一个代码管理的流程,我们基于它实现了一个协作的流程。这个协作的流程体现在我们如何去发布我们的新版本,如果修改线上的 Bug,如果进行开发,怎么集成测试,最重要的是怎么去验证,验证什么东西。整个过程都需要自动化,且都是通过 gitlab-ce提供的界面。最重要的两个界面是 Merge Request和自动化 Pipeline来做的。

    所有的问题修改,所有的提测,都是通过 gitlab-ce的 Merge Request界面进行操作的。一旦 Merge Request接受之后,都会有一个跟在后面的 Pipeline,一个持续集成或者持续发布的任务来完成后续工作,这些后续工作就是我们交付的流程。

    我们使用蜂巢的两个环境,来作为开发和测试环境以及线上环境。对于特定的环境,我们自动构建和发布之后,会自动地进行部署,对于开发人员,QA人员,甚至线上预发环境的运维人员来说,他们只需要在 Gitlab里面操作完了,相应的版本就构建上去了,这些版本都会在镜像仓库中,会对应我们的分支,会有独立的版本。我们还可以按需去部署更多的环境,去进行检验,比如线上的扩展验证。

    6.png


    如图所示,左上角为提交的 Merge Request,右面为 Merge Request的详情,如果点击 Accept Merge Request就会触发左下角的 Pipeline进行整改发布流程。

    整个交付流程如图所示:

    7.png


    1. 开发有一个主分支称为 develop,但是所有功能的开发都不在 develop上开发,而是新开分支进行开发,可以根据发布的时间点确定某个功能是不是要上线,例如图中在这一版中,feature x, y可以上线,于是 Merge到 develop分支,而 feature z赶不上这一版,会在以后的版本上线,所以暂且不 Merge到 develop分支。

    1. Feature x,y合并 develop分支需要经过 Code Review,一旦合并后,会触发自动构建镜像的 Pipeline,然后自动部署 develop环境。开发需要在这个环境里面做集成和基本的测试,包含单元测试和冒烟测试,当集成和基本的测试遇到缺陷的时候,需要回到 feature所在的分支进行缺陷修复,修复后重新 Merge到 develop,从而重新部署 develop环境。当开发任务代码质量可以达到的时候,方才提测到 QA。

    1. 有一个 Release分支用于做测试验证,提测的发起是由 develop分支 Merge到 release版本实现的。每次做 release的时候,首先会从 Master分出一个版本到 release,Master分支的版本是当前的线上版本,则 Develop Merge到 release,其实是和线上版本的一个合并,保证当前的开发版本和线上版本可以兼容。这次 Merge会触发 Pipeline构建镜像,并且自动发布 release环境, QA可以对这个环境进行自动化测试,或者手工测试,保证代码可以达到发布的质量。如果测试出现缺陷,则需要回到 feature所在的分支进行缺陷修复,修复后重新 Merge到 develop,从而重新部署 develop环境,在 develop环境测试完毕后,再次 Merge到 release,然后 QA再测试,如此反复,直到可以达到上线标准。

    1. 一个 release分支可以达到上线标准,则将 release分支合并回 master分支,这次 Merge会触发 Pipeline自动构建镜像,自动部署预发环境。线上运维人员可以对预发环境进行测试。

    1. 如果预发环境没有问题,线上运维人员可以从镜像手工部署两套线上环境中的一套,如图中 Online A和 Online B,做灰度发布,新老版本先更新其中一套环境,然后前端通过负载均衡器将请求不断的从老版环境切换到新版环境。

    1. 如果需要性能测试,性能测试人员可以手工从镜像部署一套性能测试环境进行测试。

    1. 如果线上发现缺陷,则需要从 Master上分出一个分支到 hotfix,hotfix修复完毕进行测试后需要合并到 Master分支,同时需要合并代码到 develop分支。

    配置管理

    8.png


    如图是一个配置管理的流程。

    所有的配置文件都放在代码仓库 Gitlab里面,进行代码级别的管理。

    编辑配置文件 app.properties和 app-A.properties,然后提交,通过 Merge Request提交到 Gitlab里面。

    在 Gitlab界面里面,点击 accept进行代码合并,合并后触发 webhook,调用配置中心。

    Git2Consul从 Gitlib中 pull所有的配置文件,并且将配置文件的内容通过 consul的客户端同步到 consul中。

    Profile=A的 app和 Profile=B的 app通过 consul的客户端将配置从 consul中配置到服务中,完成配置的管理。

    总结

    最后总结一下就是:

    1. 最大化利用开源工具和云端技术建立微服务和敏捷基础设施,构建 Cloud Native 应用,充分释放云的潜力。
    2. 其次,基于容器技术自动化构建、发布和配置流程,改进敏捷交付环境和产品快速迭代能力,及时有力支撑业务。目前三拾众筹基于网易蜂巢平台,从新系统设计到上线仅需1 ~ 3周;
    3. 最后,通过实践打磨的方案才能适合自己,开放性是选择云平台关键评估因素

    聊一聊基于Docker的持续构建实现

    163cloud 发表了文章 • 0 个评论 • 2623 次浏览 • 2017-02-08 17:53 • 来自相关话题

    持续集成是一种软件开发实践。在一个团队中开发人员经常会对他们的工作进行集成,这个频率通常为每人每天至少集成一次,这也就意味着一个团队每天可能会面临着多次集成。 在进行集成时,团队成员会通过自动化地构建,包括编译、发布、自动化测试, ...查看全部
    持续集成是一种软件开发实践。在一个团队中开发人员经常会对他们的工作进行集成,这个频率通常为每人每天至少集成一次,这也就意味着一个团队每天可能会面临着多次集成。

    在进行集成时,团队成员会通过自动化地构建,包括编译、发布、自动化测试,来验证。在这个过程中团队成员可以尽快地发现集成错误,使团队能够更快地开发内聚的软件。

    基于此,一般的互联网公司或者开发团队都会有自己的持续集成平台或者工具,而开源的持续集成工具如 jenkins,teamcity,gitlab ci 等都提供了持续集成的功能。

    但这些工具的使用一般都较为复杂,流程编排会比较长。

    而 Docker的存在使得持续集成摆脱了以往打通环境、资源申请、软件部署等带来的痛苦,可以更加快速方便地对既有工作成果进行持续集成。

    基于Docker的持续构建


    一般来讲,用户往往会选择对代码仓库的某一些特定分支进行持续集成,从而快速地对当前代码进行验证。

    而在持续集成中,持续地对代码进行构建是整个持续集成的基础。

    目前,大部分公司都是基于 mvn和 ant等编译打包工具来实现内部的编译构建服务。公司使用自己的 mvn等工具对仓库进行编译构建不存在任何问题,但是编译后的可执行文件分发与运行却比较复杂。

    常规的做法是通过 SCP脚本传输,或者内部开发 agent等工具用于可执行文件的部署,但这增加了软件开发部署的代价,尤其对于中小型公司,就需要自己研发部署工具。而且:

    - 在公有云平台如果要提供一个持续集成的构建服务给用户,会面临如何获取用户的可执行文件并进行运行的问题;
    - 需要部署相关环境,比如一个 tomcat应用需要安装 jdk以及环境变量,还有其他的用户依赖组件等。

    而一个基于 docker实现持续构建的平台可以很方便地解决上述问题:
    - docker通过镜像来进行分发,不仅摆脱了执行文件分发的问题,也解决了环境问题(docker不依赖于具体环境);
    - docker通过 dockerfile来进行构建,给了用户很大的编译自由,用户可以很方便地安装环境及相关软件;
    - docker运行非常快速,一台宿主机可以运行多个 docker容器。

    网易蜂巢的持续构建实现


    接下来介绍一下蜂巢的持续构建实现以及具体的使用方法。

    用户可以把代码托管在 github或者 gitlab等代码仓库,通过使用网易蜂巢的持续集成服务,实时快速地对代码进行编译和打包生成镜像。对于镜像的发布运行,用户可以在蜂巢部署镜像,也可以从蜂巢镜像仓库拉取镜像到其他支持 docker的环境进行部署。

    持续构建服务主要包括以下模块:

    - oauth2模块。用户 oauth2绑定,绑定用户身份;
    - hook模块。hook服务用于监听用户的代码 commit;
    - 构建模块。持续构建服务基于 dockerfile,用于镜像的构建;
    - 镜像仓库。镜像仓库用于镜像的存储,分布式对象存储解决文件的高可用;
    - callback回调,callback用于镜像元信息的存储;

    网易蜂巢持续构建系统设计图如下所示:

    4.jpg


    那么,如何实现整个构建的流程?用户可以登录网易蜂巢,进入镜像仓库进行以下操作:

    #第一步:创建镜像仓库


    Docker 基于镜像来进行分发,创建镜像仓库用来支持持续构建。

    镜像仓库主要用于存储镜像,网易蜂巢镜像仓库采用基于 nos的分布式对象存储,数据保持多副本,解决了磁盘坏掉导致用户镜像丢失的问题。

    如下图创建了一个 testci 1的镜像仓库用来支持持续集成。

    2.jpg


    #第二步:设置代码仓库和镜像仓库的关系


    通过 github的 api用户可以获取 github下的所有代码仓库来进行选择,可以选择在某个仓库的某一个分支或者 tag有提交的情况下触发持续构建。

    如下图,用户选择了基于 citest的 dev分支进行持续构建。

    3.jpg


    像这样,用户每次有 commit push到代码仓库都会触发相应的持续构建。

    #第三步:触发持续构建


    在相应的持续构建分支进行代码提交,从而触发持续构建。

    如下图在代码仓库中通过 git简单的增加了一个 txt文件,并提交到 github。

    1.jpg


    #第四步:代码构建


    用户把 commit代码 push到仓库后, github/gitlab会回调 hook服务;hook服务获取相应的代码 commit信息,进行过滤后,把构建任务下发到任务队列,并在最后分发的持续构建集群对镜像执行构建;在构建成功后把镜像推送到 hub.c.163.com镜像仓库。

    如下图的构建日志清晰的展示了用户的构建过程。拉取用户指定分支上的 commit,根据填写的 Dockerfile路径进行镜像构建,最后生成镜像并推送到镜像仓库。

    6.jpg


    #第五步:使用镜像进行部署


    此时,可以快速地选择蜂巢的服务部署方式对镜像进行部署,也可以直接下载镜像进行部署,以便继续对部署的容器进行持续集成相关的测试。

    如下图采用 docker pull下载镜像,通过 docker run 的方式运行镜像,然后进行后续的集成测试。

    5.jpg


    上述就是整个持续构建的基本流程,用户可以快速地在蜂巢进行代码仓库构建。

    其实,蜂巢在整个工程的开发过程中也遇到了相当多的问题,如:

    1. 网络问题。受限于 github,mvn仓库等网络限制,导致代码拉取、mvn构建等速度相对较慢。
    2. 镜像问题。镜像获取速度较慢,镜像 push较慢。
    3. 单台机器的性能受限。

    在蜂巢团队的努力下,已经很好地解决了这些难题。

    - 针对问题1:蜂巢选择了搭建代理、采用专线等方式解决了 github和 mvn仓库等网络问题。
    - 针对问题2:蜂巢周期性地同步官方镜像。如果用户的 dockerfile是基于官方的基础镜像则会被替换为蜂巢的官方镜像从而加速下载过程。同时,对于构建机器会提供镜像的缓存,加速构建。镜像 push较慢则在内网部署镜像仓库,通过专线的方式加速整个 push的过程。
    - 针对问题3:构建机器,采用集群化部署。通过 mq队列进行解耦,从而可以快速地进行水平扩展,提升构建的能力。

    作者:易庭,网易蜂巢开发工程师。

    快速指南:在DevOps中实现持续交付

    望出扶风 发表了文章 • 0 个评论 • 2736 次浏览 • 2017-09-05 22:30 • 来自相关话题

    【编者的话】时至今日,以几乎相同的步调实现开发与交付已经成为一种必需。本份快速指南将帮助大家弄了解持续交付概念中的那些“良方”与“毒药”。 【烧脑式Kubernetes实战训练营】本次培训理论结合实践,主要包括:Kubernetes架 ...查看全部
    【编者的话】时至今日,以几乎相同的步调实现开发与交付已经成为一种必需。本份快速指南将帮助大家弄了解持续交付概念中的那些“良方”与“毒药”。

    【烧脑式Kubernetes实战训练营】本次培训理论结合实践,主要包括:Kubernetes架构和资源调度原理、Kubernetes DNS与服务发现、基于Kubernetes和Jenkins的持续部署方案 、Kubernetes网络部署实践、监控、日志、Kubernetes与云原生应用、在CentOS中部署Kubernetes集群、Kubernetes中的容器设计模式、开发Kubernetes原生应用步骤介绍等。

    开发人员总是面临着软件发布规模与速度层面的种种压力,而这亦促使其采用各类新型概念和工具。但是,令人困惑的术语混淆了真正的技术和商业利益,特别是考虑到供应商也拥有自己的倾向与诉求。如果您需要的是真正的技术手段而非营销口号,大家往往会发现自己很难为持续构建与交付的实现找到最佳方法。本文将为大家带来与持续交付相关的基础知识,希望能够为各位带来一点启示。

    首先,以下术语适用于同一生产流程的不同部分,而各个部分的自动化程度皆不尽相同。

    * 持续集成(Continuous integration)是指频繁将代码合并至中央储存库中。“频繁”通常具体指一天多次。每次合并操作都会触发一个自动化的“构建与测试”实例,这一过程也会被称为持续构建。但是无论具体表达如何,持续集成和持续构建都无法直接实现交付和部署方面的工作——其只负责代码层面的管理,而不涉及其它具体事务。

    * 持续交付(Continuous delivery)是指软件交付过程中的自动化机制,其中包括一部分需要开发人员亲自动手的操作。通常来讲,开发人员都会允许和启用自动部署,不过同时也会配合其他一些手动的步骤。

    * 持续部署(Continuous deployment)是指不需要开发人员以手动方式操作的持续交付机制。整个流程皆自动实现,而不需要人为参与。

    Marko Anastasov在一篇博文中解释称,利用持续部署,“开发人员的工作通常集中在检查同事们提交的合并请求,并在将其合并到主分支上后即宣告完成。”持续集成/持续部署服务在这里接管后续工作,包括运行一切测试案例并将代码部署到生产环境中,而后通知相关团队每一个重要事件的对应结果。

    然而,仅仅了解术语和它们的定义并不能帮助大家确定应在何时、何地对其加以运用——毕竟每种技术都拥有着自己的优势与劣势。

    当然,如果市场能像对待DevOps一样清楚地区分这些概念、工具及其对应受众,自然可以带来完美的成效。然而……

    “DevOps是一种概念,一个想法,一类生活哲学。”软件交付自动化厂商XebiaLabs公司首席营销官Gottfried Sehringer指出。“这并非一种特定工序或者工具集,也不是一种技术。”

    遗憾的是,行业里的术语很少配有简单明了的表述,也没有提示能够告诉人们如何以及何时使用这些技术。因此,这份指南旨在帮助大家了解何时适合使用哪种技术。
    #根据你对速度的需求来选择加速方案
    等等,速度难道不是所有软件开发的关键吗?现如今,公司通常都会要求开发人员每天,每周或是每月进行软件更新或者添加新的功能。这在过去,甚至在敏捷开发时代下都是闻所未闻的严苛要求。

    不止于此,一些公司还会追求更快的软件更新速度。Sehringer说:“如果你在亚马逊工作,那很可能每几秒钟就需要进行一次更新。”

    不论你是软件漏洞的行家,或是开发人员又或是运维专家,当必须快速完成构建与发布任务时,大家该如何提供高质量且“不破坏任何既有成果”的代码呢?面对这样的问题,每个人都有自己的妙招。“敏捷开发”,“持续构建”和“持续集成”则是其中呼声最高的三种方案。

    下面让我们对其进行概括说明。

    软件服务供应商Nexient公司资深交付主管Nate Berent-Spillson指出,“你可以把持续性看成是‘自动化’。它降低了开发和部署的成本与时间。”

    那为什么不直接使用自动化作为专业表达?

    自动化概念的加入、持续构建、持续交付以及任何与持续性相关的因素,都属于DevOps的核心范畴,而我们其实陷入了文字表述的误区。下面,我们将带大家共同理清思路。
    #自动化DevOps的三要素
    持续构建的本质在于“通过小步骤进行构建。”每个小的步骤都是为了把软件以持续性方式集成到生产环境中这一目标而服务。

    尽管部分实践者会对“持续集成”概念作出进一步细分,但“持续集成”这一标签仍常常被指向同一类事物。持续构建属于持续集成的组成部分:在持续构建的过程中,开发者只需编写代码,并将其与仓库中现有的代码合并,之后就可以让自动化来接管构建和测试合并后的代码。这样开发者将不必浪费时间在手动编译和测试上,而是把更多时间投入到代码编写与创新实现身上。

    但是,仅仅利用部分自动化工具并不意味着能够提升整个发布流程的速度表现。毕竟代码本身还没有部署完成——而部署工作可能需要手动操作,也可能因为开发人员忙不过来而被推迟。

    作为OutSystems(面向企业的移动和网页应用的快速交付平台)公司的首席技术布道者,Dan Juengst解释说:“随着持续集成的运用,组织能够从以笨重的整体式应用(monolithic application)为核心的思维模式升级到一种能够支持并鼓励轻量化且高频度软件更新的方案。”

    然而,在更大规模的持续集成过程中,与其说持续集成是一个独立的步骤,不如将它看成是一种并行的步骤。InfoZen公司首席转型官Susan W.Sparks说:“不同于仅仅提供了一种可持续且低风险代码部署方案的持续交付机制,持续构建在持续集成当中负责定期合并新代码并实施构建。”

    正如Sparks所言:“通过持续集成,你也可以实现持续交付。”当然,前提条件是大家的代码具备可部署性。

    另外,大家还需要把创新团队放在首位。前雅虎首席技术官,现任Cybic首席技术官的Mike Kail说:“将DevOps落地的第一步通常就是采用持续集成。这为开发人员提供了更加协调的环境,有利于提高代码质量。”
    #何时使用持续集成vs.应用程序的自动化发布
    那么持续集成是否就是应用的自动化发布(ARA)——这两种称为是否代表着同一事物?答案是否定的,正如Sparks所言:“它们是同一框架下的两种不同组件。”

    持续集成的运用集中体现在使用公共源代码库(如GitHub)的应用开发人员上。Sparks说,每当开发人员更新软件时,他们的代码都将被重新整合到整个应用中。换句话说,持续集成工具检查所有的源代码,构建所有成果(例如编译软件),运行所有的单元测试,同时立即作出结果反馈。

    另一方面,应用的自动化发布是指对集成后的代码进行打包,并在开发结束后将代码自动转移。

    Sparks说:“举个例子,开发始于代码。当实现了所有功能并通过了所有测试之后,你就可以利用应用程序自动化发布来将代码包移动到下一个环境,例如测试环境。”

    从另一个角度来看,就像Sehringer说的:“持续集成是内容,而应用的自动化发布则是运用工具的过程,二者属于同一事物的不同侧面。”
    #冲洗。重复、重复、重复、重复(DevOps中的自动化)
    自动化机制拥有理想的投资回报。Sehringer指出:“如果在前期制作阶段能够确保产品的万无一失,那你就能立即把它推向生产而不破坏任何原有成果,之后只要重复这一过程就可以了。”

    换句话说,您可以通过结构化、可重复的自动化方式来实现所有的交付步骤,从而降低风险并提高发布和更新的速度。

    “在最理想的情况下,你只需按下一个按钮,就可以做到每几秒钟就进行一次发布。”Sehringer说。“但现实世界没那么理想化,还是需要人工插手来把整个流程对接起来。”

    公司可能需要法务部门的批准才能对应用做修改。Sehringer指出:“一些受到严格监管的公司甚至需要额外的手段来确保合规性。因此,了解瓶颈的具体所在是很重要的。”ARA软件应该提高效率,并确保应用能够按时发布或更新。

    Sehringer 还说:“开发人员对持续集成更为熟悉,而应用的自动化发布则属于较新的概念,也因此导致理解程度普遍不高。”
    #整合,而后加以尝试
    首先,要了解你的承诺、风险在哪里以及目标是什么。

    Berent-Spillson表示:“持续构建、持续集成和持续交付只能算是基本底限,持续部署才是更为深入的步骤。”

    他补充称:“利用持续部署,您可以承诺在不需要人工参与的情况下来部署每一行新代码,而不再以人为方式一次性将代码发布出去。当新代码提交到存储库时,其将自动接受构建、集成、测试和暂存(stage)。其中的核心变在于对主线开发作出的承诺。”

    这些概念的差异之处表现为自动化程度的区别,但它们都适用于一套更为宏观的开发框架。整个流程可以总结为:首先进行持续集成,而后是持续交付或持续部署。我们可以把持续部署看作是持续交付的升级版。但是在集成、构建和测试完成之前,不会有任何代码被实际部署——这就是为什么我们要将持续集成放在首位。

    专家们对于把这些概念付诸实践的最佳建议是从小处着手,然后在每一次迭代中作出小范围改进。最终,大家将不再专注于单个问题,而是构建起一套能够通过自动化机制实现速度与安全性保障的架构。

    Berent-Spillson的建议是,“从持续构建开始,然后提交给自动化测试(测试金字塔),并开始进行持续集成。随着你对持续集成的效果愈发满意,同时不断改进你的自动化部署方案,最终需要确保回滚的无缝化实现能力。”

    他解释称,因为回滚难度有所下降,这种方法将使得持续部署变得更容易。“在遇到错误的时候,大家可以进行回滚,然后问自己,‘我们能够如何利用自动化、感知化或测试手段来防止这一问题的发生?’”
    #给领导者们的经验教训

    * 如果您所做的只是持续构建和持续集成,那么您很有可能会造成瓶颈并减缓整个部署过程。我们的目标是实现频繁发布,这意味着您需要更高水平的自动化机制以更快地进行版本发布。
    * 在每次迭代中进行部分自动化或改进,直到您最终达到全面自动化。大家可以列出一张清单或一张图表,从而确保相当努力能帮助自身朝着目标稳步前进。
    * 在持续集成之后,使用持续交付。只有在解决了持续交付中的合规性与管理问题、并且能够实现无缝回滚之后,您才可以进一步尝试持续部署。持续部署应是软件发布当中人为介入程度最低的自动化阶段。

    原文链接:The quickie guide to continuous delivery in DevOps (翻译:马申君)

    ===========================================
    译者介绍
    马申君,代尔夫特理工大学计算机专业的研究生,研究方向是云资源的弹性伸缩和workflow的调度。

    持续交付的实践与思考

    尼古拉斯 发表了文章 • 0 个评论 • 2222 次浏览 • 2017-07-26 08:31 • 来自相关话题

    【编者的话】一直以来都在做团队里的基础性工作,直到最近,成果开始慢慢展现,尤其是上周刚看完《持续交付》这本书后,总结已经做的工作,又有了些新的感悟。 【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于D ...查看全部
    【编者的话】一直以来都在做团队里的基础性工作,直到最近,成果开始慢慢展现,尤其是上周刚看完《持续交付》这本书后,总结已经做的工作,又有了些新的感悟。

    【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:持续集成与持续交付(CI/CD)概览;持续集成系统介绍;客户端与服务端的 CI/CD 实践;开发流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及实践经验分享等。

    过去一段时间,我都是围绕着 Gitlab 的一些功能来开展的,从最开的代码与应用配置管理,然后到 CI 系统,提升代码质量,到最后完整的持续交付流程提升团队工作效率。

    那么我就结合《持续交付》这本书的内容,正文开始。
    #为什么要有持续交付

    1. 不敢发布新功能:每次发布都会心惊胆战,因为一下子发布了太多功能,测试又没做好,而这时候产品催着要上线。另外按照以往的经验,由发布而出问题的的概率最高;
    2. 线上事故处理时间长:每次出线上事故,不能很快定位问题,如果是由于同事线上改动了什么,就更难定位问题了,而在之后大家可能会狠狠责怪那个同事,事实上,他也很无辜,因为没有人告诉他什么能做,什么不能做,或者该怎么做;
    3. 发布周期太长:由于每次功能完全开发完之后才会发布上线,而如果涉及到数据库更改或者迁移,发布周期可能会拖得太长;
    4. 协作问题:比如新人来到团队时,由于被限制了各种线上的权限,尤其是发布权限,会导致很多工作开展不顺利,而每次发布求助于其他同事的话,会造成沟通问题,进一步造成了协作上的问题。另一个,往往由于习惯于口头上说下要发布了,然后发布过程对其他人而言是不可见的,若是线上还需要操作些什么的话,几乎对其他人是更不可见的;

    #持续交付能做到什么

    1. 让软件构建、部署、测试和发布过程对所有人可见:由此,大家可以学习过程,了解其他人做了什么,在一个规范的流程中工作,促进协作;
    2. 改善反馈,更早发现问题:在一个完整的流水线中,可以设置多个『检查点』,简答来说,就是加入多个测试环节,保证代码质量,而在这个过程中,越早发现问题,修复的成本越低;
    3. 通过一个完全自动化的过程在任意环境上部署和发布软件的任意版本:在陈浩大神的 《从 Gitlab 误删除数据库想到的》 这篇文章里,提到: 人管代码,代码管机器,其实持续交付就能达到这个效果。并且在一种极端情况下,假如你使用的云服务商挂了,你也能在其它云服务商上面快速重建你的整个线上系统(当然,没那么简单)。

    #持续交付的几个原则

    1. 为软件发布创建一个可重复且可靠的过程:一键发布与回滚,如果发布出了问题,你几乎可以确定不是发布脚本本身的问题,因为这个脚本已经经过多次检验;
    2. 将几乎所有的事情自动化:手工发布及漫长又不可靠,采用自动化脚本,节省时间,节省精力;
    3. 把所有的东西纳入版本控制:采用变更管理,方便审计,将所有的变更都在掌控之中,出问题可以快速定位问题;
    4. 提交并频繁做让你感到痛苦的事情:小步快走,分散痛苦与风险;
    5. 提高内建质量:越早发现问题,修复成本越低,等 QA 或者用户告诉你应用有问题的时候,修复成本非常高,也增加了你计划外的工作;
    6. 『Done』意味着『已发布』:没有完成百分之多少这种说法,反推着你将任务分解,将功能尽快发布到生成环境中去,减少了产品反馈时间,提高了竞争力,也减少了风险;
    7. 交付是每个成员的责任:流程标准,每个人都可以参与到流程的每一个部分,促进协作,也帮助新人适应与提高;
    8. 持续改进:不断演进,改善发布流程,这个流程需要持续的改进,提高吞吐,增加产量,提高质量;

    #持续交付的实践
    在目前的团队持续交付流程中,我们在每个环节的实践如下:

    1. 提交:单元测试 Mocha/AVA,以及测试覆盖率 nyc;
    2. 编译打包:即打包 Docker 镜像,推送到 Registry ,目前还没有完全引入 Docker 集群,因此部署过程省略;
    3. 部署文档:用 Ansible 脚本自动将 API 文档以及测试覆盖情况部署至静态网页文档服务器,这个时候可以直接将分支对应的文档给客户端开发,还可以直接查看测试覆盖率情况,确认与改进单元测试;
    4. Review:即提交 Merge Request,大家一起 Code Review;
    5. 部署应用:需要 Review 通过后,将代码合并至 master 分支,然后手工点击按钮部署;
    6. 回滚:假如应用出问题,可以点击按钮一键回滚;

    可以看到,目前主要是缺失预发布环境,这一步还需要将环境搭建脚本完善之后才能做到,而目前公司运维团队还是与我们开发团队分离的,因此达到相要的效果还是得做些努力。
    #总结
    目前我已经做到:将应用配置单独管理起来,以及部署相关的脚本都已经实现,因此才能很快地将持续交付流程跑起来。其实可以这么说:应用配置管理与自动部署脚本是持续交付流程的前提与基础。

    而持续交付流程一旦完善了,能极大改善我们开发团队的交付能力,甚至倒逼产品与运维团队提高他们的效率:

    * 对于产品团队,我们能要求他们将需求拆分尽可能的细,一旦开发完成我们能快速部署,于是他们能更快得到反馈,从而提高产品的试错能力。
    * 对于运维团队,我们已经将部署流程优化了,于是他们能更专心于基础设置的维护与改善,同时也可以促进协作,推行全面的配置管理。

    #Reference

    * https://about.gitlab.com/direction/
    * https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/
    * https://github.com/everpeace/concourse-gitlab-flow
    * https://docs.gitlab.com/ce/ci/environments.html
    * https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/

    原文链接:持续交付的实践与思考

    灵雀云获邀加入CDF(持续交付基金会),成为中国区三大创始成员之一

    灵雀云 发表了文章 • 0 个评论 • 498 次浏览 • 2019-03-14 10:55 • 来自相关话题

    3月12日,在加州Half Moon Bay举行的开源领导者峰会(Open Leadership Summit 2019 )上,CDF(Continuous Delivery Foundation )持续交付基金会正式宣告成立。灵雀云以全球首批创始成员身份获邀 ...查看全部
    3月12日,在加州Half Moon Bay举行的开源领导者峰会(Open Leadership Summit 2019 )上,CDF(Continuous Delivery Foundation )持续交付基金会正式宣告成立。灵雀云以全球首批创始成员身份获邀加入,也是中国区三大创始成员之一,另外两家为华为和阿里。



    CDF.png




    CDF基金会隶属于Linux基金会,Linux基金会是一个通过开源实现大规模创新的非营利组织,为多样化的持续集成和交付(CI / CD)领域奠定了新的基础。CDF基金会将作为一个中立的家园,为最重要的开源项目提供持续交付和规范,以加快发布流程。

    CDF创始成员包括灵雀云、阿里巴巴、Anchore、Armory.io、Atos、Autodesk、Capital One、CircleCI、CloudBees、DeployHub、GitLab、Google、HSBC、华为、IBM、JFrog、Netflix、Puppet、Rancher、Red Hat、SAP、Snyk和SumoLogic等。


    640.jpg



    入驻CDF基金会的第一批项目将包括Jenkins、Jenkins X、Spinnaker以及Tekton。其他项目将通过即将成立的技术监督委员会(TOC)加入CDF基金会,其重点是将CD持续交付生态系统整合在一起,以围绕可移植性和源代码库建立规范和项目。

    CDF基金会将促进行业顶级开发人员,最终用户和供应商之间的协作,以传播CI / CD方法论,定义/记录最佳实践,并创建培训材料,以使全球任何软件开发团队能够实施CI / CD最佳实践。

    灵雀云是以容器技术为基础的新一代PaaS平台领军企业,是国内推动云原生落地的重要力量。围绕应用的全生命周期管理,帮助企业客户快速构建云原生应用,实现微服务架构改造及 DevOps 落地。在云原生DevOps领域,灵雀云致力于打造开放式的DevOps工具链集成与编排平台。平台可以灵活兼容客户的工具选型,通过集成将各类工具串联起来,形成一套工具链,通过编排实现DevOps工具链与容器平台联动,形成一个完整系统。同时,不断结合自身的经验,提炼DevOps落地最佳实践,将最佳实践自动化,作为服务进行输出。



    灵雀云CTO陈恺表示:“寻求持续创新的现代组织需要高度自动化、灵活性和一致性的软件交付流程。我们很高兴看到CDF基金会的成立。它将培育一个充满活力的社区,促进文化转变、方法论、最佳实践以及工具链生态的建设,使组织能够持续地交付价值。我们期待为这一使命作出贡献。“

    DevOps“五宗罪”,这样向DevOps过渡注定会失败

    灵雀云 发表了文章 • 0 个评论 • 853 次浏览 • 2018-05-31 11:19 • 来自相关话题

    云计算提供的速度响应、敏捷性和规模效应,契合了如今不断变化的数字商业环境。企业基于最新的IT技术,重构IT架构,加速产品创新和服务交付的速度,从而提高运营效率和市场占有。 不过,企业IT管理者在利用云计算进行数字化转型时,往往会面临两 ...查看全部
    云计算提供的速度响应、敏捷性和规模效应,契合了如今不断变化的数字商业环境。企业基于最新的IT技术,重构IT架构,加速产品创新和服务交付的速度,从而提高运营效率和市场占有。

    不过,企业IT管理者在利用云计算进行数字化转型时,往往会面临两方面的挑战:一是技术,一是企业固有的流程、文化和组织架构。许多公司仍然运转于各个“信息孤岛”,陷入依赖“瀑布式”软件开发的泥潭中,这与技术本身提供的巨大灵活性背道而驰。

    在数字化时代,速度和敏捷性是企业领跑和打造核心竞争力的关键。DevOps通过打破开发与运维之间的隔阂,大大缩短软件的开发周期,并快速部署到生产环境,对企业的数字化转型至关重要。

    DevOps就像一座现代软件开发的圣杯。许多人都在积极寻找,有些人声称已经找到,而更多人还在寻找中。
    由于每家公司都有其独特的运营方式,通往DevOps成功之路上,没有一步步的标准化指导。但是,可以肯定以下这5种方式是无法过渡到DevOps的,DevOps不应该做什么,希望本文能够给企业客户以启示。

    不确定DevOps对企业的业务意味着什么

    DevOps并没有严格的定义,它为什么会出现,采用DevOps可以解决什么问题,有多种解释。从2010年起,DevOps运动的创始人之一斯蒂芬·尼尔森·史密斯(StephenNelson-Smith)就发布了一篇有关DevOps的很漂亮的帖子。清楚地说明了,开发、运维和QA团队的所有成员应该就DevOps对他们各自意味着什么达成共识。回答这些问题有助于:

    团队如何定义DevOps流程?应该在任何流程变化发生之前达成共识,否则会出现不必要的紧张情绪。团队要做的是开展工作,而不是花时间确定什么必须做,什么不该做。

    团队成员愿意失去哪些特权?他们愿意钻研哪些任务?如果开发人员不想参与测试和基础设施维护,Ops工程师不急于开始编写代码,QA团队更喜欢手工测试,而并非编写自动化单元测试代码——这样的人将无法在一个健康的、有竞争力的DevOps团队中脱颖而出。

    新成立的DevOps和其他部门之间会有什么界限?向DevOps软件交付方式的转变不可能在一夜之间发生,这需要大量的时间和资源投入。在此期间,试点DevOps的团队应该在所谓“卓越中心”的主要业务工作流程之外独立开展工作。

    没有遵守DevOps文化
    DevOps方法论实际上只有大约25%的比例使用了DevOps工具,诸如Ansible,Kubernetes,Salt,Puppet或Terraform等。75%的客户,他们的DevOps方法依赖于组织内部的文化变革,正如我们在另一篇文章中所描述的,“为什么说DevOps文化是人类的一大步?”。


    DevOps的理念非常简单: 提供持续集成、持续交付和基础设施即代码。这意味着DevOps工程师不仅要熟练使用多个DevOps工具进行代码开发、构建、测试和部署;还应该为代码交付自动化测试,并维护生产基础设施,因此,任何有可能出现的问题,都可以由团队中的任何成员来解决掉。

    成功采用DevOps范式的最后一点,是将基础设施作为代码构建,尽管是最后强调的一点,但这并不代表它不重要。当企业基础设施迁移到私有云或混合云之后,将有可能实现。当所有基础设施参数可以由每位团队成员通过轻松访问和修改文件进行配置时,就不存在瓶颈和过度的运营成本。这正好对应了“你构建,你运行”的范例,形成了DevOps方法论的核心。

    从单一任务和责任到统一的团队,拥有通用的工具集和技能集,以及共同的思维方式,对于培养可行和持久的DevOps团队至关重要。最重要的一点,这不可能作为一项基层行动而发生,它必须得到企业里C-Suite和经理们的全力支持。然而,这点引起了企业内部对治理和安全的关注,应该加以解决。
    无法重组组织结构和治理
    向DevOps迁移的原因之一仍然是,在企业业务中,错误的成本太高。这意味着错误的决策可能会让经理们失去他们的位置,这也是为什么他们真正抵制变化的原因。“如果它行得通的话,为什么要改变它呢?” 然而,在现代快节奏的世界里,遵循传统惯例并不是很有效,因为没有按时交付价值意味着没有交付价值。

    因此,为了加速软件开发,尽可能多地从交付流水线中去除管理开销。但是,不需要多个审批并不意味着不需要遵守安全和合规性限制。这仅仅意味着DevOps应该对其行为的后果负责,并且如果失控,有能力纠正错误。

    正确的做法是在,DevOps团队的软件交付流水线上复制审批功能,同时将最后的消息留给管理人员。通过这种方式,管理人员可以让DevOps在软件部署和基础设施更新方面做出决策,同时根据需要,也可以取消它们。如果缺乏这种控制,整个企业的软件部署和基础架构的统一结构就可能会变成杂乱无章的混乱。

    DevOps工程师只有开发出稳定的和能够检验错误的工作流程,使所有更新顺利进行,DevOps才可以自行开展工作。任务和职责的这种渐进式过渡,应该发生在整个企业中。这有助于建立一支强大自信的团队,自主展开工作,同时遵守安全和治理法规。
    无法评估风险
    持续交付、自动化测试、持续集成,构建不可变基础设施即代码—DevOps这些诸多优势都将会大大缩短上市时间和反馈循环。但是,如果出现差错,同样的行为会导致重大损失。因此,DevOps工程师应该接受培训,尽可能地移除错误产生的因素。


    这通常意味着自动化测试过程,俗话说:“如果可以自动化,就必须自动化”。软件交付最近的阶段如果出现错误,那么成本对业务来说是相当高的,这会给 QA 和 DevOps 团队带来消极影响和倦怠状态。


    为了避免这种结果,最好在DevOps中投入大量的精力来编写自动化单元测试,并锻炼使用Ansible和Terraform等配置管理工具,掌握Docker技能,实现快速部署测试和环境搭建,发布滚动更新,并在需要时快速回滚到以前的版本。从而降低风险,并提供稳定、不间断的服务。
    无法提供可测量的统计数据
    任何企业的核心目标都是一样的:赚取利润。因此,对企业来说,每一个变化首先应该是可行的,并得到高管们的认可。虽然 DevOps 有助于加快服务和软件交付流程,但它应该满足某些KPI,从而证明其实施的合理性。


    这些 KPI 将根据行业、传统基础设施的状况以及其他因素有所不同,但有一点是一样的:DevOps的采用应该解决问题并证明切实的结果。为了达到这些结果,管理层应审核整个企业使用的遗留基础设施,系统和流程的状态。从而确定效率和性能的大致水平,例如,从新特性的发布到发布这项功能的天数等。


    一旦确定了上面这些参数,衡量成功就变得相当简单了。不过,这不是一个月、两个月就能达成的任务,部署全面的DevOps模型需要一年之久,这取决于企业的规模和重组工作流所需的工作量。密切关注DevOps团队的表现,并将其与常规团队进行比较,有助于评估向DevOps过渡的进展和效率。
    结论
    向DevOps过渡绝不是一时之功就能实现。它需要打好基础,获得企业整个管理层的支持,投入大量的时间和资源。这一转型的结果通常会给企业带来切实的好处,正如Puppet关于DevOps的报告所论述过的。



    本文抛砖引玉,如果你有DevOps方面的任何见解,欢迎后台留言与我们交流~~

    新一代 CI 持续集成工具 flow.ci 正式开源

    flowci持续集成 发表了文章 • 0 个评论 • 1698 次浏览 • 2017-12-06 12:07 • 来自相关话题

    很高兴地宣布 flow.ci 在 Apache-2.0 协议下正式开源了。flow.ci 是国内首套开源持续集成(CI) 解决方案,帮助企业团队实现开发流程(build-test-deploy)自动化,快速持续交付高质量软件。 官方网 ...查看全部
    很高兴地宣布 flow.ci 在 Apache-2.0 协议下正式开源了。flow.ci 是国内首套开源持续集成(CI) 解决方案,帮助企业团队实现开发流程(build-test-deploy)自动化,快速持续交付高质量软件。

    官方网站:https://flow.ci
    >开源地址:https://github.com/flowci



    以此,你可以将功能完整的 flow.ci 持续集成服务部署到内网使用。在使用过程中有任何 bug 反馈或功能建议,可直接在 github 提 issues,或者通过 pull request 贡献代码。

    关于 flow.ci 新特性

    # 支持 Docker 一键部署,分分钟创建一套CI系统
    flow.ci 在 Docker Hub 上提供了最新的镜像,用户可以方便地获取 Docker 镜像,快速启动 Agent.具体文档请查看 FlowCI/docker.

    # 支持 YML 配置文件,快速创建工作流
    flow.ci 支持通过配置 yml 方式创建工作流,我们提供了iOS & Android 项目的 yml 模板,用户可自行调整配置 Agent 工作环境&参数,构建环境&参数等,具体可参考文档:FlowCI/templates.

    #几行脚本,极速上传 fir.im
    在 yml 工作流中配置以下脚本(基于Docker),可一步生成 fir.im 应用短链接,快速进行应用内测。

    ```
    • name: fir_publish
    script: | array=$(find ${IOS_IPA_DIR} -name *.ipa 2>&1) for file in ${array[@]} do fir publish $file done```# 新设计 UI/UE,只为简单高效在「产品功能」和「流程界面」上,flow.ci 拥有全新的 UI/UE,使用上更加简单高效。### 1.一个界面,聚合常用功能,全面把控构建任务
    • 可快速搜索、创建、切换 Flow
    • 查看 Agent 构建状态
    • 查看构建历史记录
    • 查看构建详情(日志)
    ### 2.管理员控制台可轻松管理所有配置这些配置包括,Flow 管理、Agent 管理、成员管理、证书管理、消息通知管理、插件管理等等。# 全新技术栈,保证高效稳定构建flow.ci 开源版采用了全新的技术栈,更看重「构建效率」「高可用」「扩展性」。
    • 基于 Java 语言编写,在效率、性能、稳定性、跨平台有着很好的平衡性
    • 采用 ZooKeeper 分布式服务框架 ,调度 Agent 任务更佳灵活
    • 支持 Docker 一键部署,简化部署流程
    • 使用 React.js 前端框架,性能优越
    # 强大灵活的插件系统flow.ci 的每个 flow 由插件和触发器构成,根据不同的语言和环境提供对应的丰富的插件,更加灵活。
    • 完全可视化的插件操作
    • 插件样式可自定义
    • 更佳适应脚本爱好者
    P.S.更多的插件,正在准备中… flow.ci Roadmap未来 flow.ci 将上线以下功能:
    • 插件系统,支持自定义脚本/ 自定义CSS
    • Pipeline,多 Job 串并联与容器云平台集成
    • 产物存储,统一管理历史存档
    • 数据统计分析,构建成功率分析并形成报表等
    • 日志分析,精准定位构建失败的原因
    • 与 IDE 集成
    • ……


    以上功能已加入 flow.ci Roadmap,如果你有其他功能需求请在 github 提 issues,或通过 pull request 的方式参与 flow.ci 迭代开发。


    结语
    我们希望通过 flow.ci 的开源,能够惠及更多的企业级开发者,让他们不再因为配置复杂度而对 CI 产生畏惧;同时希望聚集社区力量,做符合国情的、好用的 CI 工具。

    感谢支持 :)


    --

    flow.ci 团队

    快速指南:在DevOps中实现持续交付

    望出扶风 发表了文章 • 0 个评论 • 2736 次浏览 • 2017-09-05 22:30 • 来自相关话题

    【编者的话】时至今日,以几乎相同的步调实现开发与交付已经成为一种必需。本份快速指南将帮助大家弄了解持续交付概念中的那些“良方”与“毒药”。 【烧脑式Kubernetes实战训练营】本次培训理论结合实践,主要包括:Kubernetes架 ...查看全部
    【编者的话】时至今日,以几乎相同的步调实现开发与交付已经成为一种必需。本份快速指南将帮助大家弄了解持续交付概念中的那些“良方”与“毒药”。

    【烧脑式Kubernetes实战训练营】本次培训理论结合实践,主要包括:Kubernetes架构和资源调度原理、Kubernetes DNS与服务发现、基于Kubernetes和Jenkins的持续部署方案 、Kubernetes网络部署实践、监控、日志、Kubernetes与云原生应用、在CentOS中部署Kubernetes集群、Kubernetes中的容器设计模式、开发Kubernetes原生应用步骤介绍等。

    开发人员总是面临着软件发布规模与速度层面的种种压力,而这亦促使其采用各类新型概念和工具。但是,令人困惑的术语混淆了真正的技术和商业利益,特别是考虑到供应商也拥有自己的倾向与诉求。如果您需要的是真正的技术手段而非营销口号,大家往往会发现自己很难为持续构建与交付的实现找到最佳方法。本文将为大家带来与持续交付相关的基础知识,希望能够为各位带来一点启示。

    首先,以下术语适用于同一生产流程的不同部分,而各个部分的自动化程度皆不尽相同。

    * 持续集成(Continuous integration)是指频繁将代码合并至中央储存库中。“频繁”通常具体指一天多次。每次合并操作都会触发一个自动化的“构建与测试”实例,这一过程也会被称为持续构建。但是无论具体表达如何,持续集成和持续构建都无法直接实现交付和部署方面的工作——其只负责代码层面的管理,而不涉及其它具体事务。

    * 持续交付(Continuous delivery)是指软件交付过程中的自动化机制,其中包括一部分需要开发人员亲自动手的操作。通常来讲,开发人员都会允许和启用自动部署,不过同时也会配合其他一些手动的步骤。

    * 持续部署(Continuous deployment)是指不需要开发人员以手动方式操作的持续交付机制。整个流程皆自动实现,而不需要人为参与。

    Marko Anastasov在一篇博文中解释称,利用持续部署,“开发人员的工作通常集中在检查同事们提交的合并请求,并在将其合并到主分支上后即宣告完成。”持续集成/持续部署服务在这里接管后续工作,包括运行一切测试案例并将代码部署到生产环境中,而后通知相关团队每一个重要事件的对应结果。

    然而,仅仅了解术语和它们的定义并不能帮助大家确定应在何时、何地对其加以运用——毕竟每种技术都拥有着自己的优势与劣势。

    当然,如果市场能像对待DevOps一样清楚地区分这些概念、工具及其对应受众,自然可以带来完美的成效。然而……

    “DevOps是一种概念,一个想法,一类生活哲学。”软件交付自动化厂商XebiaLabs公司首席营销官Gottfried Sehringer指出。“这并非一种特定工序或者工具集,也不是一种技术。”

    遗憾的是,行业里的术语很少配有简单明了的表述,也没有提示能够告诉人们如何以及何时使用这些技术。因此,这份指南旨在帮助大家了解何时适合使用哪种技术。
    #根据你对速度的需求来选择加速方案
    等等,速度难道不是所有软件开发的关键吗?现如今,公司通常都会要求开发人员每天,每周或是每月进行软件更新或者添加新的功能。这在过去,甚至在敏捷开发时代下都是闻所未闻的严苛要求。

    不止于此,一些公司还会追求更快的软件更新速度。Sehringer说:“如果你在亚马逊工作,那很可能每几秒钟就需要进行一次更新。”

    不论你是软件漏洞的行家,或是开发人员又或是运维专家,当必须快速完成构建与发布任务时,大家该如何提供高质量且“不破坏任何既有成果”的代码呢?面对这样的问题,每个人都有自己的妙招。“敏捷开发”,“持续构建”和“持续集成”则是其中呼声最高的三种方案。

    下面让我们对其进行概括说明。

    软件服务供应商Nexient公司资深交付主管Nate Berent-Spillson指出,“你可以把持续性看成是‘自动化’。它降低了开发和部署的成本与时间。”

    那为什么不直接使用自动化作为专业表达?

    自动化概念的加入、持续构建、持续交付以及任何与持续性相关的因素,都属于DevOps的核心范畴,而我们其实陷入了文字表述的误区。下面,我们将带大家共同理清思路。
    #自动化DevOps的三要素
    持续构建的本质在于“通过小步骤进行构建。”每个小的步骤都是为了把软件以持续性方式集成到生产环境中这一目标而服务。

    尽管部分实践者会对“持续集成”概念作出进一步细分,但“持续集成”这一标签仍常常被指向同一类事物。持续构建属于持续集成的组成部分:在持续构建的过程中,开发者只需编写代码,并将其与仓库中现有的代码合并,之后就可以让自动化来接管构建和测试合并后的代码。这样开发者将不必浪费时间在手动编译和测试上,而是把更多时间投入到代码编写与创新实现身上。

    但是,仅仅利用部分自动化工具并不意味着能够提升整个发布流程的速度表现。毕竟代码本身还没有部署完成——而部署工作可能需要手动操作,也可能因为开发人员忙不过来而被推迟。

    作为OutSystems(面向企业的移动和网页应用的快速交付平台)公司的首席技术布道者,Dan Juengst解释说:“随着持续集成的运用,组织能够从以笨重的整体式应用(monolithic application)为核心的思维模式升级到一种能够支持并鼓励轻量化且高频度软件更新的方案。”

    然而,在更大规模的持续集成过程中,与其说持续集成是一个独立的步骤,不如将它看成是一种并行的步骤。InfoZen公司首席转型官Susan W.Sparks说:“不同于仅仅提供了一种可持续且低风险代码部署方案的持续交付机制,持续构建在持续集成当中负责定期合并新代码并实施构建。”

    正如Sparks所言:“通过持续集成,你也可以实现持续交付。”当然,前提条件是大家的代码具备可部署性。

    另外,大家还需要把创新团队放在首位。前雅虎首席技术官,现任Cybic首席技术官的Mike Kail说:“将DevOps落地的第一步通常就是采用持续集成。这为开发人员提供了更加协调的环境,有利于提高代码质量。”
    #何时使用持续集成vs.应用程序的自动化发布
    那么持续集成是否就是应用的自动化发布(ARA)——这两种称为是否代表着同一事物?答案是否定的,正如Sparks所言:“它们是同一框架下的两种不同组件。”

    持续集成的运用集中体现在使用公共源代码库(如GitHub)的应用开发人员上。Sparks说,每当开发人员更新软件时,他们的代码都将被重新整合到整个应用中。换句话说,持续集成工具检查所有的源代码,构建所有成果(例如编译软件),运行所有的单元测试,同时立即作出结果反馈。

    另一方面,应用的自动化发布是指对集成后的代码进行打包,并在开发结束后将代码自动转移。

    Sparks说:“举个例子,开发始于代码。当实现了所有功能并通过了所有测试之后,你就可以利用应用程序自动化发布来将代码包移动到下一个环境,例如测试环境。”

    从另一个角度来看,就像Sehringer说的:“持续集成是内容,而应用的自动化发布则是运用工具的过程,二者属于同一事物的不同侧面。”
    #冲洗。重复、重复、重复、重复(DevOps中的自动化)
    自动化机制拥有理想的投资回报。Sehringer指出:“如果在前期制作阶段能够确保产品的万无一失,那你就能立即把它推向生产而不破坏任何原有成果,之后只要重复这一过程就可以了。”

    换句话说,您可以通过结构化、可重复的自动化方式来实现所有的交付步骤,从而降低风险并提高发布和更新的速度。

    “在最理想的情况下,你只需按下一个按钮,就可以做到每几秒钟就进行一次发布。”Sehringer说。“但现实世界没那么理想化,还是需要人工插手来把整个流程对接起来。”

    公司可能需要法务部门的批准才能对应用做修改。Sehringer指出:“一些受到严格监管的公司甚至需要额外的手段来确保合规性。因此,了解瓶颈的具体所在是很重要的。”ARA软件应该提高效率,并确保应用能够按时发布或更新。

    Sehringer 还说:“开发人员对持续集成更为熟悉,而应用的自动化发布则属于较新的概念,也因此导致理解程度普遍不高。”
    #整合,而后加以尝试
    首先,要了解你的承诺、风险在哪里以及目标是什么。

    Berent-Spillson表示:“持续构建、持续集成和持续交付只能算是基本底限,持续部署才是更为深入的步骤。”

    他补充称:“利用持续部署,您可以承诺在不需要人工参与的情况下来部署每一行新代码,而不再以人为方式一次性将代码发布出去。当新代码提交到存储库时,其将自动接受构建、集成、测试和暂存(stage)。其中的核心变在于对主线开发作出的承诺。”

    这些概念的差异之处表现为自动化程度的区别,但它们都适用于一套更为宏观的开发框架。整个流程可以总结为:首先进行持续集成,而后是持续交付或持续部署。我们可以把持续部署看作是持续交付的升级版。但是在集成、构建和测试完成之前,不会有任何代码被实际部署——这就是为什么我们要将持续集成放在首位。

    专家们对于把这些概念付诸实践的最佳建议是从小处着手,然后在每一次迭代中作出小范围改进。最终,大家将不再专注于单个问题,而是构建起一套能够通过自动化机制实现速度与安全性保障的架构。

    Berent-Spillson的建议是,“从持续构建开始,然后提交给自动化测试(测试金字塔),并开始进行持续集成。随着你对持续集成的效果愈发满意,同时不断改进你的自动化部署方案,最终需要确保回滚的无缝化实现能力。”

    他解释称,因为回滚难度有所下降,这种方法将使得持续部署变得更容易。“在遇到错误的时候,大家可以进行回滚,然后问自己,‘我们能够如何利用自动化、感知化或测试手段来防止这一问题的发生?’”
    #给领导者们的经验教训

    * 如果您所做的只是持续构建和持续集成,那么您很有可能会造成瓶颈并减缓整个部署过程。我们的目标是实现频繁发布,这意味着您需要更高水平的自动化机制以更快地进行版本发布。
    * 在每次迭代中进行部分自动化或改进,直到您最终达到全面自动化。大家可以列出一张清单或一张图表,从而确保相当努力能帮助自身朝着目标稳步前进。
    * 在持续集成之后,使用持续交付。只有在解决了持续交付中的合规性与管理问题、并且能够实现无缝回滚之后,您才可以进一步尝试持续部署。持续部署应是软件发布当中人为介入程度最低的自动化阶段。

    原文链接:The quickie guide to continuous delivery in DevOps (翻译:马申君)

    ===========================================
    译者介绍
    马申君,代尔夫特理工大学计算机专业的研究生,研究方向是云资源的弹性伸缩和workflow的调度。

    持续部署的发展之路

    精灵云 发表了文章 • 0 个评论 • 1408 次浏览 • 2017-09-05 17:50 • 来自相关话题

    我们无数次听到这类的抱怨:管理层不会去做、代码太过混乱、项目太大、有太多的监管障碍。由此种种,对于许多企业来说,在持续集成/持续部署的道路已步履蹒跚,但不得不说,仍有一部分企业做到了。 以Michiel Rook在2016 年的D ...查看全部
    我们无数次听到这类的抱怨:管理层不会去做、代码太过混乱、项目太大、有太多的监管障碍。由此种种,对于许多企业来说,在持续集成/持续部署的道路已步履蹒跚,但不得不说,仍有一部分企业做到了。

    以Michiel Rook在2016 年的DevOps大会上的演讲为例,一起来看看关于持续部署的发展之旅。他们的项目被称为“San Diego Project”,但他们公司内部却被称为“大泥球”,因为它的代码库相当地混乱。

    下图是实施持续部署前的状态:

    1.jpg



    该项目的压力很大。皆来源于它纯手动发布,脆弱的测试,频繁的宕机以及问题不断。这个项目团队大约由16人组成,但他们对修改现有代码并没有什么信心。

    他们知道需要做什么,所以他们设定了以下目标:

     减少问题
     减少周期时间
     提高生产效率
     提高积极性

    他们采取的方法是:整体修改,建立一个代理并添加一个服务,然后不断地增加服务,直到这个整体被取代。


    2.jpg



    他们以如下原则来指导这次持续部署之旅:

     应用strangler模式
     使用API的第一个方法
     为每个domain设置一个服务
     迁移单个页面
     建立负载平衡器后的服务
     访问遗留数据库
     实施持续部署
     运用docker
     开发前端作为服务

    从持续集成开始:开发和构建/测试,每次都产生一个工件。持续交付:从构建/测试到验收再到生产; 进入生产阶段是一个手动的过程,但代码是可部署的。最后,当整个流程实现自动化时,就达到持续部署的目标了。

    关于持续部署的优点有以下几点:

     小步推进
     早期反馈
     减少循环时间
     风险减低
     实验室环境


    3.jpg



    Michiel的项目落地后,他总结了几个实现持续部署的关键方面,如下:

     直接提交到Master。没有分支。我们都不希望延迟集成,且滥用版本控制功能分离。另外,分支上的所有内容都会增加冲突和延迟集成的风险。
     每一次提交都要投入生产。
     使用配对编码进行代码审查。这需要约束,但所有的开发人员都需要成对进行,混合搭配有经验的开发人员。
     严把质量关。确保大量测试和代码覆盖率。
     功能切换和A/B Test。确保一部分开发人员可以看到版本信息,一部分人不能看到,并促进A / B测试。但一定要把人员数量保持在一个合理的范围内。
     Dashboards。显示是部署的关键,通过它我们可以获取很多信息,比如KPI、构建时间、页面加载时间、访问者数量、A/B Test结果,等等。
     DevOps。心态是一种文化;dev和ops之间并无太多隔阂。团队内部都拥有所有权,但这并不意味着每个人都知道所有事。
     自动化可重复的事。如果同样的事你需要做两次,那说明你已经浪费了时间。
     连续测试。使用单元测试和冒烟测试来查看服务是否存在,并持续监控。探索性的测试很重要,因为你将继续测试最关键的路径。


    4.jpg



     管道作为代码。自动化流水线。最后,部署起来是这样的:

    5.jpg



     反馈 –及时的反馈很重要,因为DevOps是在此基础之上建立的。举个例子,Michiel这个项目上有一个闪烁的红光,这表示失败。所以不管什么时候,及时反馈都是工作中的第一要事。

    Michiel的项目时间跨度有一年之久。最终,他们将每个服务的构建时间减少到不到10分钟,显著改善了页面加载时间,同时他们自己也增加了自信心和加快了速度等。明白了团队需要接受和改变的重要性的真理。同时,他们还了解到,与业务优先级一致是关键,确保拥有一定工作经验的员工亦是至关重要,限制功能切换同样至关紧要。

    总的来说,Michiel和他的团队实现了持续部署。在他的演讲结束时,Michiel也提到了他的无奈,想要取代的遗留系统仍在服务中。所以持续部署这条路还很长,但值得去做。


    推荐阅读:
    如何为微服务选择正确的数据库
    为什么你的DevOps会失败?


    关于Ghostcloud
    Ghostcloud(中文名:精灵云)坐落于成都天府软件园,是成都高新区重点扶持企业,国内首批从事容器虚拟化研发的企业,是西南地区唯一一家基于Docker的云计算服务商,为企业级行业客户提供针对互联网化、私有云管理平台、大数据业务基础架构的平台服务。
    Ghostcloud因容器技术而生,以最新容器技术Docker为基础,为适应不同行业客户需求,全自主研发了一套调度引擎框架Newben,且全方位适配Kubernetes主流开源调度引擎,也是国内率先实现双调度引擎的企业,是一流的企业级容器云服务专家。Ghostcloud推出了企业级容器云PaaS/CaaS平台,命名为EcOS(EnterpriseContainer Operation System)。Ghostcloud将EcOS平台与微服务/DevOps相融合,运用至企业IT系统的全生命周期的开发、测试、运维及发布流程中,致力于为多个领域企业向“互联网+”转型提供针对互联网化、私有云管理平台、大数据业务基础架构的平台服务,帮助企业级客户降低成本、提升效率、简化运维及产品部署,并提升系统的可靠性和安全性。

    Kubernetes之健康检查与服务依赖处理

    张夏 发表了文章 • 0 个评论 • 6541 次浏览 • 2017-08-13 23:09 • 来自相关话题

    【编者的话】对线上业务来说,保证服务的正常稳定是重中之重,对故障服务的及时处理避免影响业务以及快速恢复一直是开发运维的难点。Kubernetes提供了健康检查服务,对于检测到故障服务会被及时自动下线,以及通过重启服务的方式使服务自动恢复。而对于服务依赖,无论资 ...查看全部
    【编者的话】对线上业务来说,保证服务的正常稳定是重中之重,对故障服务的及时处理避免影响业务以及快速恢复一直是开发运维的难点。Kubernetes提供了健康检查服务,对于检测到故障服务会被及时自动下线,以及通过重启服务的方式使服务自动恢复。而对于服务依赖,无论资源描述文件是pod, rc或deployment, 对应yaml文件中描述仅是container启动顺序而非Container中服务启动顺序,Kubernetes提供了的Init Container,可处理服务之间依赖。

    【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:持续集成与持续交付(CI/CD)概览;持续集成系统介绍;客户端与服务端的 CI/CD 实践;开发流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及实践经验分享等。

    简单例子说明什么是健康检查以及服务依赖,比如一个应用分别有A、B、 C 3个服务,健康检查就是如何确定A、B与C所在的Container处于运行状态且服务工作正常;而对于服务依赖,假设服务A必须在服务B成功启动之前启动,而服务B必须在服务C成功启动之前启动,即启动顺序为A->B->C。
    #健康检查
    k8s_healthcheck.png

    ##使用Liveness及Readness探针

    • Liveness探针:主要用于判断Container是否处于运行状态,比如当服务crash或者死锁等情况发生时,kubelet会kill掉Container, 然后根据其设置的restart policy进行相应操作(可能会在本机重新启动Container,或者因为设置Kubernetes QoS,本机没有资源情况下会被分发的其他机器上重新启动)。
    • Readness探针:主要用于判断服务是否已经正常工作,如果服务没有加载完成或工作异常,服务所在的Pod的IP地址会从服务的endpoints中被移除,也就是说,当服务没有ready时,会将其从服务的load balancer中移除,不会再接受或响应任何请求。
    ##探针处理Handler类型无论对于Readness或Liveness探针,Handler均支持以下3种类型:ExecAction, TCPSocketAction, HTTPGetAction。每种类型说明与举例如下:ExecAction:Container内部执行某个具体的命令,例子。TCPSocketAction:通过container的IP、port执行tcp进行检查, 例子。HTTPGetAction: 通过container的IP、port、path,用HTTP Get请求进行检查,例子。##探针检查结果探针检查结果分为3种情况:[list=1]
  • 成功(Success):通过检查。
  • 失败(Failure):检查失败。
  • 未知(Unknown):检查未知,需要人工干预。
  • ##健康检查总结
    探针类型          说明                                 通过健康检查标准 ExecAction       container内部执行shell命令            shell命令返回0TCPSocketAction  通过container的IP、port执行tcp进行检查  port是否打开HTTPGetAction    通过container的IP、port、path,       200<=返回值<400                     用HTTP Get请求进行检查
    ##服务可用性与自动恢复 1. 如果服务的健康检查(readiness)失败,故障的服务实例从service endpoint中下线,外部请求将不会再转发到该服务上,一定程度上保证正在提供的服务的正确性,如果服务自我恢复了(比如网络问题),会自动重新加入service endpoint对外提供服务。[list=1]
  • 另外,如果设置了Container(liveness)的探针,对故障服务的Container(liveness)的探针同样会失败,container会被kill掉,并根据原设置的container重启策略,系统倾向于在其原所在的机器上重启该container、或其他机器重新创建一个pod。
  • 由于上面的机制,整个服务实现了自身可用与自动恢复。
  • ##使用建议:[list=1]
  • 建议对全部服务同时设置服务(readiness)和Container(liveness)的健康检查
  • 通过TCP对端口检查形式(TCPSocketAction),仅适用于端口已关闭或进程停止情况。因为即使服务异常,只要端口是打开状态,健康检查仍然是通过的。
  • 基于第二点,一般建议用ExecAction自定义健康检查逻辑,或采用HTTP Get请求进行检查(HTTPGetAction)。
  • 无论采用哪种类型的探针,一般建议设置检查服务(readiness)的时间短于检查Container(liveness)的时间,也可以将检查服务(readiness)的探针与Container(liveness)的探针设置为一致。目的是故障服务先下线,如果过一段时间还无法自动恢复,那么根据重启策略,重启该container、或其他机器重新创建一个pod恢复故障服务。
  • #服务依赖##理解Init Container一个pod中可以有一或多个Init Container。Pod的中多个Init Container启动顺序为yaml文件中的描述顺序,且串行方式启动,下一个Init/app Container必须等待上一个Init Container完成后方可启动。例如,Init Container1-> ... -> Init Containern -> app Container[1-n]。Init Container1成功启动并且完成后,后续的Init Container和app Container才可以启动,如Init Container启动或执行相关检查失败,后续的init Container和应用Container将不会被执行启动命令。因此可利用Init Container来判断app Container中被依赖的服务是否成功启动。如被依赖的app Container服务启动失败,那么利用Init Container启动失败可以阻止后续app Container服务的启动。由于Init Container必须要在pod状态变为Ready之前完成,所以其不需要readiness探针。另外在资源的requests与limits上与普通Container有细微差别,详见 Resources,除以上2点外,Init Container与普通Container并无明显区别。##Init Containers用途[list=1]
  • 前文已经提及,由于Init Container必须在app Containers启动之前完成,所以可利用其特性,用作服务依赖处理。比如某一个服务A,需依赖db或memcached,那么可以利用服务A pod的Init Container判断db/memcached是否正常提供服务,如果启动服务失败或工作异常,设置Init Container启动失败,那么pod中的服务A就不会被启动了。
  • 应用镜像因安全原因等没办法安装或运行的工具,可放到Init Container中运行。另外,Init Container独立于业务服务,与业务无关的工具如sed, awk, python, dig等也可以按需放到Init Container之中。最后,Init Container也可以被授权访问应用Container无权访问的内容。

  • ##Init Container处理服务依赖应用举例
    serviceA服务依赖serviceB,而serviceB采用上文提及Readness探针的HTTPGetAction Handler。
    spec:
      initContainers:
      - name: init-serviceA
        image: registry.docker.dev.fwmrm.net/busybox:latest
      command: ['sh', '-c', "curl --connect-timeout 3 --max-time 5 --retry 10 --retry-delay 5 --retry-max-time 60 serviceB:portB/pathB/"]
      containers:

    如果启动serviceA Pod时,serviceB还没有ready,通过kubectl get po -o wide查看pod处于Init状态
    NAME                        READY     STATUS    RESTARTS   AGE       IP          .l  NODE
    serviceA-3071943788-8x27q 0/1 Init:0/1 0 20s 10.244.1.172 bjo-ep-svc-017.dev.fwmrm.net

    通过kubectl describe po serviceA-3071943788-g03wt查看,可以看出app Container的启动时在init Container启动并成功完成后:
    Events:
    FirstSeen LastSeen Count From SubObjectPath Type Reason Message
    --------- -------- ----- ---- ------------- -------- ------ -------
    25s 25s 1 default-scheduler Normal ScheduledSuccessfully assigned serviceA-3071943788-g03wt to bjo-ep-dep-040.dev.fwmrm.net
    25s 25s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net Normal SuccessfulMountVolume MountVolume.SetUp succeeded for volume "serviceA-config-volume"
    25s 25s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net Normal SuccessfulMountVolume MountVolume.SetUp succeeded for volume "default-token-2c9j1"
    24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Pulling pulling image "registry.docker.dev.fwmrm.net/ui-search-solr-data:latest"
    24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "registry.docker.dev.fwmrm.net/busybox:latest"
    24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Created Created container
    24s 24s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.initContainers{init-myservice} Normal Started Started container
    20s 20s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Pulling pulling image "registry.docker.dev.fwmrm.net/infra/is:latest"
    20s 20s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Pulled Successfully pulled image "registry.docker.dev.fwmrm.net/infra/is:latest"
    20s 20s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Created Created container
    19s 19s 1 kubelet, bjo-ep-dep-040.dev.fwmrm.net spec.containers{is} Normal Started Started container

    查看docker Container log,init Container正在按照预先的设定,每3秒轮询验证serviceB健康检查点serviceB:portB/pathB/
    docker logs 4fd58bf54f76
    waiting for serviceB service
    waiting for serviceB service
    ... ...


    等待一段时间后,再次通过kubectl get po -o wide查看pod处于Running状态
    NAME                        READY     STATUS    RESTARTS   AGE       IP          .l  NODE
    serviceA-3071943788-g03wt 1/1 Running 0 1m 10.244.2.68 bjo-ep-dep-040.dev.fwmrm.net


    如果pod重启了,所有init Container都需重新运行。Kubernetes禁止Init Container使用readiness探针,可以使用Pod定义 activeDeadlineSeconds 和 Container的 livenessProbe 防止 init containers 一直重复失败. activeDeadlineSeconds 包含了 init container 启动的时间。

    ##参考资料
    Container Lifecycle Hooks: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/
    Attach Handlers to Container Lifecycle Events: https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/
    Init Containers: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
    Init Container and Probe: https://blog.giantswarm.io/wait-for-it-using-readiness-probes-for-service-dependencies-in-kubernetes/
    Configure Pod Initialisation: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container
    Debug Init Containers: https://kubernetes.io/docs/tasks/debug-application-cluster/debug-init-containers/
    Delaying the deployment of our stubborn service: https://blog.giantswarm.io/wait-for-it-using-readiness-probes-for-service-dependencies-in-kubernetes/

    欢迎转载,请注明作者出处:张夏,FreeWheel Lead Engineer,DockOne社区

    持续交付的实践与思考

    尼古拉斯 发表了文章 • 0 个评论 • 2222 次浏览 • 2017-07-26 08:31 • 来自相关话题

    【编者的话】一直以来都在做团队里的基础性工作,直到最近,成果开始慢慢展现,尤其是上周刚看完《持续交付》这本书后,总结已经做的工作,又有了些新的感悟。 【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于D ...查看全部
    【编者的话】一直以来都在做团队里的基础性工作,直到最近,成果开始慢慢展现,尤其是上周刚看完《持续交付》这本书后,总结已经做的工作,又有了些新的感悟。

    【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:持续集成与持续交付(CI/CD)概览;持续集成系统介绍;客户端与服务端的 CI/CD 实践;开发流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及实践经验分享等。

    过去一段时间,我都是围绕着 Gitlab 的一些功能来开展的,从最开的代码与应用配置管理,然后到 CI 系统,提升代码质量,到最后完整的持续交付流程提升团队工作效率。

    那么我就结合《持续交付》这本书的内容,正文开始。
    #为什么要有持续交付

    1. 不敢发布新功能:每次发布都会心惊胆战,因为一下子发布了太多功能,测试又没做好,而这时候产品催着要上线。另外按照以往的经验,由发布而出问题的的概率最高;
    2. 线上事故处理时间长:每次出线上事故,不能很快定位问题,如果是由于同事线上改动了什么,就更难定位问题了,而在之后大家可能会狠狠责怪那个同事,事实上,他也很无辜,因为没有人告诉他什么能做,什么不能做,或者该怎么做;
    3. 发布周期太长:由于每次功能完全开发完之后才会发布上线,而如果涉及到数据库更改或者迁移,发布周期可能会拖得太长;
    4. 协作问题:比如新人来到团队时,由于被限制了各种线上的权限,尤其是发布权限,会导致很多工作开展不顺利,而每次发布求助于其他同事的话,会造成沟通问题,进一步造成了协作上的问题。另一个,往往由于习惯于口头上说下要发布了,然后发布过程对其他人而言是不可见的,若是线上还需要操作些什么的话,几乎对其他人是更不可见的;

    #持续交付能做到什么

    1. 让软件构建、部署、测试和发布过程对所有人可见:由此,大家可以学习过程,了解其他人做了什么,在一个规范的流程中工作,促进协作;
    2. 改善反馈,更早发现问题:在一个完整的流水线中,可以设置多个『检查点』,简答来说,就是加入多个测试环节,保证代码质量,而在这个过程中,越早发现问题,修复的成本越低;
    3. 通过一个完全自动化的过程在任意环境上部署和发布软件的任意版本:在陈浩大神的 《从 Gitlab 误删除数据库想到的》 这篇文章里,提到: 人管代码,代码管机器,其实持续交付就能达到这个效果。并且在一种极端情况下,假如你使用的云服务商挂了,你也能在其它云服务商上面快速重建你的整个线上系统(当然,没那么简单)。

    #持续交付的几个原则

    1. 为软件发布创建一个可重复且可靠的过程:一键发布与回滚,如果发布出了问题,你几乎可以确定不是发布脚本本身的问题,因为这个脚本已经经过多次检验;
    2. 将几乎所有的事情自动化:手工发布及漫长又不可靠,采用自动化脚本,节省时间,节省精力;
    3. 把所有的东西纳入版本控制:采用变更管理,方便审计,将所有的变更都在掌控之中,出问题可以快速定位问题;
    4. 提交并频繁做让你感到痛苦的事情:小步快走,分散痛苦与风险;
    5. 提高内建质量:越早发现问题,修复成本越低,等 QA 或者用户告诉你应用有问题的时候,修复成本非常高,也增加了你计划外的工作;
    6. 『Done』意味着『已发布』:没有完成百分之多少这种说法,反推着你将任务分解,将功能尽快发布到生成环境中去,减少了产品反馈时间,提高了竞争力,也减少了风险;
    7. 交付是每个成员的责任:流程标准,每个人都可以参与到流程的每一个部分,促进协作,也帮助新人适应与提高;
    8. 持续改进:不断演进,改善发布流程,这个流程需要持续的改进,提高吞吐,增加产量,提高质量;

    #持续交付的实践
    在目前的团队持续交付流程中,我们在每个环节的实践如下:

    1. 提交:单元测试 Mocha/AVA,以及测试覆盖率 nyc;
    2. 编译打包:即打包 Docker 镜像,推送到 Registry ,目前还没有完全引入 Docker 集群,因此部署过程省略;
    3. 部署文档:用 Ansible 脚本自动将 API 文档以及测试覆盖情况部署至静态网页文档服务器,这个时候可以直接将分支对应的文档给客户端开发,还可以直接查看测试覆盖率情况,确认与改进单元测试;
    4. Review:即提交 Merge Request,大家一起 Code Review;
    5. 部署应用:需要 Review 通过后,将代码合并至 master 分支,然后手工点击按钮部署;
    6. 回滚:假如应用出问题,可以点击按钮一键回滚;

    可以看到,目前主要是缺失预发布环境,这一步还需要将环境搭建脚本完善之后才能做到,而目前公司运维团队还是与我们开发团队分离的,因此达到相要的效果还是得做些努力。
    #总结
    目前我已经做到:将应用配置单独管理起来,以及部署相关的脚本都已经实现,因此才能很快地将持续交付流程跑起来。其实可以这么说:应用配置管理与自动部署脚本是持续交付流程的前提与基础。

    而持续交付流程一旦完善了,能极大改善我们开发团队的交付能力,甚至倒逼产品与运维团队提高他们的效率:

    * 对于产品团队,我们能要求他们将需求拆分尽可能的细,一旦开发完成我们能快速部署,于是他们能更快得到反馈,从而提高产品的试错能力。
    * 对于运维团队,我们已经将部署流程优化了,于是他们能更专心于基础设置的维护与改善,同时也可以促进协作,推行全面的配置管理。

    #Reference

    * https://about.gitlab.com/direction/
    * https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/
    * https://github.com/everpeace/concourse-gitlab-flow
    * https://docs.gitlab.com/ce/ci/environments.html
    * https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/

    原文链接:持续交付的实践与思考

    fir.im 持续集成技术实践

    flowci持续集成 发表了文章 • 0 个评论 • 1743 次浏览 • 2017-05-11 16:59 • 来自相关话题

    互联网时代,人人都在追求产品的快速响应、快速迭代和快速验证。不论是创业团队还是大中型企业,都在探索属于自己的敏捷开发、持续交付之道。fir.im 团队也在全面实施敏捷,并推出新持续集成服务— flow.ci ,以帮助企业将开发测试流程自动化,更快速地交付产品。 ...查看全部
    互联网时代,人人都在追求产品的快速响应、快速迭代和快速验证。不论是创业团队还是大中型企业,都在探索属于自己的敏捷开发、持续交付之道。fir.im 团队也在全面实施敏捷,并推出新持续集成服务— flow.ci ,以帮助企业将开发测试流程自动化,更快速地交付产品。

    4月15日,fir.im CTO 郭扬在“光环国际·2017敏捷春季峰会”带来了《敏捷工程实践的基石——持续集成》的技术实践,从敏捷方法论的角度分享了持续集成流程的质量实践与 fir.im 团队的 CI 技术实践。演讲实录整理如下,希望能带给你一些思考。




    郭扬,fir.im CTO,曾就职于奔驰戴姆勒创新实验室,Thoughtworks,索尼移动通信,网易等公司,担任 DevLead,负责组建技术团队,管理项目进度与项目风险,软件及 DevOps 的架构设计、高并发条件下的性能调优、敏捷教练等工作。



    # 持续集成做什么
    持续集成的概念出现在 2001 年,它其实是一个 XP 极限编程的工程实践。那么持续的是什么,集成是什么呢,非常简单就是“一直不停地集成代码”。

    持续集成是把代码频繁的合并到主干,通过自动构建的方式验证软件的质量,让团队快速的响应质量,快速的修复问题,快速的给客户解决问题,快速地交付更好的软件质量。

    # 我们为什么要做持续集成

    开发人员对下面的软件开发场景很熟悉,比如:

    • 场景一:开发了新功能,老功能产生新的 bug;
    • 场景二:修好一个 bug,又产生其他 bug,甚至出现连环 bug;
    • 场景三:出现的 bug 比较多,修改代码要很谨慎,不熟悉的模块一般不敢动,怕引起问题;
    持续集成是如何缓解这个问题,Martin Fowler 大师曾经说过:

    “Continuous Integration doesn’t get rid of bugs, but it does make them dramatically easier to find and remove.” — Martin Fowler

    如上面所说,持续集成不能消除 bug ,但能更容易地发现 bug,更快速地修复,提升产品质量。那么,持续集成能给我们带来哪些价值?从这张图上可以看到,持续集成形成一个完美的闭环。通过持续的集成进行不断地检查、调整,同时,项目的透明性也得到了最大的体现。# fir.im 如何进行持续集成实践这是一个常见的持续集成流水线:在日常的开发过程中,程序员在本地提交代码,持续集成流水线要求先做一次本地集成,在本地进行验证后提交到源代码管理仓库中,之后源代码工具会发出 webhook 触发到持续集成系统中。当构建/测试完成后,会及时通过钉钉或邮件通知团队(测试/研发/boss/产品经理)集成状态,产品经理或项目经理收到通知后会在测试环境做验收测试,这是一个比较完美的反馈环。假如测试通过验收完毕后,持续集成系统会自动触发部署到类生产环节或测试环境,或由专人手动部署到生产环境。## 为什么要做本地集成首先,代码在远程进行管理,每个人都会提交代码,远程的代码仓库会产生变化,所以在本地集成的时候要求进行代码合并,以免出现分支冲突和代码冲突。其次,不要依赖于持续集成系统给你结果,可能需要 30 分钟的时间,不要让开发人员等待,一定要先做本地集成。## 如何做版本提交再说一个提交的问题,我们尽量保证每一次提交都是一个完整的提交,也就是原子提交。

    当代码变动你想创建提交时,这个提交应该尽可能的小量,并且包含一个不可分割的特性(feature)、修复(fix)或优化(improved)。

    拿每个产品开发都会遇到的 login 功能开发举例,当填完的用户名和密码传到数据库,做完验证后给用户返回一个结果。那什么是一个原子提交?比如,提交验证一个用户名,这是一个完整的 feature ;验证密码是否符合格式(6位/8位),这也是一个完整的 feature ;当我验证完用户名和密码后再传到数据库之后,查询正确与否,这也是一个完整的 feature ;保证每次提交是一个完整的 feature 或修复了一个 bug,不要代码写成半截。## 持续集成系统这里讲的是狭义的持续集成系统,通常的 CI 系统收到提交之后会触发构建,构建会有信息返回比如 commit id 、commit 信息、代码变更等,收到代码提交后会触发自动构建,接着安装依赖进行编译,并触发质量保证流程,也就是说自动化测试集。自动化测试集包括代码静态检查-单元测试-集成测试-验收测试-性能测试,也会有压力测试、回归测试、monkey test等等一系列的测试。 接下来,我们具体讲一下 fir.im 团队如何进行持续集成实践的。## fir.im 的敏捷环境fir.im 是一个内测分发平台,我们也做了一个持续集成 CI 产品-flow.ci。先来看一下我们正在使用的敏捷环境:
    • Trello 看板;
    • 三个环境(类生产环境,测试环境,生产环境);
    • CI 工具(Jenkins/flow.ci
    ## 说一下 Git 分支管理我们在应用 3 个分支 —— master/develop/feature 分支,对 feature 命名会有一些要求,持续集成系统一定会反馈到 trello 的 kanban 里,所以对于 feature 分支我们也有这样的命名 feature/fci-{card number} 以方便区分。多分支如何做频繁地持续集成?master 分支,即线上分支。线上通常会有一些 hotfix, 任何产品都不可能避免线上的 bug ,这些 bug 需要在 master 分支进行修复,修复完成后持续集成系统会告知已上线,收到团队反馈,这些代码会要求更新在 develop 分支上,之后所有团队也会收到相关通知,那么 feature 分支会有变化吗?答案是肯定的,因为频繁的集成可以防止代码偏离。这就是我们多分支构建的策略。还有一个策略——不同的分支不同的构建,持续集成系统跑完整个流程会很长,所以在 feature 分支频繁度会比在本地构建要高一些,但是也没有那么高。为了保证持续集成系统能快速地收到反馈,需要在 feature 分支上做一些定制的 workflow ,所以我们做了代码静态分析和单元测试。当 feature 分支的 card 做完之后(scrum 中 done 的含义是指测试验收完毕),集成到 develop 分支,develop 分支会自动部署到测试环境,会跑一个整个自动化测试集,为什么是这样的构建策略呢?

    我们会做代码 review ,当 feature 分支提 pr 到 develop 分支上,这样 develop 分支的构建条件是:当收到 pr 之后,开始跑持续集成。假如部署完成整个测试跑过了产品经理验收之后,没毛病了,终于可以发布了到 master 分支。

    整个团队的构建频率可以看下这张图:本地集成的频率非常高,远程构建对应的是 feature 分支,会相对低一下。QA 环境对应的是 develop 分支的构建粒度。这样的构建每天都会产生,所以做完之后不要积压,一定要保持上线节奏。kanban + scrum 结合的方式构成我们每日构建,这是一个整体的构建策略和上线频率。## fir.im 的持续集成系统演变过程罗马不是一天建成的,持续集成不是一开始就是完美的。每个开发者心中都有一个比较理想的自动化工作流——持续部署,大概会经历这几个演变阶段:
    • 最初阶段:提交代码-自动部署;
    • 一般进阶:提交代码-代码静态分析-自动部署,最简单先再加入代码静态分析;
    • 高级进阶:提交代码-代码静态分析-自动化测试集-自动部署;
    这是我们在用的自动化测试集,下面分别说下静态检查分析、单元测试、验收测试、性能测试的具体用途。### Step 1. 静态代码分析每个公司都会有自己的代码规范,代码静态分析工具能够保证代码质量,现成的工具有 java 的 FindBugs,ruby 的 rubocop 等。利用代码检查工具可以帮助团队发现可重构的地方,输出产出 – HTML 报告,也会发现潜在 bug;有的代码检查工具还会检查出一些安全漏洞。这三点是代码静态分析最重要的作用。这里也分享一个 GitHub 地址,列出一些主流语言的代码分析工具,可以参考一下。### Step 2. “单元测试”这里的 “单元测试”也加上了集成测试,毕竟创业公司要求资源最大化。程序员一定要写单元测试,要克服开发的惯性思维,不要甩锅。下面有一些注意的点和大家分享:
    • 测试异常——不仅仅测试正确情况,也要主动测试异常;
    • 减少耦合——保证独立的可测试性;
    • 功能分离——单元测试流太长,超过 20 分钟的话要详细想一下如何将功能单独拆开,效率更高;
    • 测试=需求——从测试代码看到每个 class 是干什么的,同时出现 bug 时,第一时间是看测试,想想如何从测试中复现;

    ### Step 3. 验收测试

    验收测试是端对端的测试,从收到用户名密码到返回结果,是不是我们所期望的一个值,这是验收 Acceptance Test,其实是验收了整个功能。代码静态检查和单元测试,保证了我们如何怎么去写代码,验收测试保证了写正确代码,符合开发需求。

    flow.ci 做验收测试比较多,用的是比较流行的框架 Cucumber + Selenium WebDriver,目前支持 3 种数据库,5 种 git 仓库,7 种 开发语言跑在 docker 容器云上,支持 iOS 构建跑在 mac 机器上,要保证这些排列组合正常运行,这是 flow.ci 做验收测试最核心的价值。



    其实,持续集成是一个工作流,当 push 代码的时候才会 run 起来,但是 flow.ci 本身系统也有外部依赖的特殊性,会依赖一些第三方的 sevice(比如 GitHub/GitLab 等),验收测试应该一直保持不断地运行,也可以叫持续测试吧。因为我们永远不能保证第三方的 api 会不会改变:)

    ### Step 4. 性能测试

    我们的性能测试做的比较简单,主要测试 api.因为 fir.im 做 app 的内测分发,我们需要性能测试保证 app 上传下载的正常稳定。性能测试是单用户的,压力测试是多用户的,这是两者之间的区别。

    性能测试会有一些不确定性,有很多系统会产生缓存。flow.ci 的性能测试跑在 docker 上,是一个干净独立的环境,需要让系统预热运行一下。Locust/JMeter/LoadRunner是目前比较流行的性能测试工具。
    flow.ci 目前用的是 locust,可以参考一下。


    ## 持续集成的可视化、数据分析

    我们认为一个好的持续集成系统也要做到项目进度的透明化,最传统的方式是发送相关的邮件,但实质上有几个人去看呢?为此我们采购了一个大的屏幕来解决这个问题,用来时刻提醒团队的某个构建结果。当然也可以用闪烁灯或音频的方式。




    说到数据统计分析,整个 ci 流程跑下来产生的很多数据也非常有挖掘的价值。比如,对于代码静态分析有多少 Offence、Risk、Bug,对于单元测试有失败率、测试覆盖率;对于验收测试或性能测试有多少的失败率,这些数据都有可能成为衡量一个程序员的标准。



    ## 结语
    CI 就像盖楼房的脚手架一样,没有脚手架就没办法盖出一个足够高的楼,没有 CI 就无法交付质量足够好的软件!

    欢迎分享你的观点。

    ___
    P.S.想要现场 slide 的同学,请扫码下图关注公众号flow_ci,并回复关键词「ci实践」即可获得 :)

    案例分享〡三拾众筹持续交付开发流程支撑创新业务

    163cloud 发表了文章 • 0 个评论 • 1974 次浏览 • 2017-02-10 10:58 • 来自相关话题

    本文来自三拾众筹系统架构师陈晓辉的演讲,题为“持续交付开发流程支撑创新业务”,介绍了三拾众筹基于网易蜂巢的系统开发实践。现将分享内容整理如下: 三拾众筹项目介绍 三拾众筹是一个创新型的业务,我们的理想是做不一 ...查看全部
    本文来自三拾众筹系统架构师陈晓辉的演讲,题为“持续交付开发流程支撑创新业务”,介绍了三拾众筹基于网易蜂巢的系统开发实践。现将分享内容整理如下:

    三拾众筹项目介绍

    三拾众筹是一个创新型的业务,我们的理想是做不一样的众筹平台:

    1. 基于内容产品提供众筹服务
    2. 专注探寻最有创意的想法、最有温度的故事
    3. 深耕影视、游戏、音乐、传媒、动漫等泛文娱领域

    1.png


    从2016年7月份项目筹备以来,经过两个多月的开发,10月份平台正式上线运营。目前的团队规模不大,属于内部创业的状态,但是我们的口号是:再小的力量,也能掷地回响。

    2.jpg


    今天的分享是从技术角度介绍一下我们如何构建这个持续开发的流程,来支撑我们的创新业务。

    在运行一个创新业务的时候,我们的技术会面临很大的挑战,这和我们创新业务的特点是相关的:

    1. 业务是快速变更的,不可能想好所有的事情才开始启动我们的项目,所以刚开始的时候,所谓的创新更多的是在试错。我们希望项目在做的时候,不断地收集反馈,不断地调整方向,最终找到突破点。而在不断调整方向的过程中,技术必须做到及时响应。当业务需要技术提供弹药的时候,技术不能说我们还在调研,我们还在建厂房,功能不能变更。
    2. 业务爆发式地增长。前面我们说去找方向,那什么是正确的方向,其实很难去判断,但是至少我们不是为了维持某种状态去做的,因为我们是一个从无到有的过程。一旦我们找到了正确的方向,接下来业务就会出现一个提升或者扩张,但是时间是无法预期的,往往是爆发式的,很难线性地去判断。但是对于技术来讲,如何能够不拖业务爆发的后腿,是一个棘手的问题。当业务有很大流量导入的时候,我们的系统不能撑不住,挂了。
    3. 资源成本投入。所有的创新项目资源都是有限的,如果资源很多,往往就没有了创新的土壤。资源不多就必须将有限的资源用在刀刃上。

    3.png


    面对这三项挑战,我们的技术团队必须具备三项技术能力:

    1. 快速迭代:产品要快速交付,快速部署。
    2. 可扩展:系统能够通过横向扩展的方式,支撑更大的流量。
    3. 技术有按需的能力,只扩展应该扩展的模块。

    这让我们这个创业团队想要借助云的力量,借助网易云容器平台的力量。

    对于云来讲,按需的能力是天然的,在网易云上,我们是按需按时分配的;而快速迭代和可扩展,是云的潜力,使得我们不需要采购机器,安装系统,部署环境。

    那三拾众筹如何才能发挥云的潜力,如何设计我们的系统,使用什么样的开发过程,才能让云真正的帮助我们的业务?

    这里有一个重要的概念,就是 Cloud Native。之前有人翻译为云原生应用,我觉得比较直白,我起了一个小清新的名字,叫做向云而生。

    这表示我们的应用应该设计为面向云和容器平台去应用的。

    #设计目标

    - 使用标准化流程自动配置(declarativeformats for setup automation),从而使新的开发者花费最少的学习成本加入这个项目。

    - 和操作系统之间尽可能地划清界限,在各个系统中提供最大的可移植性。

    - 适合部署在现代的云计算平台,从而在服务器和系统管理方面节省资源。

    - 将开发环境和生产环境的差异降至最低,并使用持续交付实施敏捷开发。

    - 可以在工具、架构和开发流程不发生明显变化的前提下实现扩展。

    #另外还有12原则

    三拾众筹非常相信12原则,把整个系统按照12原则进行设计。

    12 Factors
    I. Codebase-One codebase tracked in revision control, many deploys
    II. Dependencies-Explicitly declare and isolate dependencies
    III. Config-Store config in the environment
    IV. Backing services-Treat backing services as attached resources
    V. Build, release, run-Strictly separate build and run stages
    VI. Processes-Execute the app as one or more stateless processes
    VII. Port binding-Export services via port binding
    VIII. Concurrency-Scale out via the process model
    IX. Disposability-Maximize robustness with fast startup and graceful shutdown
    X. Dev/prod parity-Keep development, staging, and production as similar as possible
    XI. Logs-Treat logs as event streams
    XII. Admin processes-Run admin/management tasks as one-off processes

    系统架构

    如图是三拾众筹的系统概览,也是我们当前系统的部署架构

    4.png


    三拾众筹的架构采用的是服务化的架构,是由一系列相互协同的服务组成的。服务之间有协作的过程,服务对外也提供了统一的界面。每一个服务本身有自己的存储,有自己的缓存。

    所有的服务分两个区域,也即服务分两种类型。第一是应用的服务,第二是基础服务。

    在应用服务里面,对外有一个主站服务,同时承担了 API网关的职责。它会把前台的请求分发到后台,并且根据规则进行路由。

    服务与服务之间都是通过 Restful API也即 HTTP的方式,服务之间会有明确的依赖关系,而且依赖关系的强弱在这里用实线和虚线做区分。通过这些依赖关系来构成和编排我们的服务。

    我们最初上线的平台也不是这样的,而是只有一个众筹平台。是随着功能的丰富,应对更快的变化,而逐渐拆分的,例如对于支付模块,当我们需要接入更多的支付方式,针对支付有更多的优化需求的时候,我们需要独立出一个收银台的模块,进行服务拆分。包括会员,包括订单的部分。

    为了支撑应用服务的环境,我们还有一些基础设施服务。

    比如注册中心,服务之间有自动的服务注册与服务发现的机制。我们的所有服务是通过注册中心进行相互关联的,不需要人工的编排,是可以自动地发现服务。

    我们可以通过服务的控制台去管理服务。我的服务状态是什么,对应的版本就是什么。

    每个应用都涉及到一些配置参数,如果配置参数扔在每个服务上的话,对于运维来说代价就比较高了。对于微服务架构来讲,必然需要一个集中化,可分发的配置中心,也是在基础服务中的。

    我们会使用 Git仓库作为配置的后端,通过配置中心去分发 Git仓库中的配置,同时后面我们还会提到,有一个流程来管理整个过程。

    在这个架构里,所有的组件都在容器里面。每个服务构建的结果就是镜像,在运行期就体现为容器。

    这里面的每个服务都使用的是网易云的无状态服务,除了构建服务。构建服务是从代码构建为镜像,是在我们自己的服务器上运行,也是一个容器。

    设计要点

    接下来我分享一下我们设计时的考虑及实现要点:

    #Cloud Native的设计

    1. 从设计开始,我们就隔离了基础设施和后端服务依赖,这个隔离一方面是由容器来做的,隔离了应用和服务器之间的关系。另一方面,应用层我们用了很多的框架,例如后面提到的 springboot和 springcloud,我们使用公共的开源框架和工具,把一些面向服务化,容器化的基础功能进行实现,对于应用本身不需要关心这些过程,只需要关注中间层,根据 spring的规约来进行开发。

    1. 从一开始,就把配置和代码进行分离。将配置和镜像进行分离。

    1. 对于编排的问题,通过 springcloud和 consul进行服务发现的功能,来实现服务的自动编排。

    1. 我们实现了持续集成和持续交付的开发过程,显式地分离了构建,发布,运行的整个过程。这也是今天分享的一个主题。

    #容器化的实践

    1. 广泛使用了容器,在我们看来,容器就是服务。当我们实现一个新功能的时候,首先要考虑需不需要单独拆分为一个新的服务。
    2. 通过提供一批基础镜像,来简化服务的开发,可以说是应用开发的模板
    3. 使用了网易云基础设施平台,因为他非常开放,技术导向,对程序员友好。提供了丰富的 API,通过这些 API可以实现自动化,实现自动交付。另外蜂巢提供了很多基础 PaaS服务,包含数据库,缓存,CDN,对象存储,负载均衡等,降低构建服务的难度,提高开发效率。我们几乎用了所有的 PaaS服务,使得我们不必过多关心平台层面的东西。

    #微服务基础设施

    1. 服务的注册,发现和负载均衡机制。这个机制目前是通过 spring cloud来做的。Spring cloud是一个非常完整的微服务开发的框架,他的主要作用是在应用和设施之间提供一个抽象层,让我们用一致的 API去使用不同的服务发现机制,比如基于 Java开发的 eureka,包括我们使用的 consul。

    1. 我们实现了配置中心

    1. 我们实现了服务控制台,可以查看各个服务的状态,以及获取服务状态变更的消息通知,还有对于服务端点 Endpoint本身进行管理。对于微服务架构来说,每一个服务的端点 Endpoint应该更加智能,这是和 SOA的区别。我们也是这样的,对于每一个服务,我们借助 springcloud提供的一系列管理端口,我们的服务控制台可以通过这些管理端口去控制它,包括去查看和修改某一个服务节点的配置,查看某个节点的日志,这都是可以通过服务控制台去实现的。
    2. 持续交付的过程,后面会详细描述协作流程和自动化交付的机制。

    #技术清单

    蜂巢
    • 集群和容器、镜像仓库
    • RDS、缓存
    • 负载均衡、对象存储

    服务模板
    • consul
    • spring boot/cloud
    • Rest RPC: spring mvc, feign, ribbon,(客户端的负载均衡)
    • nginx (外部 HTTP请求的转发), consul-template (配置和配置中心打通)
    • dumb-init (Docker里面运行服务的工具)

    持续集成
    • Gitlab-CE (私有代码仓库,协作流程和配置管理的入口)
    • docker、maven
    • flyway, junit, h2, mockito, spring test (持续集成的关键点是自动化的验证)

    镜像构建

    为了尽量降低服务本身和基础设施之间的关联,在构建基础镜像的时候,分成几个层次去考虑。

    1. 最里面的一层,是OS和系统工具的一层,我们是基于 Debian系统进行构建的。
    2. 应用环境的部分是和应用分离开来的,包括 JDK,consul服务发现的机制等,这里有个小工具 dumb-init,可以在一个 Docker里面实现多进程。如果在 Docker里面使用多进程会有一个比较大的坑:如果某个进程死掉,他的子进程就会变成僵尸进程,没有办法收回,导致我们关闭 Docker容器的时候是需要强制杀掉的。这对于程序需要优雅关机来说是很有问题的,Dumb-init可以解决这个问题,另外 dumb-init还可以实现信号的重写。比如有些应用是需要接收一些信号,比如 ctrl C才能结束的,为了响应 SIGINT信号,可以通过 dumb-init进行转发。
    3. 在应用层的 Dockerfile会非常简单,选择一个正确的基础镜像,然后把包打进去就可以了。

    5.png


    基于 Gitflow代码管理和协作流程

    Gitflow是一个代码管理的流程,我们基于它实现了一个协作的流程。这个协作的流程体现在我们如何去发布我们的新版本,如果修改线上的 Bug,如果进行开发,怎么集成测试,最重要的是怎么去验证,验证什么东西。整个过程都需要自动化,且都是通过 gitlab-ce提供的界面。最重要的两个界面是 Merge Request和自动化 Pipeline来做的。

    所有的问题修改,所有的提测,都是通过 gitlab-ce的 Merge Request界面进行操作的。一旦 Merge Request接受之后,都会有一个跟在后面的 Pipeline,一个持续集成或者持续发布的任务来完成后续工作,这些后续工作就是我们交付的流程。

    我们使用蜂巢的两个环境,来作为开发和测试环境以及线上环境。对于特定的环境,我们自动构建和发布之后,会自动地进行部署,对于开发人员,QA人员,甚至线上预发环境的运维人员来说,他们只需要在 Gitlab里面操作完了,相应的版本就构建上去了,这些版本都会在镜像仓库中,会对应我们的分支,会有独立的版本。我们还可以按需去部署更多的环境,去进行检验,比如线上的扩展验证。

    6.png


    如图所示,左上角为提交的 Merge Request,右面为 Merge Request的详情,如果点击 Accept Merge Request就会触发左下角的 Pipeline进行整改发布流程。

    整个交付流程如图所示:

    7.png


    1. 开发有一个主分支称为 develop,但是所有功能的开发都不在 develop上开发,而是新开分支进行开发,可以根据发布的时间点确定某个功能是不是要上线,例如图中在这一版中,feature x, y可以上线,于是 Merge到 develop分支,而 feature z赶不上这一版,会在以后的版本上线,所以暂且不 Merge到 develop分支。

    1. Feature x,y合并 develop分支需要经过 Code Review,一旦合并后,会触发自动构建镜像的 Pipeline,然后自动部署 develop环境。开发需要在这个环境里面做集成和基本的测试,包含单元测试和冒烟测试,当集成和基本的测试遇到缺陷的时候,需要回到 feature所在的分支进行缺陷修复,修复后重新 Merge到 develop,从而重新部署 develop环境。当开发任务代码质量可以达到的时候,方才提测到 QA。

    1. 有一个 Release分支用于做测试验证,提测的发起是由 develop分支 Merge到 release版本实现的。每次做 release的时候,首先会从 Master分出一个版本到 release,Master分支的版本是当前的线上版本,则 Develop Merge到 release,其实是和线上版本的一个合并,保证当前的开发版本和线上版本可以兼容。这次 Merge会触发 Pipeline构建镜像,并且自动发布 release环境, QA可以对这个环境进行自动化测试,或者手工测试,保证代码可以达到发布的质量。如果测试出现缺陷,则需要回到 feature所在的分支进行缺陷修复,修复后重新 Merge到 develop,从而重新部署 develop环境,在 develop环境测试完毕后,再次 Merge到 release,然后 QA再测试,如此反复,直到可以达到上线标准。

    1. 一个 release分支可以达到上线标准,则将 release分支合并回 master分支,这次 Merge会触发 Pipeline自动构建镜像,自动部署预发环境。线上运维人员可以对预发环境进行测试。

    1. 如果预发环境没有问题,线上运维人员可以从镜像手工部署两套线上环境中的一套,如图中 Online A和 Online B,做灰度发布,新老版本先更新其中一套环境,然后前端通过负载均衡器将请求不断的从老版环境切换到新版环境。

    1. 如果需要性能测试,性能测试人员可以手工从镜像部署一套性能测试环境进行测试。

    1. 如果线上发现缺陷,则需要从 Master上分出一个分支到 hotfix,hotfix修复完毕进行测试后需要合并到 Master分支,同时需要合并代码到 develop分支。

    配置管理

    8.png


    如图是一个配置管理的流程。

    所有的配置文件都放在代码仓库 Gitlab里面,进行代码级别的管理。

    编辑配置文件 app.properties和 app-A.properties,然后提交,通过 Merge Request提交到 Gitlab里面。

    在 Gitlab界面里面,点击 accept进行代码合并,合并后触发 webhook,调用配置中心。

    Git2Consul从 Gitlib中 pull所有的配置文件,并且将配置文件的内容通过 consul的客户端同步到 consul中。

    Profile=A的 app和 Profile=B的 app通过 consul的客户端将配置从 consul中配置到服务中,完成配置的管理。

    总结

    最后总结一下就是:

    1. 最大化利用开源工具和云端技术建立微服务和敏捷基础设施,构建 Cloud Native 应用,充分释放云的潜力。
    2. 其次,基于容器技术自动化构建、发布和配置流程,改进敏捷交付环境和产品快速迭代能力,及时有力支撑业务。目前三拾众筹基于网易蜂巢平台,从新系统设计到上线仅需1 ~ 3周;
    3. 最后,通过实践打磨的方案才能适合自己,开放性是选择云平台关键评估因素

    聊一聊基于Docker的持续构建实现

    163cloud 发表了文章 • 0 个评论 • 2623 次浏览 • 2017-02-08 17:53 • 来自相关话题

    持续集成是一种软件开发实践。在一个团队中开发人员经常会对他们的工作进行集成,这个频率通常为每人每天至少集成一次,这也就意味着一个团队每天可能会面临着多次集成。 在进行集成时,团队成员会通过自动化地构建,包括编译、发布、自动化测试, ...查看全部
    持续集成是一种软件开发实践。在一个团队中开发人员经常会对他们的工作进行集成,这个频率通常为每人每天至少集成一次,这也就意味着一个团队每天可能会面临着多次集成。

    在进行集成时,团队成员会通过自动化地构建,包括编译、发布、自动化测试,来验证。在这个过程中团队成员可以尽快地发现集成错误,使团队能够更快地开发内聚的软件。

    基于此,一般的互联网公司或者开发团队都会有自己的持续集成平台或者工具,而开源的持续集成工具如 jenkins,teamcity,gitlab ci 等都提供了持续集成的功能。

    但这些工具的使用一般都较为复杂,流程编排会比较长。

    而 Docker的存在使得持续集成摆脱了以往打通环境、资源申请、软件部署等带来的痛苦,可以更加快速方便地对既有工作成果进行持续集成。

    基于Docker的持续构建


    一般来讲,用户往往会选择对代码仓库的某一些特定分支进行持续集成,从而快速地对当前代码进行验证。

    而在持续集成中,持续地对代码进行构建是整个持续集成的基础。

    目前,大部分公司都是基于 mvn和 ant等编译打包工具来实现内部的编译构建服务。公司使用自己的 mvn等工具对仓库进行编译构建不存在任何问题,但是编译后的可执行文件分发与运行却比较复杂。

    常规的做法是通过 SCP脚本传输,或者内部开发 agent等工具用于可执行文件的部署,但这增加了软件开发部署的代价,尤其对于中小型公司,就需要自己研发部署工具。而且:

    - 在公有云平台如果要提供一个持续集成的构建服务给用户,会面临如何获取用户的可执行文件并进行运行的问题;
    - 需要部署相关环境,比如一个 tomcat应用需要安装 jdk以及环境变量,还有其他的用户依赖组件等。

    而一个基于 docker实现持续构建的平台可以很方便地解决上述问题:
    - docker通过镜像来进行分发,不仅摆脱了执行文件分发的问题,也解决了环境问题(docker不依赖于具体环境);
    - docker通过 dockerfile来进行构建,给了用户很大的编译自由,用户可以很方便地安装环境及相关软件;
    - docker运行非常快速,一台宿主机可以运行多个 docker容器。

    网易蜂巢的持续构建实现


    接下来介绍一下蜂巢的持续构建实现以及具体的使用方法。

    用户可以把代码托管在 github或者 gitlab等代码仓库,通过使用网易蜂巢的持续集成服务,实时快速地对代码进行编译和打包生成镜像。对于镜像的发布运行,用户可以在蜂巢部署镜像,也可以从蜂巢镜像仓库拉取镜像到其他支持 docker的环境进行部署。

    持续构建服务主要包括以下模块:

    - oauth2模块。用户 oauth2绑定,绑定用户身份;
    - hook模块。hook服务用于监听用户的代码 commit;
    - 构建模块。持续构建服务基于 dockerfile,用于镜像的构建;
    - 镜像仓库。镜像仓库用于镜像的存储,分布式对象存储解决文件的高可用;
    - callback回调,callback用于镜像元信息的存储;

    网易蜂巢持续构建系统设计图如下所示:

    4.jpg


    那么,如何实现整个构建的流程?用户可以登录网易蜂巢,进入镜像仓库进行以下操作:

    #第一步:创建镜像仓库


    Docker 基于镜像来进行分发,创建镜像仓库用来支持持续构建。

    镜像仓库主要用于存储镜像,网易蜂巢镜像仓库采用基于 nos的分布式对象存储,数据保持多副本,解决了磁盘坏掉导致用户镜像丢失的问题。

    如下图创建了一个 testci 1的镜像仓库用来支持持续集成。

    2.jpg


    #第二步:设置代码仓库和镜像仓库的关系


    通过 github的 api用户可以获取 github下的所有代码仓库来进行选择,可以选择在某个仓库的某一个分支或者 tag有提交的情况下触发持续构建。

    如下图,用户选择了基于 citest的 dev分支进行持续构建。

    3.jpg


    像这样,用户每次有 commit push到代码仓库都会触发相应的持续构建。

    #第三步:触发持续构建


    在相应的持续构建分支进行代码提交,从而触发持续构建。

    如下图在代码仓库中通过 git简单的增加了一个 txt文件,并提交到 github。

    1.jpg


    #第四步:代码构建


    用户把 commit代码 push到仓库后, github/gitlab会回调 hook服务;hook服务获取相应的代码 commit信息,进行过滤后,把构建任务下发到任务队列,并在最后分发的持续构建集群对镜像执行构建;在构建成功后把镜像推送到 hub.c.163.com镜像仓库。

    如下图的构建日志清晰的展示了用户的构建过程。拉取用户指定分支上的 commit,根据填写的 Dockerfile路径进行镜像构建,最后生成镜像并推送到镜像仓库。

    6.jpg


    #第五步:使用镜像进行部署


    此时,可以快速地选择蜂巢的服务部署方式对镜像进行部署,也可以直接下载镜像进行部署,以便继续对部署的容器进行持续集成相关的测试。

    如下图采用 docker pull下载镜像,通过 docker run 的方式运行镜像,然后进行后续的集成测试。

    5.jpg


    上述就是整个持续构建的基本流程,用户可以快速地在蜂巢进行代码仓库构建。

    其实,蜂巢在整个工程的开发过程中也遇到了相当多的问题,如:

    1. 网络问题。受限于 github,mvn仓库等网络限制,导致代码拉取、mvn构建等速度相对较慢。
    2. 镜像问题。镜像获取速度较慢,镜像 push较慢。
    3. 单台机器的性能受限。

    在蜂巢团队的努力下,已经很好地解决了这些难题。

    - 针对问题1:蜂巢选择了搭建代理、采用专线等方式解决了 github和 mvn仓库等网络问题。
    - 针对问题2:蜂巢周期性地同步官方镜像。如果用户的 dockerfile是基于官方的基础镜像则会被替换为蜂巢的官方镜像从而加速下载过程。同时,对于构建机器会提供镜像的缓存,加速构建。镜像 push较慢则在内网部署镜像仓库,通过专线的方式加速整个 push的过程。
    - 针对问题3:构建机器,采用集群化部署。通过 mq队列进行解耦,从而可以快速地进行水平扩展,提升构建的能力。

    作者:易庭,网易蜂巢开发工程师。