明源云创CI/CD技术演进

源宝导读:在敏捷迭代的过程中需要能够快速的把开发的代码集成打包部署到各个环节对应的环境中。为了高效稳定的完成这个工作,我们引入了DevOps实践理论,并形成了配套的CI/CD工具。本文将介绍云创的CI/CD工具如何演进的过程。

一 、传统构建

    在最开始阶段,诉求很简单。将gitlab的代码自动部署到测试,预发布环境。当时市面上这类工具也不多,基本扫一遍大部分都是用jenkins。自然而然也就选用了jenkins,毕竟有问题google,baidu起来也容易找到答案。

    由于这个时期面对的是php和开发同学在本地编译好的js。对于Jenkins的应用就十分简单,在界面给配置仓库和分支再用ssh工具给rsync到对应的服务器。后续再就是再加装一些插件做下sonar扫描,做一些参数配置构建。基本上都还是一些十分基础的使用也就不在占用过多篇幅了。

二 、流水线

    随着云创开始推动DevOps,原有的构建方式想覆盖代码到制品交付的全过程有比较大的难度。为了DevOps的推进工作,必须引入具备pipeline能力的工具。

2.1、Jenkins2-流水线执行器

    DevOps越来越火,市面上也出现很多CI/CD工具,同时jenkins也推出了2.0版本。我们对一些工具也做了一些尝试(gitlab-ci,drone),有很多工具的理念确实很好,最终我们还是选择了jenkins2.0来实现我们的pipeline。主要如下几个原因:

  • 定义方式:Jenkins支持脚本式的定义流水线,其他的都是声明式。这样看Jenkins的灵活度更高

  • 生态:Jenkins社区有几千个插件提供了各种各样的能力,其他工具都需要自己想办法实现这些能力。

  • 门槛:Jenkins文档丰富并且我们也一直在使用,相对来说门槛是最低的。

  • 成熟度:Jenkins已经发展了十多年完全具备生产可用的条件,其他产品都还没到生产就绪状态。

