生成式AI领域的最新成果都在这里!抢 QCon 展区门票 了解详情
写点什么

基于容器服务的持续集成与云端交付(一)- 交付之禅

  • 2017-02-13
  • 本文字数:3732 字

    阅读完需:约 12 分钟

前言

随着微服务架构与容器虚拟化技术的发展,持续集成与持续交付的概念又重新回到了大家的视野,越来越多的公司开始使用持续集成的系统来解决频繁发布带来的质量问题;使用持续交付的工具来实现代码在不同环境上的自动部署。原本有些学院派乌托邦式的思想正被千千万万次的集成与部署证明着它应有的价值。那么究竟是因为什么让持续集成与持续交付这个已经不再年轻的软件开发与交付的思想重新焕发绽放迷人的光彩呢?

传统软件交付之殇

传统软件的开发与交付的周期都很漫长,一款普通的企业软件通常需要十几个开发人员,几个月的时间来完成,从需求的分析、系统的设计、编写测试用例、系统开发、单元测试、组装测试到交付调试。有条不紊的流程与规范像一辆绿皮火车下的枕木,稳定而可靠的保证整个系统缓慢的推进,每一次交付、升级,都需要提供基础的硬件、软件的环境、软件的代码、软件的文档与手册。还记得刚刚迈入软件开发行业的时候,跟随公司的服务团队,驻场交付产品,每一个驻场工程师都按照之前预演过好多遍的流程,对照着系统的部署手册,一步一步的组装硬件,安装软件,稍有差池,就要按照对应的应急预案进行回滚。开始的时候觉得交付像一个神圣的仪式,将用智慧和汗水构建成的软件交付给客户使用,是一种非常荣耀和值得骄傲的事情;后来越来越多次的产品交付让我深深的感觉每一次交付都像分娩一样痛苦,扪心自问是否有简单更舒畅的流程可以将软件交付给客户呢?

传统模式的反思与 CI/CD 概念的提出

通常来讲,一个软件的生命周期分为问题的定义、可行性的分析、系统设计、系统编写、系统测试与调试、系统部署与交付、维护与升级等步骤。在传统软件的生命周期中,更倾向于使用瀑布流的模式来去有条不紊的规范整个流程,每一个阶段都期望遵循“活动 - 结果 - 审核 - 再活动 - 直至正确”的流程来保证系统稳定。整个软件的生命周期就变成了一个很长的二维线性的流程。这也制约了软件的开发迭代与交付的速度,前辈们想了非常多的办法来提高整体的开发速度,比如将一个单体的系统系统设计成为服务化的分布式的子系统,这样可以让一个大型的单体软件的开发变成多个小的独立系统的并行开发;使用组件化的方式组建系统,在不同的系统间复用模块加速开发;通过自动化工具或者脚本进行自动化部署与交付等等。

诚然,这些都解决了软件交付过程中的一些问题与难点,但是这些方式都像西医一样,治标不治本,因为要想快速的交付,首先要明白软件交付过程中遇到的核心问题是什么。总结成两个词“自动”与“可靠”。自动是一个很宽泛的词汇,在软件交付中代表着测试自动化、交付自动化、运维自动化等等,而可靠讲的是每一次交付要保证是当前的交付是稳定的或可回滚到稳定版本的。

为了解决“自动”与“可靠”的问题,敏捷开发鼻祖 Martin Fowler 提出了持续集成与持续交付的概念,它所描述的软件开发,是从原始需求识别到最终产品部署到生产环境这个过程中,需求以小批量形式在团队的各个角色间顺畅流动,能够以较短地周期完成需求的小粒度频繁交付。频繁的交付周期带来了更迅速的对软件的反馈,并且在这个过程中,需求分析、产品的用户体验和交互 设计、开发、测试、运维等角色密切协作,相比于传统的瀑布式软件团队,更少浪费。通过这种小步快跑的方式,将小功能快速迭代、验证、交付,通过自动化的工具,将测试、部署、运维自动化,减少需求在软件生命周期中流动的时间。但是为什么看上去可以奉为圭臬的持续集成与持续交付的思想却在相当长的时间被开发者束之高阁呢?

实现持续集成持续交付的难点

对持续集成持续交付有一些理解与体会的开发者会经常看到类似下面这张图的持续交付流程。

