`
frank1998819
  • 浏览: 751951 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类

基于 Docker、Kubernetes 实现高效可靠的规模化 CI/CD 流水线的搭建(转)

 
阅读更多
高效可靠的CI/CD流水线是一个IT组织实现软件服务快速交付的基础,现如今大量企业采用jenkins集群来搭建其交付流水线。然而,如何管理大量Jenkins Slave的差异化?如何简单快速实现Jenkins能力的横向扩展?如何实现流水线的高可用?如何有效利用闲置的Jenkins Slave资源?上述这些问题一直困拢着集群管理员,近两年随着虚拟化技术突飞猛进的发展,Docker, Kubernetes 等现代化工具彻底颠覆了交付团队的交付流程,同时也为CI/CD流程水线的搭建与管理提供了全新思路。 

Setup 

目前流行的CI工具很多,鉴于本文讨论CI/CD流水线在企业中的应用,考虑到企业不会有意愿将源代码的访问权开放给第三方,像Travis CI等这些基于SaaS的CI工具自然被pass,由于Jenkins在CI领域的主导性地位,所以本文的CI工具只涉及Jenkins。另外,本文默认您对Jenkins, Docker, Kubernetes 等工具有一些基础的了解。 

持续交付流水线简介 

简单介绍一下持续交付流水线,如下图所示,简单来说流水线工作流程是这样的,当代码库有代码变更的时候持续集成服务器(Jenkins)会监听到代码变更并自动触发第一个阶段 — 持续集成阶段,这个阶段做的事情是自动构建,单元测试,静态代码分析以及生成报告。如果所有步骤都如预期成功通过的话会自动进入下一个阶段 — 自动化测试阶段,在跑自动化测试套件之前,首先要把成功通过第一阶段的产出物(artifact), 如果选择java做为开发语言的话就是生成的war包,ruby的话就是gem文件,部署到测试服务器上,部署完成之后触发自动化测试套件,包括验收测试,容量测试,性能测试等会自动执行,如果所有测试用例都顺利通过(有些公司还需要做一些手工测试如探索性测试等)的话,那么这个版本就会被标记成一个可发布的侯选版本。一旦业务需要,就会通过一键部署的方式将相应的侯选版本发布到生产环境上去。如果你想更多的了解持续交付相关的知识请阅读David Farley and Jez Humble的名著《Continues Delivery》。 

实践与痛点 

上述这个过程实现起来需要这样做,首先需要把上图中各个阶段的工作脚本化,说具体一点就是需要写一个构建脚本来完成编译,单元测试,静态代码分析,生成报告等步骤,从而完成持续集成阶段的工作,然后是自动化测试脚本,这个脚本可以触发自动化测试套件并生成相关报告,最后需要写一个部署脚本,用于将持续集成阶段的产出物部署到测试环境上(当然最后的发布阶段也会重用这个脚本),这里需要注意的是要确保部署都是可重复的,重复部署同一个产出物N次的效果与只部署一次的效果相同,也就是大家常说的幂等。接下来就轮到Jenkins出场了,首先我们需要配置一下Jenkins来监听代码库的变更,这就意味着只要有代码迁入就会触发相对应的流水线,然后我们用Jenkins job或pipeline将这几个阶段的脚本串联起来(下图是以job为例),这样一个简单的CI/CD流水线就搭建完成了。 

如上图所示,每一个Job负责运行某一阶段的脚本,可以简单类比为Job1运行持续集成阶段的脚本将源代码从代码库中迁出,编译,单元测试,静态代码分析以及生成报告,Job2首先将持续集成阶段的产出物部署到测试环境并运行自动化测试套件,生成报告并标记产出物,Job3用于按需发布。每个Job所运行的脚本依赖的语言或运行环境会有所不同,可以通过label方式选择到相应的Slave上运行。 

但在企业级大规模的应用CI/CD流水线时,由于企业中多团队多产品的存在,不同的团队会根据产品自身的特点来选择不同的技术实现方式,这就意味着产品实现语言会有很多种,比如java, C#, ruby, python, nodejs ...那么相对应的CI/CD流水线就需要提供所有语言的编译环境并安装相关的依赖包,当然为了减少依赖,避免冲突以及更好的管理这些编译环境聪明的管理员会选择让每一个slave只能运行特定编程语言的Job, 如下图所示: 

上图这个Jenkins集群Maser只用来调度和收集log,所有的Job都会由Master根据不同的label导流到对应的Slave上运行。这种集群的实现方式是我们在VM时代不得已的选择,虽然能解决大部分问题,但也带来了很多困扰。 
  • 单点依赖 Jenkins Master成为单点,一旦Jenkins Master down机,那将是灾难性的,整个CI/CD流水线都将处于不可用的状态。
  • 不易维护 大量差异化的Jenkins Slave管理起来难度很大,由于差异化的存在,维护升级几乎都需要手动完成,人力成本投入很高。
  • 不易扩展 举个例子,我们发现流水线对Java7这个Slave发出的请求量比较大,经常出现排队现像。为了缓解这种情况,管理员需要增加一个可以编译Java7应用的Slave,那么管理员需要怎么做呢?首先需要准备一台VM,然后安装java7以及所有依赖的软件包,最后配置Slave相关信息label等并将新安装好的Slave注册到Master,基本上都需要人为干预,扩展起来非常不方便。
  • 资源浪费 每一台Jenkins Slave Server都是一台实实在在运行的VM, 当Slave Sever空闲时也不能将它所占用的资源释放,因为随时可能需要这个Slave完成相关的Job。
解决痛点 

下面我们来看一下虚拟化技术带来了的福音,下图是一个基于Kubernetes, Docker搭建起来的Jenkins集群,为了避免混淆我略去了Kubernetes集群中的Master node。我们看到Jenkins Mater以Docker container的形式运行在Kubernetes一个Node上并将所有Jenkins相关数据存储到一个volume中,Jenkins Slave也以Docker container的形式运行在各个Node中,之所以用虚线来表现Slave是因为Slave不是一直存在的,它会被动态的按需创建并自动删除。简单介绍一下这种动态创建注册Slave的方式,它的工作流程是,当Jenkins Master收到一个build的请求时,会用按照label的要求动态的创建一个运行在Docker container中的Jenkins Slave并注册到Master上, 然后运行相应的Job,当Job运行完成后这个Slave会被注销,所在的Docker container也会被自动删除。 

这种基于Docker, Kubernetes搭建的CI/CD流水线给Jenkins集群带来了诸多益处: 
  • 高可用 Jenkins Master被部署在Kubernetes集群上,一旦container运行异常意外退出,那么Kubernetes会自动用相同的Docker image帮我们从新起动一个新的Jenkins,并将volume attach给新创建的Docker container,从而保证不会丢失任何数据,实现了Jenkins集群的高可用性。
  • 自动伸缩 由于每一次运行Job时,Jenkins Master都会动态创建一个Jenkins slave,Job完成之后Slave会被注销所在的Docker container也会被自动删除,所占用的资源就会被自动释放。也就是说当同时请求的Job数量越多,生成的Slave container就会越多,占用的资源也就越多,反之亦然,而且这种动态伸缩是完全不需要人为干预的。
  • 完全隔离 由于每一次运行Job都是在一个全新的Jenkins slave中运行,避免了同时运行的Job与Job之间发生冲突的可能性。
  • 容易维护 对比之前每一个Jenkins Slave是一台固定VM的做法,以这种方式搭建的集群维护的不再是固定的VM而是创建动态Slave所需要的Docker image,我们可以很容易通过Docker File来build适用于我们自已的Docker image并将它们存储在私有的Docker registry中,非常易于维护。
  • 容易扩展 当我们发现Jenkins的Queue中存在大量等待执行的Job是因为kubernetes集群的资源不足时,能够很容易的初始化一个kubernetes node并将它添加到集群中来,实现横向扩展非常的方便。
简单实现 

下面我们来完成一个简单的实现: 

1、首先你需要安装一个Kubernetes cluster,请参考https://kubernetes.io/docs/setup/ Kubernetes安装完成之后,首先需要用下面两条命令和文件部署一个Jenkins到Kubernetes集群: 
代码 
  1. kubectl create -f jenkins-deployment.yaml  
  2. kybectl create -f jenkins-service.yaml  


tip: 标红的部分很重要,开放8080端口是用来访问Jenkins web portal用的;而动态创建的Jenkins slave会默认通过50000(可修改)端口与master建立连接。 
检查jenkins安装运行情况: 

2、查看Jenkins log,用管理员密码登录Jenkins并安装Kubernetes plugin。 
3、 配置Kubernetes cloud 
Manage Jenkins/Configure System/ Add a new cloud/ Kubernetes: 

Add pod template/Kubernetes Pod Template: 

点击Save之后大功告成。 

牛刀小试 

下面我们来测试一下这个动态注册Slave的Jenkins集群是否工作正常,首先登录Jenkins创建一个简单的free style job,指定这个Job只能在Label为“jnlp”的agent上运行。点击build now,你会发现奇迹发生了,原来没有注册任何Slave的Jenkins动态的创建一个Slave并注册到Master上,然后运行相应的Job,当Job运行结束后这个Slave被自动清除了。 

PS:这只是一个简单的实现,在企业的实践中,我们需要不同的build环境,需要我们基于jenkinsci/jnlp-slave这个Image构建我们自己的Jenkins slave Image并保存到私有的Registry中,相对应的Kubernetes需要从私有Registry拉取Image。 

参考文献: 
分享到:
评论

相关推荐

    jenkins+k8s+docker+harbor的ci、cd操作

    在这个文件中,我们将通过 Jenkins 结合 Kubernetes(k8s)、Docker 和 Harbor 实现 CI/CD 操作。 CI/CD 概述 持续集成(CI)是指通过自动化的手段来构建、测试和集成应用程序的过程。持续交付(CD)是指将应用...

    自动化打包部署前端vue项目,思维导图

    GitLab CI/CD 是一个强大的工具,可以实现从前端Vue项目的构建到部署的全流程自动化。 #### 二、自动化部署前端Vue项目的基本步骤 1. **生成SSH密钥对**: - 使用`ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_...

    JFrog的Kubernetes容器平台技术实践.pptx

    在传统模式下,无法满足按需使用的需求,无论是开发、测试、技术支持还是其他团队,都缺乏独立的CI/CD流水线和沙箱环境。因此,JFrog决定将内部的应用和服务全面Kubernetes化,以解决这些问题。 实践中,JFrog采取...

    陈展文-招行如何基于 K8S 容器技术打造 DevOps 流水线.pdf

    5. 持续集成和持续部署(CI/CD):Kubernetes为招商银行的持续集成和持续部署流程提供了强大的支持,使得软件开发、测试和部署更加自动化和高效。 随着DevOps实践的不断深入,招商银行的未来计划可能包括进一步优化...

    cicd常用框架和组件

    2. **GitLab CI/CD**:GitLab内置了CI/CD功能,允许用户在GitLab仓库中直接配置和运行流水线。它的YAML语法简洁明了,且与GitLab的其他特性(如代码审查、版本管理)紧密结合,为开发团队提供了一站式解决方案。 3....

    关于流水线3.0打造DevOps落地工具链的介绍说明.zip

    本文将深入探讨“流水线3.0”如何构建DevOps落地工具链,帮助组织实现更高效、更可靠的软件工程流程。 首先,我们要理解什么是流水线。在DevOps语境下,流水线通常指的是自动化的工作流程,它能够将代码变更自动...

    Docker with OpenStack

    2. **持续集成/持续部署(CI/CD)**:在OpenStack上构建自动化的测试和部署流水线,利用Docker容器来确保环境一致性。 3. **大规模应用部署**:在大型组织或企业内部,通过OpenStack和Docker的结合,可以实现大规模...

    金融企业的DevOps规模化转型2022DevOps顶级峰

    DevOps实践中,必须确保自动化工具链、持续集成/持续部署(CI/CD)流水线以及基础设施即代码(IaC)策略都符合监管标准,实现安全和合规的自动化。 2. **文化转变**:DevOps不仅仅是技术变革,更是一场文化革命。...

    微众银行测试流水线建设实践-安继贤.pdf

    2. **持续集成/持续交付(CI/CD)**:微众银行采用了CI/CD流程,每次代码提交都会触发自动化构建和测试,快速发现并修复问题,加速迭代速度。这种模式有助于保持软件的稳定性和可靠性,同时缩短产品上线周期。 3. **...

    The DevOps 2.4 Toolkit.zip

    8. **版本控制系统**:如Git,它是源代码管理的关键工具,促进了协作开发和版本控制,也是CI/CD流水线的起点。 9. **微服务架构**:在Java环境中,Spring Boot和Spring Cloud等框架支持微服务的开发,使得应用程序...

    《深入探索云原生流水线的架构设计》1

    - 多场景应用:Pipeline被广泛应用于CI/CD(持续集成/持续部署)、快数据平台、自动化测试平台以及SRE运维链路等多个领域。 5. 实现细节 虽然没有给出具体的实现细节,但从整体架构和功能特性来看,Pipeline可能...

    自动安装部署

    这通常涉及到一系列自动化工具和技术,如配置管理工具(如Ansible、Chef或Puppet)、持续集成/持续部署(CI/CD)工具(如Jenkins、GitLab CI/CD)以及容器化技术(如Docker和Kubernetes)。 在描述中提到的链接可能...

    使用open source产品组装你的web应用架构(转载)

    2. GitLab CI/CD:集成在GitLab中的CI/CD系统,与版本控制紧密集成,提供便捷的流水线管理。 七、容器化与编排 1. Docker:轻量级的容器技术,使得应用可以在标准化的环境中运行,便于移植和扩展。 2. Kubernetes...

    阿里云 专有云Enterprise版 V3.5.0 企业级分布式应用服务EDAS 技术白皮书 - 20180710.pdf

    4. **快速迭代**:通过CI/CD流水线,加快新功能上线速度,缩短产品周期。 **安全性与合规性** EDAS遵循严格的隐私和数据保护政策,提供安全的访问控制、数据加密、审计日志等功能,确保用户数据的安全。同时,它...

    Python库 | sumo_docker_pipeline-1.1-py3-none-any.whl

    将SUMO与Docker结合,可能是为了在不同环境下便捷地部署和运行交通模拟任务,比如在持续集成/持续部署(CI/CD)流水线中进行大规模的仿真测试。 综上所述,"sumo_docker_pipeline"是一个用于Python 3的库,它整合了...

    基于IT系统的PaaS实践分享

    4. **自动化流水线**:通过构建持续集成/持续部署(CI/CD)流水线,实现软件发布的自动化。 5. **统一资源调度**:支持虚拟机、物理机、容器等多种计算资源的统一管理和调度。 6. **安全性**:通过安全扫描、权限控制...

    云原生将本之路技术探索创新与应用共34页.pdf.zip

    4. **持续集成/持续部署(CI/CD)**:云原生提倡快速迭代,CI/CD流水线是实现这一目标的关键。通过自动化测试、构建和部署,可以快速将代码更改推向生产环境,降低了错误风险。 5. **DevOps文化**:云原生强调开发和...

    26洞悉PaaS平台的本质1

    软件生产流水线(CI/CD)使得代码提交、测试、打包和部署成为无缝过程,而自动化运维则包括监控、报警、性能优化和资源调度等环节。这种自动化不仅提高了效率,还减少了人为错误,确保服务质量的持续提升。 【PaaS...

Global site tag (gtag.js) - Google Analytics