2.2、基于Kubernetes的动态构建环境

    随着团队对于质量的要求逐渐变高(单测,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/v1
kind: ImageCachemetadata
name: imagecache-jenkinsspec
images:  - 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产品的后台运维工作。

也许您还想看

云客大数据架构实践

云客大数据管理保障体系

回归统计在DMP中的实战应用

k8s中流量分离以及资源隔离实战

研发协同平台持续集成Jenkins作业设计演进

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

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

相关文章

7-51 两个有序链表序列的合并 (20 分)(vector做法)

一 :题目 、已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。 输入格式: 输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列&#xff…

linux qt4卸载,linux卸载QT4和安装QT5的方法

由于项目中需要用到QT的程序,因此安装QT5的软件支持库和QT开发环境是必须的:apt-get insatall qt5-defaultapt-get insatall qt-creatorQT5的库和QT Creator开发环境是独立运行的,如果QT Creator缺少QT5的库则程序写好了没法编译;…

7-53 两个有序序列的中位数 (25 分)(思路加详解)用STL容器中的set容器的自动去重过不去

一:题目 已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A 0 ​ ,A 1 ​ ,⋯,A N−1 ​ 的中位数指A (N−1)/2 ​ 的值,即第⌊(N1)/2⌋个数(A 0 ​ 为第1个数)。 输入格式: 输入分三行。第一行给出序列的公共长…

Blazor带我重玩前端(五)

概述本文主要讨论Blazor事件内容,由于blazor事件部分很多,所以会分成上下两篇,本文为第一篇,后续会有第二篇。我们可以视组件是一个类,我们先看一下前文所说的Index.Razor页面生成的C#代码。在此,先补充一下…

关于TensorFlow开发者证书,你想要的资源都在这里!

今天是TensorFlow开发者证书的一个里程碑,全球已经有500位开发者通过考试并顺利拿到了 TensorFlow Certificate。我也有幸在各位大佬的指点下,顺利通过考试,成为国内第7位拿到 TensorFlow Certificate 的开发者。按照Google官网的数据&#…

Kubernetes 在知名互联网公司的(dotnet)落地实践

容器化背景本来生活网(benlai.com)是一家生鲜电商平台,公司很早就停止了烧钱模式,开始追求盈利。既然要把利润最大化,那就要开源节流,作为技术可以在省钱的方面想想办法。我们的生产环境是由 IDC 机房的 10…

Java银行开户,取钱,存钱,查询余额,退出。。。。。

一:上码 package com.wyj.two;import java.util.Scanner;/*** 封装的练习*/ public class Demo8 {public static void main(String[] args) {Scanner in new Scanner(System.in);Account account new Account();System.out.println("欢迎来到杰哥银行"…

linux开发亿连手机互联,亿连手机互联车载版下载-亿连手机互联车机版v6.6.1 安卓版-腾牛安卓网...

亿连手机互联车机版,交互一体,手机-导航仪应用深度融合;升级服务,依托手机OTA升级导航仪应用;流畅连接,双通道互联技术连接更流畅;全新界面,配合前装和后装专业市场;为您…

7-3 树的同构 (25 分)(思路加详解)来呀baby!!!!!!!!

一:题目 7-3 树的同构 (25 分) 给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树…

Dapr微服务应用开发系列0:概述

题记:Dapr是什么,Dapr包含什么,为什么要用Dapr。Dapr是什么Dapr(Distributed Application Runtime),是微软Azure内部创新孵化团队的一个开源项目,皆在解决微服务应用开发过程的一些共性问题。以…

你以为.NET Core仅仅是开源跨平台?试试Docker,刷新你的认知!

2016 年微软发布了 .NET Core 1.0,可谓是平地起惊雷,因为微软终于开源和跨平台了。但是一直到19年12月份发布了.NET Core3.1,开源社区的威力才展现出来,3个月增加了100w开发者,才真正吸引大厂的关注。但你以为仅仅是因…

7-2 一元多项式的乘法与加法运算 (20 分)(思路加详解+map做法)map真香啊 各个测试点的用例子 来吧宝贝!

一:题目 设计函数分别求两个一元多项式的乘积与和。 输入格式: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。 输…

Azure认知服务之表单识别器

认知服务Azure 认知服务的目标是帮助开发人员创建可以看、听、说、理解甚至开始推理的应用程序。Azure 认知服务中的服务目录可分为五大主要支柱类别:视觉、语音、语言、Web 搜索和决策。开发人员使用 Azure 认知服务能够轻松地将认知功能添加到其应用程序中。Azure…

配置文件中的数据库连接串加密了,你以为我就挖不出来吗?

一:背景1. 讲故事前几天在调试物联柜终端上的一个bug时发现 app.config 中的数据库连接串是加密的,因为调试中要切换数据库,我需要将密文放到专门的小工具上解密,改完连接串上的数据库名,还得再加密贴到 app.config 中…

基于.NetCore3.1系列 —— 日志记录之自定义日志组件

前言回顾:日志记录之日志核心要素揭秘在上一篇中,我们通过学习了解在.net core 中内置的日志记录中的几大核心要素,在日志工厂记录器(ILoggerFactory)中实现将日志记录提供器(ILoggerProvider)对象都可以集成到Logger对象组合中,这…

c语言glut打正方形,OpenGL绘制正方形并用键盘移动

准备工作:在OpenGL中,基本图形元素如点、线、折线和多边形都是由一个或多个顶点所定义。OpenGL的7种基本图元:WeChat77732bbab74bef94d9f34e151bce8b6e.pngWeChat26002917d9408c5eef2f9637246fd9a6.pngOpenGL绘制正方形与OpenGL绘制三角形类似…

.NET或.NET Core Web APi基于tus协议实现断点续传

【导读】前两天我采用技巧式方案基本实现大文件分片上传,这里只是重点在于个人思路和亲身实践,若在实际生产环境要求比较高的话肯定不行,仍存在一些问题需要深入处理,本文继续在之前基础上给出基于tus协议的轮子方案,本…

省钱攻略送上!戴尔官网OptiPlex商用台式机到手仅需2279元!速速抢购!

如何用最少的钱磕到性价比超优的设备?两三千元左右的价格能买到狠货吗?来戴尔小企业官网,助力业务在线,Slay全场!粉丝额外宠粉福利1.关注公众号 2.通过戴尔官网客服采购电脑产品3.发送订单截图至公众号后台就会有机会…

如何面对人生危机?

点击蓝字关注,回复“职场进阶”获取职场进阶精品资料一份一名读者提问:洋哥,我7年前从大厂出来,创业多年。连续失败,没买车也没房,女朋友也和我分手了,父母也对我失望至极。最近我开始焦虑、失眠…

不用虚机不用Docker使用Azure应用服务部署ASP.NET Core程序

一般我们写好了应用程序想要部署发布它,要么发布到物理机,要么发布到虚拟机,要么发布到容器来运行它。现在有了Azure应用服务,我们可以完全不用管这些东西,只管写好自己的代码,然后使用VisualStudio的发布功…