在这张图中我们讲述了一个持续集成与持续交付的流程,从代码的提交、构建与编译、单元测试到部署环境、集成测试与发布。软件交付本身就是一件复杂的事情,不同的产品、不同的架构、不同的业务形态会导致持续集成与持续交付的实现上有非常大的不同。还记得很久以前流行一个关于哲学的笑话,当你问十个哲学家什么是哲学的时候,你会得到十一种答案,因为每个人都有对哲学不同的理解。对于持续交付也一样,Martin Fowler 讲述了一个乌托邦式的软件开发与交付的模式 - 持续集成与持续交付,但是前辈只给了我们先进的思想,并没有给出默认的实现。不同的公司、不同的产品、不同的技术栈、不同的开发与部署形态决定了持续集成与持续交付注定是因人而异的,在大家不断摸索什么样的方式是持续集成与持续交付的最佳实践的过程中。有的人做少了,只实践了其中的一部分,导致基本的交付能力上有缺欠;有的人做多了,引入了更多复杂的流程,导致原本应该提速的交付流程,像穿着名牌高跟鞋参加跨栏一样,怎么也快不起来。

如果将上面的流程具象化一个 LNMP(Linux、Nginx、MySQL、PHP) 的例子,就变成了如下的过程。

我们会发现当整个持续交付的流程流转到了持续交付系统的时候,流程开始和具体的环境与编程框架开始耦合,比如单元测试在这个例子中需要运行 PHPUnit 相关的命令去实现;准备环境需要根据具体的部署环境是 KVM 的虚拟机还是物理机或者是云服务器区别实现;配置环境需要根据具体的编程模型来准备在本例中会通过自动化配管工具例如 Ansible 来验证与准备不同环境中的代码运行时环境;分发代码后的流程在本例中是通过重启 Nginx 实现。其实这就是持续集成与持续交付真正难的部分,它并没有特定的要求规定什么流程该用什么方式做什么,就像大型软件系统的架构设计,只有“法”没有“型”,这也就是为什么程序员有很多,但架构师少的可怜的道理。

归根结底,持续集成与持续交付的难点在于如何屏蔽不同语言、不同框架、不同系统之间的持续集成与持续交付流程的差异性。曾经幻想过是否能有一种方式可以归约软件的交付,而这就是 Martin Fowler 留给我们的课后思考题 - 论如何实现持续集成与持续交付的流程标准化。

新的交付之道——容器标准化交付

容器虚拟化这几年随着 Docker 的推出,也逐渐进入到开发者的视野中。刚刚接触 Docker 的时候,按照学习新知识的习惯,我将 Docker 和虚拟机或者虚拟化进行了等同,认为他们是一个领域的不同实现,通过类比的方式来学习 Docker。但是后来我发现,Docker 的意义不在于解决软件底层的环境定义的问题,更多的是在解决交付的问题。

在上文中我们讨论了为什么持续集成与持续交付对于很多公司来讲是有难度的。而解决这个问题的最理想的办法就是是否有一种方式可以将交付的流程编程一个标准化,这样进行持续集成与持续交付的开发者可以很快的像读说明书一样,一步一步完成自己的持续集成与持续交付流程。

容器给交付带来最大的变革就是标准化。

Dockerfile: 将代码和环境打包成了镜像,将原来系统中分发的最小单元由代码变成了镜像,不同的环境、不同的软件、不同的配置都可以通过 Dockerfile 的配置来实现,标准化了交付的最小单元,让交付的最小单元不再和环境、编程框架耦合。

Docker API: 将软件的生命周期管理从原来的不同框架不同实现变成了统一标准的命令。启动软件变成了 docker run,停止软件变成了 docker stop,重启软件变成了 docker restart。

Docker Compose: 将软件交付的方式进行了标准化,大型的软件是由很多不同的部分组成的,而 Docker Compose 就是将软件之间的关联关系用标准话的方式进行了描述,并通过分发 Docker Comopse 的配置文件即可将软件进行交付。

如上图,我们将刚才的例子用 Docker 的方式进行推演,发现原本和编程框架或者环境耦合的部分现在通过 Docker 进行了标准化,这样不同语言不同框架不同业务场景的开发者就可以快速的时间自己的持续集成与持续交付了。

软件定义交付时代已到来?

云计算的兴起,让越来越多的 IT 基础设施变成虚拟的、软件定义的,比如软件定义存储、软件定义网络等等。通过编程的方式可以将原本的 IT 基础设施进行创建、分配、管理,屏蔽掉了底层的硬件的异构。反过来看云端交付的场景,是否可以变成软件定义的。我们可以通过资源编排(例如阿里云的 Ros 或者 AWS CloudFormation)定义基础的设施;可以通过 Docker 软件定义部署;云资源和容器化的应用都可以用 API 的方式来实现软件定义运维。

软件定义基础设施 + 软件定义部署 + 软件定义运维 = 软件定义交付?这个问题留给大家更多的思考。

阿里云容器服务是阿里云 2015 年 12 月推出的基于容器的 CaaS 产品,集成了阿里云 OSS、ECS、SLB、SLS、VPC、RDS 等多款 IaaS 云产品的能力。容器的交付方式虽然给交付带来了很多的便利,但是还远远不够,阿里云容器服务为微服务、持续交付提供了大量云交付的能力,可以让 Docker 的交付过程更顺畅。在下一篇文章中,我们将讨论下阿里云容器服务提供了什么样的功能特性满足大家的云端交付场景。

