客户网站开发全流程,html注册登录界面代码,cf刷枪网站怎么做的,深圳做公司网站推广的简介#xff1a; 自动化构建和CI/CD往往是相辅相成的#xff0c;可以理解为#xff0c;自动化构建是温饱问题#xff0c;解决了温饱就会有更多的提高生产力的诉求#xff0c;也就是对应的CI平台#xff0c;CI/CD本篇文章不做扩展。 作者 | 琉克 来源 | 阿里技术公众号
一…简介 自动化构建和CI/CD往往是相辅相成的可以理解为自动化构建是温饱问题解决了温饱就会有更多的提高生产力的诉求也就是对应的CI平台CI/CD本篇文章不做扩展。 作者 | 琉克 来源 | 阿里技术公众号
一 构建平台的由来
只要是软件开发就离不开构建构建无处不在构建是源代码和用户呈现之间的桥梁。
这里要澄清一点构建 ! 编译构建的本质是把源代码翻译成运行环境能识别的产物源代码可能是Java代码也可能是配置文件、资源文件等运行环境可能是物理机也可能是虚拟机也可能是mobile phone。
所以工程师每天每时每刻都在构建不构建就没法验证。随着规划的扩大把构建自动化掉提供一个“打包平台”也就是一个自然而然的事情毕竟提高生产力是第一诉求吗这也就是构建平台最开始的由来把每天干的事情自动化掉搬上平台。
自动化构建和CI/CD往往是相辅相成的可以理解为自动化构建是温饱问题解决了温饱就会有更多的提高生产力的诉求也就是对应的CI平台CI/CD本篇文章不做扩展。
二 理解构建
构建 ! 编译构建本身是一个很复杂的编排过程。举两个例子
1 Android APK的构建过程 上图中绿色部分为工具浅蓝色部门为源代码中间产物。可以看到是一系列的工具输入的编排最终生成运行环境可识别的产物。上诉构建过程生成的产物(APK)可被Android手机识别并运行。
2 Java Jar包的构建过程 可以看到jar包的构建过程和上面APK的差异非常大相对来说也是更简单。
3 构建工具
上面两个case可以看出来构建本身很复杂要最终构建出一个可以运行的产物需要做很多事情我们完全可以手动javac copy jar等等一系列操作实现构建过程。但当工程越来越大文件越来越多这个事情就不是那么地令人开心了。这些命令往往都是很机械的操作。所以我们可以把这些机械的操作交给机器去做。对应的构建工具也应运而生毕竟提高生产力是第一诉求。
拿Java举例
Ant 上面的示例中Ant定义了五个任务init、compile、build、test和clean。
每个任务做什么都定义清楚了。在打包之前要先编译所以通过depends来指定依赖的路径。
如果在命令行里执行ant build那就会先执行compile而compile又依赖于init所以就会先执行init。
执行命令
ant test
通过命令就可以执行编程打包测试。为开发者带来了很大的便利提供了工作效率。
但是Ant有一个很致命的缺陷那就是没办法管理依赖。
我们一个工程要使用很多第三方工具不同的工具不同的版本。
每次打包都要自己手动去把正确的版本拷到lib下面去不用说这个工作既枯燥还特别容易出错。为了解决这个问题Maven如约而至。
Maven
Ant仅是一个构建工具它并未对项目的中的工程依赖以及项目本身进行管理并且Ant作为构建工具未能消除软件构建的重复性因为不同的项目需要编写对应的Ant任务。 Maven作为后来者继承了Ant的项目构建功能并且提供了依赖关系插件机制项目管理的功能因此它是一个项目管理和综合工具 其核心的依赖管理 项目信息管理 中央仓库Maven的核心理念是约定大于配置。每一种类型都有固定的构建生命周期。
和ant的build.xml相对的maven项目的核心是pom.xmljava开发同学肯定都很熟。
Gradle
Gradle已经抛弃了Ant、Maven中Xml配置的形式取而代之的是Gradle采用了领域特定语言Groovy的配置。Gradle继承了Maven中仓库坐标依赖这些核心概念。文件的布局也和Maven相同。但同时又继承了Ant中target的概念我们又可以重新定义自己的任务(在Gradle中叫做task)。
相比maven会更简洁比如在maven中要引入依赖 转换成gradle脚本
dependencies {compile(org.springframework:spring-core:2.5.6)compile(org.springframework:spring-beans:2.5.6)compile(org.springframework:spring-context:2.5.6)compile(com.google.code.kaptcha:kaptcha:2.3:jdk15)testCompile(junit:junit:4.7)
}
配置从原来的28行缩减至7行效果惊人。
同时gradle在构建性能上也碾压mavengradle在maven的基础上额外增加了增量构建、build cache、daemon等特性大大提升构建时间。
类似的构建工具其实还有很多基本属于百花齐放比如facebook的BUCKGoogle的bazel等国内也有一些厂商自己的构建工具比如腾讯的blade。不同的工具都会有自己的优势和劣势。
三 构建平台的演进
1 原始时代
其实最开始的诉求非常简单构建工具基本都是现成的人少功能简单。所有构建基本都是手动。
移动端支付宝一个应用一个仓库谁发版直接在个人电脑上拉取最新代码执行编译发布app store。服务端一台物理机一套构建脚本谁要发布直接登录输入仓库/分支信息执行构建然后发版。
2 自动化
显然随着人员的增长规模的扩大原始时代根本无法支撑进一步发展主要的矛盾
多人协作困难。多人抢占。个人机器构建的不稳定性成功率极低。
这一阶段最大的诉求项目管理/多人协作/自动化构建。应运而生两个平台CP SCM。
CP主要负责项目管理多人协作。SCM主要负责代码管理构建任务调度构建机器管理运维SCM慢慢演变成一个大杂烩jar包上传管理客户端签名各种。
大概长下面这个样子
初级阶段 这里构建比较大的难点还是在机器的管理和调度其实做了很多事情
机器管理增删机器。机器保活可用性监控。机器环境一致性的保障。机器构建负载均衡。构建脚本的统一升级维护。
上面框架运行了一段时间后还是发生了很多问题构建成功率越来越低主要有几个问题
ssh通道是有连接数限制的抽风性的ssh连接异常。负载均衡控制困难机器之间负载经常不一致构建时快时慢。机器配置管理难度大。
进阶阶段
其实这一块开源有非常成熟的方案 -- jenkins。我们干的很多的事情jenkins都已经帮我们干了。也能很好的解决我们遇到的痛点
C/S架构无ssh通道限制。自动控制负载均衡机器监控。灵活的构建和任务配置。强大的开放能力和丰富的API。
改造完大概长这样 黑科技填坑
这里要抛出一个新的概念「制品库」。
Java开发中大家对maven、gradle这些工具肯定不能再熟悉了。前面讲构建工具的时候讲过Java构建工具有几代演进AntMavenGradle。Maven之前的上古工具用的人应该非常少了。
在Maven之前是不存在版本管理依赖管理这种概念的所有的东西都在你的仓库。你的工程里面用到了gsonspringlog等开源框架和功能时是需要去手动下载对应的jar包然后放在代码库中。如果需要更新需要不停去项目对应官网下载最新发布的包。
Maven之后的工具提供了强大的依赖管理功能只要在pom.xml写上你要使用的依赖maven会自动下载依赖修改和升级只需要修改GAV坐标groupidartifactidversion依赖的所有jar包都存储在「制品库」中。
此时的构建大概长这个样子 物理机缓存使用overlay文件系统每次构建缓存独立防止公共缓存被刷入。监控制品库的覆盖记录生产delete task快速通知物理机删除公共缓存。记录overlay文件系统upper层的增加记录记录add task定时刷入物理机公共缓存。
存在的问题
环境一致性保证环境升级。复杂的脚本逻辑。
理解下这两个问题随着业务的迅速发展接入的系统越来越多APP越来越多构建的环境越来越“胖”。
比如App除了支付宝还有口碑财富香港钱包等各个产品有自己的构建逻辑也有自己的工具比如支付宝用gradle4口碑用gradle2。
其它的技术栈也越来越多JavaGOC等需要不同的JDK版本GO环境等。
所有环境都塞进一台物理机这里存在两个比较严重的问题
频繁增加新的工具如何确保不影响既有的环境和构建。环境不可复制新的构建机器初始化困难很难保证和旧有环境的一致性。
历史发生过的问题
新加的物理机编码异常导致构建产物异常运行时出现乱码。升级IOT的AndroidSDK影响支付宝部分手机计步功能失效。环境升级操作不当导致的各种构建失败。
3 容器化
构建是一件非常值得敬畏的事情需要保证构建的绝对正确一旦构建异常了后果不堪设想。
最好的保证构建正确性的方式就是什么都不要改不要加机器不要改环境什么都不要动。
但是现实是总是有越来越多新的场景冒出了今天要支持这个明天要支持那个这里是一个比较矛盾的点。
在容器技术出来之前大家都是用的是虚拟机技术我们可以模拟出来一台乃至多台电脑但是太笨重了也不好维护。2013年Docker开源它轻量高性能(秒级启动)隔离性让他迅速成为焦点。
构建也尝试探索docker技术非常适合在构建时使用可以很好的解决上面的问题。改造后长下面这样 之后升级环境再也不是痛各种场景容器隔离升级互不影响物理机秒级扩容。运维人员基本只要维护Dockerfile就行。
当然也会带来新的问题
Mac构建没法虚拟化仍然是传统物理机构建 Ansible运维。容器化之后缓存失效构建时间暴增。镜像本身的管理物理机磁盘空间管理。
4 镜像化
前面讲的都是软件的构建过程和构建服务这里其实还存在一个问题除了构建的一致性软件的运行环境一致性也至关重要。经常会发生一个软件在我的电脑可以在别人的环境却跑不起来。
随着容器技术越来越火serverless技术和应用微服务架构的演进。容器正迅速成为企业应用打包和部署的基本单位可以真正的实现build once run everywhere。 在蚂蚁的历史中也是如此越来越多的场景开始镜像化部署所以镜像构建本身也变得越来越重要镜像构建的效率稳定性安全性等至关重要。
镜像构建也经过两次演进
docker build
docker build是比较简单的我们在之前的架构之上新增了一种镜像构建类型主要存在下面几个弊端。
1对于multi-stage 的Dockerfile 构建 无法实现并行编译 2docker build 缓存利用效率低改变Dockerfile 前面的一层后面所有的层都需 要重新构建而无法使用缓存这要求用户不得不认真控制写好自己的Dockerfile以确保镜像缓存复用。
buildkit K8S
buildkit是从docker build分离出来的单独项目目前buildkit已经集成到Docker 18.06之后的版本之中核心特性
可扩展的前端格式buildkit使用前后端分离的架构设计除了Dockerfile也支持其他类型的前端格式。并行构建执行对于multistage类型Dockerfile buildkit可以实现不同stage之间的并行执行。支持构建缓存的多种处理方式buildkit处理本地缓存snapshot同时还提供了将构建缓存导入/导出到本地或者远程registry。多种输出格式buildkit支持导出成tar包或者oci格式的镜像格式。引入Dockerfile新语法RUN --mount支持构建时挂载。
这里不进行扩展有兴趣的同学可以查看buildkit的官方项目蚂蚁目前每天运行着上万数量的高可用镜像构建服务。
5 拥抱云原生
随着蚂蚁越来越多的业务serverless化云原生慢慢成为了趋势。伴随着的是对K8s之上的构建和资源的使用诉求。
而K8s本身使用门槛又极高同时也缺乏灵活的任务编排能力。相应的构建团队也开始调研和投入云原生的构建和调度解决方案。
背景
2019年3月份持续交付基金会CDF正式成立它致力于使企业在多个 CI / CD 平台上更轻松地构建和复用 DevOps 管道。
第一批进入CDF项目的主要有四个 Tekton 作为谷歌捐赠的 CDF 重要项目 是一组用于构建 CI/CD 系统的共享开源组件与 Kubernetes 紧密相连其重要性不言而喻。
并且jenkinsX底层也选择了tekton作为执行引擎。
Jenkins X is committing fully to Tekton as its pipeline execution engine. We are convinced that this is the right choice for Jenkins X, as a cloud-native CI/CD platform on Kubernetes, and for our users.内部落地
综合权衡采用tekton是一个比较合理的解决方案站在巨人的肩膀不重复造轮子。
经过一段时间的探索和演进逐步落地了云原生的资源调度和构建解决方案——ironman。服务内部每天几万的构建、代码扫描、CI任务等场景。
详细细节可以参考下面几篇文章
tektoncd github持续交付基金会
下一步计划
tekton相比K8s复杂度大大降低并且提供了足够灵活的编排和调度能力但是仍然有缺陷
概念复杂偏厚重整体调度相比直接使用POD会更慢使用上仍然有一些成本对一线用户的接入使用不友好
目前正在投入POD预热等极简模式解决上诉痛点。当然还有很多未解的难题就不一一赘述。
6 构建中台
经历了自动化容器化镜像化等场景发现用户的需求实在是千奇百怪越来越多只能说蚂蚁的业务发展太快。
我们有越来越多的业务场景IOT小程序大数据...构建的需求差异性也非常大。有Mac构建Linux构建Windows构建。应付还是有点吃力。尤其是在Mac和Windows两种无法虚拟化的场景大量的机器分组有点维护不动。现状大概长这样 由于构建逻辑基本都是在构建团队维护SCM和构建脚本中的代码逻辑也处于一个非常混乱的状态基本就是大量的if else伪代码大概长这样
if (framework sofa) {buildCmd mvn clean packageif (app special) {buildCmd mvn clean package -Ptesttrue}
} else if (framework android) {buildCmd gradle clean assembleRelease
} else if (framework jar) {buildCmd mvn clean install mvn deploy
} else if (xxx) {buildCmd xxx
}
这个阶段在面对一些个性化的构建需求其实有点力不从心需求千奇百怪“我要加个额外的参数”“我要更多的CPU”“我需要用Mac来跑构建”“我需要用某某软件的某某版本”。
当前阶段是没法继续支撑蚂蚁未来的业务发展的在加上当前底下已经有非常多的资源linuxwindowsMacK8S管理困难。
所以未来的构建平台至少是可以做到下面两点
构建可描述逻辑回归业务方。构建资源(机器)动态插拔任意切换。
构建可描述
所有的构建逻辑是透明的可配置化可代码化可描述内容包括
构建机器类型构建所需资源大小构建所需环境软件构建执行逻辑构建结果产物
构建资源动态插拔任意切换
这里最关键的点是去掉大量分组维护带来的难点让资源之间可以共用互相流动。同时可以实现资源之间的任意切换降级保障构建服务的高可用比如K8s资源降低到物理机构建。
新的框架大概长下面这样 业务使用方只要定义好buildspec.yaml文件就可以实现任何个性化的构建需求。 底下执行构建的资源可以是K8S可以是jenkins可以是物理机whatever构建资源描述好自己支持的类型入场即可。
buildspec.yaml大概长下面这样
name: android-aar-build
params:- name: productLinedefault: alipay- name: sprintIddefault: ${SPRINT_ID}
resources:- name: code-repotype: giturl: https://code.alipay.com/xxxxxref: master
environment:type: LINUX_CONTAINERimage: reg.docker.alibaba-inc.com/alipay/aarbuild:latest
buildTasks:- name: Download configimage: python:3commands:- python --version- name: Install Dependencyimage: ruby:2.6commands:- echo -------2 in ruby:2.6ruby -v
artifacts:- name: pod-for-alipaytype: iot-signpath: xxxx.zip
四 构建的挑战
1 统一构建中台
目前还在持续的开发和演进中作为服务蚂蚁全栈的构建服务其稳定性高可用灵活性至关重要。尤其是极限生存能力。
2 云原生调度基础设施
面向K8s的CI/CD让K8s的资源使用简单优雅。tekton的优雅升级极简的调度方案友好的接入成本。
3 极致的构建效率和体验
深度定制构建工具
Java研发MavenGradle并发构建缓存构建增量构建甚至秒级构建。终端研发秒级构建快速本地部署验证。镜像构建目前仍然需要30s的构建时间需要持续做下去缓存的命中率镜像加速remote cache除了构建提效还可以帮助部署提效。
制品库升级
颠覆现有不合理模式比如因为Jar release覆盖导致的“黑科技”提升研发体验和研发效率。软件制品身份追踪深入可信研发。
原文链接
本文为阿里云原创内容未经允许不得转载。