由于这个期间面对的是php和开拓同学在本地编译好的js。对付Jenkins的运用就十分大略,在界面给配置仓库和分支再用ssh工具给rsync到对应的做事器。后续再便是再加装一些插件做下sonar扫描,做一些参数配置构建。基本上都还是一些十分根本的利用也就不在占用过多篇幅了。
二 、流水线随着云创开始推动DevOps,原有的构建办法想覆盖代码到制品交付的全过程有比较大的难度。为了DevOps的推进事情,必须引入具备pipeline能力的工具。
DevOps越来越火,市情上也涌现很多CI/CD工具,同时jenkins也推出了2.0版本。我们对一些工具也做了一些考试测验(gitlab-ci,drone),有很多工具的理念确实很好,终极我们还是选择了jenkins2.0来实现我们的pipeline。紧张如下几个缘故原由:

随着团队对付质量的哀求逐渐变高(单测,sonar,api测试,等等),开拓措辞也不再只是阐明型措辞,前端专业线也有源码直接在线完成编译打包的诉求等等一系列缘故原由。构建所须要的环境开始成为我们须要考虑的问题了,基于过往认知我们列出了下列方案:
在jenkins的master节点安装所有须要的工具以及措辞环境 。常备几台ecs作为slave节点,每台卖力一到两种措辞的构建任务。利用docker插件在启动构建任务时拉取准备好的环境镜像运行容器进行构建。这几个方案都面临环境的管理的问题,都须要在镜像或者机器里面准备好 sonar,各种措辞的单元测试环境,api测试工具这些,每一次步骤的改变或者工具的版本升级都可能须要去折腾一遍镜像或者机器。这会给后期带来高昂的掩护本钱,以是必须找到更好的方案。在Jenkins插件仓库中创造理解题思路kubernetes-plugin。kubernetes-plugin可以在构建开始时调用K8S的接口创建一个POD作为slave来进行构建任务,POD是一组容器的凑集这一组容器能共享网络和文件。利用kubernetes-plugin有了下图的设计:
在定义pipeline的时候按照需求把须要的镜像组合一下。这样只须要掩护一些环境很单一的镜像即可,新增步骤或者改变工具或环境版本只是加多一个镜像或者改一个镜像tag。
在每次任务启动,都会在集群节点启动一个 Slave 的 Pod 容器组进行任务构建,构建完成后容器自动销毁。
2.3、利用shared library实现参数化定义流水线基于上面的动态环境的方案,我们考试测验开始定义了几条流水线我们意识到了问题,须要写大量的groovy脚本并且业务团队很难自己写好这些脚本,这样流水线的落地会变的很困难。须要探求一个好的办法来办理这些问题,shared library可以很好的办理这个问题。
所有的job的定义都是一样的,都是加载shared library并运行,shared library根据参数给出的信息来运行流水线。
这样就不须要每个项目掩护一个脚本而是掩护一些大略的参数即可,所有项目共用shared library如果有些调度也能够统一调度。
采取了这种模式,云擎实现流水线管理只管理参数,不须要跟jenkins深度耦合。
基于jenkins2.0和Kubernetes我们实现了可以动态天生构建环境,能快速接入新任务并且能够统一调度的pipeline构建系统。
三 、低本钱高并发的弹性构建Pipeline全面推广并且所有业务团队接入云擎利用特性分支的开拓办法,每次特性合并触发构建会同时触发多个仓库进行构建,这样一下给构建用的集群带来了极大的压力发生多次崩溃。只能先掌握并发构建的数量,然后立马开始进行优化。
3.1、Kubernetes节点自动伸缩第一个考试测验的方案是对构建集群配置节点自动伸缩。
节点自动伸缩组件是基于 kubernetes 资源调度的分配情形进行伸缩判断的,节点中资源的分配是通过资源要求(Request)进行打算的。当 Pod 由于资源要求(Request)无法知足并进入等待(Pending)状态时,节点自动伸缩组件会根据配置的弹性伸缩组配置信息中的资源规格以及约束配置,打算所需的节点数目,如果可以知足伸缩条件,则会触发伸缩组的节点加入。当一个节点在弹性伸缩组中且节点上 Pod 的资源要求低于阈值时,节点自动伸缩组件会将节点进行缩容。因此只须要资源要求(Request)的精确、合理设置,开启自动伸缩功能就具备了节点自动伸缩的能力。
下图只是设置集群缩容的阈值:
设置好节点自动伸缩,问题并没有很好的办理,由于新的节点就绪须要韶光比较长(分钟级别靠近十分钟),当新节点准备就绪的时候已经有一部分构建完成了,后续的构建任务可以直接在原有的节点实行。实际上结果便是节点扩充出来了却不在须要这些节点了。
3.2、Serverless流水线构建属于高度动态的行为,为了动态的构建操作而掩护一个固定的打算资源池对本钱是不利的,但是没有固定的打算资源又会导致相应延迟。有没有好的办法能兼顾呢?serverless-kubernetes集群解君愁。
在先容serverless-kubernetes集群之前,有必要先理解一个项目Virtual Kubelet。
Virtual Kubelet的浸染很大略,便是将各大公有云厂商供应的容器做事与K8S的apiserver打通,实现通过K8S的api编排云厂商的无做事器容器做事(如:AWS的Fargate,Azure的ACI,阿里的ECI等)。事理上便是向K8S的apiserver注册一个假造的kubelet(相称于加入一个节点)吸收apiserver调度过来的pod,只不过真实的kubelet吸收到负载之后是在自身管理的node上进行启动pod等操作,Virtual Kubelet吸收到负载后调用注册的api。下图是Virtual Kubelet官网的架构描述:
阿里云供应两种形态的Virtual Kubelet运用,一种是对真实节点的集群加入一个Virtual Kubelet进行扩展,一种是完备无真实节点node在托管的master节点下面挂载Virtual Kubelet实现serverless-kubernetes集群。
Serverless 集群中只有 pod 运行时才会收费精确到秒,这意味着我们不须要准备固定的打算资源等待构建任务。同时又供应了可以快速启动容器的能力,这就办理了相应延迟的问题。
Serverless也有一个限定导致我们并不能直策应用,为了安全ECI是不许可运行的容器挂载宿主机的docker.sock。这样之前将宿主机的docker.sock挂载到容器内再利用docker build命令构建docker镜像的办法就行不通了。这一点导致利用Serverless进行构建的想法一贯没有落地,直到我们找到了google开源的镜像构建工具kaniko,kaniko的构建办法和事情事理与docker build十分类似,只不过不须要docker.sock和root权限,并且支持更多的参数利用起来更方便。搞定docker镜像构建的问题后,立马全面运用了serverless集群进行构建。
为了利用Kaniko也费了一番功夫,这里就不详细描述踩过的坑了,有须要的可以找我们直接要可用的方法即可。
3.3 、slave启动速率优化Serverless运用之后,虽然本钱问题和并发问题都很好的办理了。不过新的问题涌现了,单次构建的耗时比较长,经由剖析创造紧张耗时在启动slave的时候拉取镜像比较耗时(均匀约三分钟),由于ECI是没有持久化存储。在钉钉上跟ECI的产品经理提出了我们的诉求,希望ECI能够供应把镜像持久化的功能避免每次都要花费大量韶光拉取镜像。
给ECI团队提出了诉求之后等待了三个月,他们终于给出了一个办理方案—镜像缓存(imc)同步在K8S这边供应了对应的CRD。镜像缓存的事情事理便是在ECI实例启动时挂载一个包含用户定义的镜像的磁盘,ECI实例就可以在本地直策应用镜像启动容器。
定义缓存镜像例子:
apiVersion: eci.alibabacloud.com/v1kind: ImageCachemetadataname: imagecache-jenkinsspecimages: - registry-vpc.cn-hangzhou.aliyuncs.com/example-jnlp:kaniko - ...... - ...... imageCacheSize: 20
将该功能实装之后,之前须要耗时约三分钟拉取镜像的动作现在变成命中缓存启动容器,全体slave启动韶光从之前的三分钟以上优化到半分钟到一分钟完成。
在考试测验Serverless的方案时还碰着了一些阻碍性的问题,我们将问题反馈到阿里产品团队后都及时得到理解决,目前来说只须要利用最新版本的Serverless集群按照我们的方案已经不存在这些问题了,以是这里也就不再摧残浪费蹂躏篇幅了。
四、未来展望完成这个优化之后,整套构建方案中须要办理的大问题都被办理掉了,实现了一个生产可用低本钱高并发能力的构建系统。之后紧张是增强功能提高系统可用性两个方向进行优化:
云擎整合多个jenkins-master节点统一管理,构建任务按照标签匹配master运行并保持至少有2台master可以匹配。云擎具备自动创建master以及构建用serverless-k8s集群的能力。优化shared library,可以更加灵巧的定义每一个流水线步骤。------ END ------
作者简介
尹同学: 运维卖力人,目前卖力明源云SaaS产品的后台运维事情。
文章来源微信"大众年夜众号:明源技能团队