构建制品不一致,后续工作都是白费 | 研发效能提升36计

简介:本篇文章,我们从软件交付的终态出发,提出了不可变构建的概念。在软件开发的过程中,我们怎样才能享受产业生态的红利,实现软件交付过程的标准化呢?软件交付当中的集装箱应该是什么样的?

专栏策划|雅纯

志愿编辑|冯朝凯、橙蜂

之前我们举了《集装箱改变世界》(作者:马克.莱文森)中的一个例子,书中提到上世纪五六十年代,集装箱的使用,使得整体货运成本降低了95%,大部分的码头工人都面临着失业。

这件事情看起来很简单,但却给经济全球化带来了非常大的影响。后面美国企业的订单可以下到中国、以及中国成为“世界工厂”,都与之有很大的关系。集装箱的背后是标准化和基于统一标准的产业链,这里有两点比较重要的,一个是标准化,另外一个是不可变。

那么,在软件开发的过程中,我们怎样才能享受产业生态的红利,实现软件交付过程的标准化呢?软件交付当中的集装箱应该是什么样的?

如何保证软件交付过程的标准化

近十几年,软件交付形态发生了很大的变化,从最开始买物理机、建机房到虚拟机再到现在的容器。这中间为什么会产生这样的变化呢?

容器本身的底层技术是namespace和cgroup,然而这两个东西在十几二十年前就出现了。最早应用这些技术的是对资源利用率和隔离有明确诉求的云厂商,比如说阿里云不希望跑在机器上不同用户的东西互相串,最好的办法就是能限制每个用户的资源,如CPU、内存等。有了这个诉求,就会用LXC等方式去隔离,去限制资源。但是这还是没有产生容器。为什么呢?问题是各个云厂商只能在自己内部做,但是不能对外分发。所以Docker的伟大之处并不是在底层做了多大地创新,而是提供了一个可以对外分发的容器镜像。

容器镜像是一个分发的形式,我们可以把容器镜像分发给别人,或者是让别人继承我们的镜像。同时Docker又提供了Dockerfile。Dockerfile允许我们通过一个文件的形式去描述镜像。一旦能够定义镜像就可以协作了。有了这样的能力以后,容器就很快被大家所接受了。所以容器的接受看起来好像是技术发展的过程,其实是随着云原生、云市场的发展必然带来的结果。

我们很多人认为的“集装箱”就是容器,这个容器很多时候我们都认为是docker容器。在K8s里面支持很多个容器运行,大部分的情况都是用docker容器。docker容器的优势就是刚才说的两点:镜像和Dockerfile。这两点使得docker镜像可以像集装箱一样做分发。

此外,容器还提供了很好的资源隔离,可以在比较小的粒度上进行隔离。虚拟机虽然也做了隔离,但是它的粒度比较大。不仅如此,容器还提供了非常弹性的资源管理方式,这点比虚拟机和物理机都有非常大的改善。本质上它就是物理机上的一个进程,这是它和虚拟机的本质的差别。

了解了软件集装箱是什么后,然后我们再来了解下容器镜像的组成。

如上图所示,这张图非常形象地展示了容器镜像的内部结构。当我们自己执行dockerbuild构建镜像的时候,你会发现它出来的日志有很多hash值,一层一层的。实际上它是由很多层组成的,我们通过LXC或者其他的技术,把容器的进程创建出来,这个进程通过namespace和cqroup做了资源隔离和限制。容器镜像都有一个BaseImage,我们知道运行一个程序,对操作系统的环境是要求的,比如依赖的library等。这个程序如果随便在一台物理机和虚拟机部署,会随着机器的环境不同而不同,有可能导致风险。所以容器镜像给了一个基本镜像,把这个东西放里面了。再往上是Addemacs和Addapache,这两层我们会在Dockerfile中去写。然后最上面的是Writable,就是我们在容器Container运行的时候真正可以去写的东西。

那么容器镜像的特点是什么呢?它是分层的,每一层都是可以复用的,我们在某个机器上有很多个容器,如果Base镜像一样,只要下一次就行了。可以看到镜像的大小是所有的层堆起来的,堆的东西越少,这个镜像就会越小。容器镜像有一个最小的镜像叫scratch,就是一个最原始的基础镜像。这里面几乎什么都没有,基于它构建一个非常非常小的容器的话,可能就是几兆的大小。但是如果你基于CentOS基础镜像可能就是上G的大小。

容器镜像有一个非常重要的概念叫“One process per container”(容器生命周期=进程生命周期)。我们可以认为容器就是K8s上的一个进程,如果把K8s比作操作系统,那么容器就是它上面运行的一个进程。进程的生命周期是可以被管理的。虽然容器有这么多的优点,但实际在用的时候也会遇到很多的问题。