个人简介

莫源,阿里云高级研发工程师。在加入阿里巴巴之前,先后在北京天方地圆科技有限公司、微软亚洲研究院任职。现主要负责阿里云容器服务产品的底层服务发现系统、集群管理系统的研发,从事容器的持续交付、持续集成的方案的设计与实现。在云计算、分布式系统、图像识别与虚拟现实方向有多年的开发经验。


感谢木环对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-02-13 16:446746

评论 3 条评论

发布
用户头像
软件交付的核心问题是自动和可靠,想请问下老师:为什么有这个结论呢?这个结论的依据是什么?
2019-06-20 08:26
回复
用户头像
文章的两个过程图是不是顺序放反了?
2019-01-08 00:12
回复
是放反了
2020-03-08 11:41
回复
没有更多了
发现更多内容

pulsar 报错源码排查:"Not enough non-faulty bookies available"

李code

源码 pulsar 故障恢复 参数调优 白话源码

Z世代新母婴人群消费洞察2023

易观分析

母婴 新消费 Z世代 消费

Spring竟然可以创建“重复”名称的bean?—一次项目中存在多个bean名称重复问题的排查

京东科技开发者

spring bean @Bean 企业号 3 月 PK 榜

cookie时效无限延长方案

京东科技开发者

自动化测试 Cookie 接口自动化 UI自动化 企业号 3 月 PK 榜

对前端性能优化的一些小看法

Yestodorrow

机器学习算法(八):基于BP神经网络的乳腺癌的分类预测

汀丶人工智能

数据挖掘 机器学习 BP神经网络

【共创共赢】AntDB数据库合作伙伴交流会(北京站)顺利举办

亚信AntDB数据库

数据库 AntDB AntDB数据库 企业号 3 月 PK 榜

30s 就可以掌握的 Nginx 片段

Java你猿哥

Java nginx ssm Java工程师 nginx 开源版

《云原生架构容器&微服务优秀案例集》惊喜来袭

阿里巴巴云原生

阿里云 容器 微服务 云原生

CNStack 虚拟化服务:实现虚拟机和容器资源的共池管理

阿里巴巴云原生

阿里云 云原生 虚拟化 CNStack

软件工程高效学 | 软件工程基础

TiAmo

软件工程

GPT-4 可以开始测试了

HoneyMoose

AI大模型加速升级,数据和隐私何以为安?

博文视点Broadview

博睿学院 | 本周四,博睿学院数据集成系列公开课正式开讲

博睿数据

数据中台 智能运维 博睿数据 博睿学院

Redis高频40问

程序员大彬

Java Redis redis 底层原理

如何使用责任链默认优雅地进行参数校验?

JAVA旭阳

Java spring

聊聊前端性能指标那些事儿

京东科技开发者

性能优化 前端 性能 前端性能 企业号 3 月 PK 榜

Spring依赖注入Bean类型的8种情况,你学废了吗?

Java永远的神

spring 源码 程序员 后端 java面试

扒站软件:SiteSucker汉化激活

真大的脸盆

Mac Mac 软件 网站下载 下载网站工具

49天含泪苦学这些分布式技术文档,一不小心,吊打了字节跳动面试官

三十而立

Java 分布式 java面试

微前端框架single-spa子应用加载解析

京东科技开发者

生命周期 微前端 VUE 3.0 源码 企业号 3 月 PK 榜 single-spa

openEuler开源新项目,嵌入式实时虚拟机ZVM介绍

openEuler

Linux 操作系统 虚拟机 嵌入式 openEuler

工信部数据库适配验证中心项目验收通过 柏睿数据参与共建

科技热闻

滴滴 一面总结

Java你猿哥

Java 滴滴 java面试 面经

Three.js 进阶之旅:全景漫游-初阶移动相机版

dragonir

JavaScript 前端 three.js

OpenHarmony社区运营报告(2023年2月)

OpenHarmony开发者

OpenHarmony

全网最新架构实战文档:高并发+分布式+微服务+SpringBoot+Nginx

三十而立

Java 分布式 java面试

阿里架构组分布式架构技术使用心得:全在这一份文档里面了

三十而立

Java java面试

解决90%面试问题!GitHub顶级"Java面试手册"了解下八股文天花板

Java你猿哥

Java 面经 校招 Java工程师 春招

ShareSDK常见问题

MobTech袤博科技

三维动画视觉软件Autodesk Maya 2023软件介绍及安装教程

魔仙苹果mac堡

maya Autodesk Maya 安装教程

基于容器服务的持续集成与云端交付(一)- 交付之禅_DevOps & 平台工程_莫源_InfoQ精选文章