下面我们聊一聊容器镜像的一些常见的问题和建议。

容器镜像常见问题及实践建议

容器镜像常见的问题:

  • 把所有的东西都装到一个容器里面,把容器当虚拟机来用。
  • 把ENTRYPOINT设置为systemd:systemd管理的进程运行的结果和状态和的容器状态是不一致的,有可能里面的进程已经僵死了,或者Crash了,但是systemd还活着,从外部看起来这个容器没问题。
  • 私有化部署的时候带一堆导出的镜像tar包。tar包是不分层的,它不知道里面是有很多层。
  • 每次把基础镜像下发到整个集群,导致网络变得特别拥堵

我们的实践建议是:

  • 尽量采用轻量的基础镜像和确定的镜像版本。
  • 通过分层来复用镜像内容,避免重复拉取。
  • 避免采用systemd,包括supervisord和类似这样的daemon管理服务来做ENTRYPOINT。
  • 采用本地的dockerregistry等以层为粒度来离线拷贝镜像。
  • 避免同时要做大量的pull,可采用P2P的方式(如使用dragonfly)提升镜像分发效率。

容器镜像可以实现软件交付过程的标准化。标准化是手段不是目的,标准化是帮助我们更高效的复用的技术。

回到软件交付的终态,我们的目的是希望提供一个稳定可预期的系统。

而达成这个目标的前提是,要有确定的运行环境和软件制品。确定的环境是指代码(及其依赖)、构建环境、构建脚本与预期一致的产出软件制品,这一点如何做到我们后面再作分享。我们先看如何保证软件制品的一致性。

如何保证软件制品的一致性

要保证软件制品的一致性,软件制品应该有确定的格式、唯一的版本、能够追溯到源码、能够追溯到生产和消费过程,这样才能使持续交付更好地服务于企业的制品管理与开发。

在制品构建过程中,经常会遇到一些问题。例如应用的代码库里没有Makefile,package.json,go.mod而没法确定依赖,或者制品能构建成功但缺失几个依赖,又或是在自己的开发环境运行正常而在生产环境出现了开发环境没有的bug。导致这些问题出现的原因是因为构建本身是可变的,当你构建可变时,就会带来一系列的问题。为此,我们需要通过不可变构建来使制品与预期一致。

要实现不可变构建,我们需要保证有:

  • 相同的代码
  • 相同的构建环境
  • 相同的构建脚本

相同的代码

例如程序员开发时,不在依赖描述文件(如go.mod,package-lock.json,pom.xml,requirements.txt等)中指定依赖的版本,则会默认使用最新的版本作为依赖,这样产出的制品会随着依赖的更新而不能保持一致,这将带来完全不在预期内的风险。

相同的构建环境

对于构建环境来说,Dockerfile可以用来在容器平台下描述环境,通过Dockerfile我们能为制品使用一致的环境。很多时候我们并不需要在运行中使用构建环境的很多依赖,而构建镜像的体积往往比较惊人,这个时候我们就需要将构建环境与运行环境分开,以得到尽可能轻量的镜像制品。

相同的构建脚本

对应的,使用相同的,与代码实现无关的构建脚本也是非常重要的,在Dockerfile的环境中必须指定确定的环境依赖版本。

只有在同一份代码(及同一个依赖)、同样构建环境的描述、和同样构建脚本的环境下,所产生的软件制品才是相同的。这里强调的是说所有的东西都要保证一致性,如果说三者是一样的话,那产生出来的制品也是一样的,即使构建时间不同,产出的制品也是相同的。

做好不可变基础设施,首先要标准化最终交付制品的形态,并且明确此交付形态的运维管理方式。而要保证不可变,那首先要做好不可变的构建,然后才能有一致的软件制品。

NOTE:构建准确性,永远比构建更快重要。制品的构建信息不准确,导致构建制品不一致、版本不可控,所有后续的工作都是浪费。

如何提升构建效率

在构建这块,一个需要关注的点的是如何提升构建效率。我们先看一个简单的计算问题:

这是一个非常大的数据,也是非常大的损耗。很多时候一个项目的工程效率太低的原因就是因为构建太慢。构建耗时过长使得制品迭代非常慢,功能更新和bug修复也会受到影响。

那我们如何提升构建的效率呢?下面是我们的一些实践建议:

1个基本原则:保证构建的准确性,构建的准确性永远优于构建的效率。只有在保证准确性的前提下提升效率才有意义。

5点建议

  • 应用瘦身:检查应用的依赖情况,应用包体积是否过大,依赖项是否过多,能否去除不必要的依赖,能否构建更小的镜像。
  • 分层构建:底层的东西先构建出来以后被上层所复用,然后就可以做增量式的了。
  • 构建缓存:构建过程中拉取依赖是很耗时的,要避免重复拉取。
  • 网络优化:主要是保证代码、构建机器和制品库之间的低网络延时。代码和构建机器是否是在同一个低时延链路中。例如代码在Github上而使用云效构建,此时的延时相对于内网会高出许多。
  • 仓库镜像:仓库镜像可以极大地减少拉取依赖项的时间。在国内的网络环境下,如果从源仓库获取依赖,可能延时会非常长,这时可以使用镜像网络降低延时。例如nodejs开发者常使用淘宝的npm镜像源,而Python开发者使用清华的镜像源。对于企业来说也可以构建自己的镜像仓库以提升可靠性与降低延时。云效也使用了镜像仓库,来减少拉取的时间。
(小编推荐:云效流水线Flow 是一款云原生时代的流水线工具,通过容器技术让企业摆脱对虚拟机构建环境的依赖。您甚至可以根据您的使用需求,在同一条流水线上使用不同的构建环境。此外,云效流水线Flow 还提供了各种语言的容器环境,满足不同的构建使用场景。点击文末阅读原文,了解详情)

总结

本篇文章,我们从软件交付的终态出发,提出了不可变构建的概念。希望通过:相同的源码+相同的环境+相同的构建脚本=>带来一致的软件制品。而这些东西都是保存在源代码里的,所以源代码的管理非常重要。

下篇文章,我们将分享如何对源代码进行有效管理

原文链接

本文为阿里云原创内容,未经允许不得转载。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/511473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

巧用 Bitmap 实现亿级海量数据统计

作者 | 码哥字节来源 | 码哥字节在移动应用的业务场景中,我们需要保存这样的信息:一个 key 关联了一个数据集合。常见的场景如下:给一个 userId ,判断用户登陆状态;显示用户某个月的签到次数和首次签到时间&#xff1b…

cache 访问延迟背后的计算机原理

简介:本文介绍如何测试多级 cache 的访存延迟,以及背后蕴含的计算机原理。 CPU 的 cache 往往是分多级的金字塔模型,L1 最靠近 CPU,访问延迟最小,但 cache 的容量也最小。本文介绍如何测试多级 cache 的访存延迟&…

创新推出 | Serverless 场景排查问题利器:函数实例命令行操作

简介: 实例命令行功能的推出希望能消除用户使用 Serverless 的“最后一公里”,直接将真实的函数运行环境展现给用户,此后 Serverless 将不再是一个“黑盒”,用户可以更加信任和依赖 Serverless 平台来扩展更多的业务场景和规模。 …

人人都是 Serverless 架构师 | 弹幕应用开发实战

简介:如何使用 Serverless 架构实现全双工通信的应用,Serverless 架构中数据库是如何使用的,本篇文章将为您揭开答。 作者 | 寒斜(阿里云云原生中间件前端负责人) Serverless 的理念是即时弹性,用完即走。…

“ Linux 和 Kubernetes 正在成为一切的平台”—— 对话全球最大独立开源公司 SUSE CTO...

【CSDN 编者按】作为全球企业级开源解决方案领导者SUSE的CTO,Brent Schroeder见证了一波又一波技术潮流赋能企业创新发展,为企业注入新活力。同时,他也感受到技术革新给企业的商业策略、运营方式和IT基础设施所带来的冲击。他认为&#xff0c…

各位 PHPer,Serverless 正当时

简介:PHP 作为一个开发群体的很大的语言其应用范围相当广泛,Serverless 的理念和 PHP 语言的理念都是让开发者最大精力集中在自己的业务价值。那么 PHP 遇见 Serverless 会迸发出哪些火花呢? 前言 PHP 的应用范围相当广泛,尤其是…

双龙贺岁,龙蜥 LoongArch GA 版正式发布

简介:Anolis OS 8.4 LoongArch 正式版发布产品包括 ISO、软件仓库、虚拟机镜像、容器镜像。 简介 继 Anolis OS LoongArch 预览版发布后,现迎来龙蜥 LoongArch 正式版首发,该正式版在预览版的基础上提供了 AppStream、PowerTools 等仓库。A…

c语言中a lt 1e-9,年9月计算机二级考试C语言强化训练题

年9月计算机二级考试C语言强化训练题为了使广大学员在备战计算机二级考试时更快的掌握相应知识点,小编在此精选了计算机二级C语言的练习题供学员参考,大家要抓紧时间备考,祝大家备考愉快,梦想成真。一、单选题1). 若有说明&#x…

Serverless 年终技术盘点 :工业、学术、社区遍地开花,国内厂商迅速卡位

简介:预计 2021 年,将会有大量主流企业的核心应用,从原来的主机架构迁移到 Serverless 架构。 作者 | 刘宇(花名:江昱) 2021 年,Serverless 架构在权威咨询机构 Forrester 所发布的 《 The F…

Docker 如何安全地进入到容器内部

作者 | 飞向星的客机来源 | CSDN博客🌟 前言镜像是构建容器的蓝图,Docker 以镜像为模板,构建出容器。容器在镜像的基础上被构建,也在镜像的基础上运行,容器依赖于镜像。本文将对 容器的运行 及相关内容进行详细讲解。容…

KubeVela v1.2 发布:你要的图形化操作控制台 VelaUX 终于来了

简介:时间来到 2022 年,KubeVela 也正式进入了第四个阶段,在原先核心控制器 API 基本稳定的基础上,我们以插件的形式增加了一系列开箱即用的功能。让开发者可以通过 UI 控制台的方式,连接 CI/CD 完整流程,端…

c语言水仙花数(输入判断),用c语言判断一个数是否为水仙花数?

你的C语言程序我帮你改完了,完整的程序如下(改动的地方见注释)#includeint narcissistic(int number){//这里n1改成n0并加product变量保存连乘积int a,b0,n0,c,number2,number3,product;number2number;number3number;while(number>0){//这里把number>10改成number>0nu…

云原生的 CICD 框架:Tekton

作者 | AddoZhang来源 | 云原生指北Tekton 是 Google 开源的 Kubernetes 原生CI/CD 系统,功能强大扩展性强。前身是 Knavite 里的 build-pipeline 项目,后期孵化成独立的项目。并成为 CDF 下的四个项目之一, 其他三个分别是 Jenkins, Jenkins X, Spinnak…

人人都是 Serverless 架构师 | “盲盒抽奖”创意营销活动实践

简介:当 Serverless 与低代码这两个不同的技术共同相交于同一个业务时会有怎样的价值展现?本文以 “盲盒抽奖” 这个 Serverless Devs 做过的创意营销活动为例,为大家讲述 Serverless 和低代码是如何搭配来满足一个业务诉求的。 作者 | 寒斜 …

这样才是代码管理和 Commit 的正确姿势 | 研发效能提升36计

简介:效能提升从小习惯开始,这样才是代码管理和 Commit 的正确姿势! 专栏策划|雅纯 志愿编辑|张晟 软件交付是以代码为中心的交付过程,其中代码的作用有几点:第一,最终的制品要交付…

vSphere+、vSAN+来了!VMware 混合云聚焦:原生、快速迁移、混合负载

编辑 | 宋慧 出品 | CSDN云计算 vSphere、vSAN,从云计算兴起,就是 VMware 在虚拟化、分布式存储里大名鼎鼎的核心技术产品。不过随着云的发展到云原生、以及国内混合云快速发展的今天,虚拟化的领导者 VMware 有哪些最新的方案,值…

技术解读:实时数仓Hologres如何支持超大规模部署与运维

简介:在本次评测中,Hologres是目前通过中国信通院大数据产品分布式分析型数据库大规模性能评测的规模最大的MPP数据仓库产品。通过该评测,证明了阿里云实时数仓Hologres能够作为数据仓库和大数据平台的基础设施,可以满足用户建设大…

成功通航:用宜搭提升数字化管理效能,确保每次飞行任务安全执行

简介:宜搭帮助山西成功通航节省了100万左右的成本,同时使管理运营效率提升了76%。 山西成功通用航空股份有限公司 50-100人 / 航空运输 / 山西-长治 / 成功通航综合管理平台 “通用航空迎来发展机遇,随着通航行业‘放管服’政策的不断推进…

用键盘输入一条命令

作者 | 闪客来源 | 低并发编程新建一个非常简单的 info.txt 文件。name:flash age:28 language:java在命令行输入一条十分简单的命令。[rootlinux0.11] cat info.txt | wc -l 3这条命令的意思是读取刚刚的 info.txt 文件,输出它的行数。我们先从最初始的状态开始说起…

Redis 7.0 Multi Part AOF的设计和实现

简介:本文将详解Redis中现有AOF机制的一些不足以及Redis 7.0中引入的Multi Part AOF的设计和实现细节。 Redis 作为一种非常流行的内存数据库,通过将数据保存在内存中,Redis 得以拥有极高的读写性能。但是一旦进程退出,Redis 的数…