基于Jenkins实现的CI/CD方案

这篇具有很好参考价值的文章主要介绍了基于Jenkins实现的CI/CD方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于Jenkins实现的CI/CD方案

前言

最近基于Jenkins的基座,搭建了一套适用于我们项目小组的持续集成环境。现在把流程整理分享出来,希望可以给大家提供一些帮助和思路。

使用到的组件和版本

组件名称 组件版本 作用
Harbor 2.7.3 镜像仓库
Jenkins 2.319.2 持续集成工具
Pipeline 2.6 Jenkins插件,编排流水线脚本
SSH Pipeline Steps 2.0.0 Jenkins插件,提供远程执行ssh能力
Git 4.10.1 Jenkins插件,提供拉取git代码仓库的能力
Httpd 2.4.18 HTTP服务器,用于归档编译后的软件包,镜像包
Maven 3.6.3 后端代码构建工具
Node 8.17.0 前端代码构建工具
Docker 20.10.0 容器版本
Docker Compose v2.18.1 容器编排

我这边是基于Jenkins的Pipeline+Docker的方式进行的任务编排,Jenkins是找的一个别人做好的,内置了绝大多数插件的容器版本,链接地址:https://hub.docker.com/r/h1kkan/jenkins-docker。这个做好的镜像里面没有SSH Pipeline Steps这个插件,需要自己额外下载一下,这边需要注意一下插件和Jenkins的对应版本。

基本流程图

基于Jenkins实现的CI/CD方案,jenkins,ci/cd,运维
这边有几个需要注意的地方,简单说明一下

  1. 首先需要配置代码仓库的webhook,这个网上有很多资料,可以自行参考配置一下

  2. dockerfile,docker-compose.yml这些文件需要内置在代码仓库中或者服务器内(我们是dockerfile文件内置在代码仓库,docker-compose.yml文件放在服务器里面固定目录)

  3. 在第五步,执行远端ssh时,需要去更改docker-compose.yml中的image节点,一开始准备用shell去做的,但是实现有点难度,然后就内置了一个python脚本,用yaml这个库去实现的,具体脚本updateImageLabel.py参考:

    import yaml
    import sys
    
    filename = sys.argv[1]
    # 加载docker-compose.yml文件
    with open(filename,'r') as f:
        data = yaml.load(f)
    # 更新镜像标签
    data['services'][sys.argv[2]]['image'] = sys.argv[3]
    with open(filename, 'w') as yaml_file:
        yaml_file.write(yaml.dump(data, default_flow_style=False))
    

    使用时,传入三个参数,分别是docker-compose.yml文件路径,需要更新的服务,更新后的镜像标签

    python3 updateImageLabel.py ${dockerComposePath}  ${service}  ${image}
    
  4. Harbor的安装可以参考我之前的博客,安装完成如果是http的话,还需要配置一下insecure-registries仓库信息,并且执行docker login命令登录镜像仓库,用于拉取Harbor仓库镜像

    {
      "insecure-registries": [
        "harbor服务器地址"
      ]
    }
    
  5. 第七步是可选的,做这个是为了方便每一个版本的归档,这边可以归档软件包或者save之后的镜像包

具体实现步骤

下面具体写一下实现的步骤,因为涉及的东西很多,有一些能找到的通用的步骤我就先不写了,大家可以自行去百度或者Google。

基础中间件部署

这边只讲Jenkins和Httpd的部署,Harbor部署可以参考我之前的文档。

Jenkins部署

通过docker的方式拉起Jenkins

docker run -u root -e TZ=Asia/Shanghai --name=jenkins -d -e TZ="Asia/Shanghai" -p 8080:8080 -p 50000:50000 -v /data/jenkins:/var/jenkins_home -v /run/docker.sock:/var/run/docker.sock -v /data/archive:/data/archive h1kkan/jenkins-docker:2.319.2

容器起来之后,需要进入到容器内部执行一下docker login的命令,在Jenkins容器内部也生成一套Harbor的凭证。

第三个挂载目录是用来开给Httpd服务器的,用于归档软件包和镜像包。

Httpd服务器部署

通过docker拉起Httpd服务器

docker run -p 8001:80 -v /data/archive:/usr/local/apache2/htdocs/ -d --name httpd httpd:2.4.18 

这边挂载目录就是Jenkins开出来的目录

Maven、Node、JDK等基础镜像

可以先从外网拉取对应版本,然后本地打成tar包之后上传到服务器解压,再tag之后推送到自己的Harbor仓库。

在Jenkins配置Git凭证

这个网上也很多,就不细致展开了,可以自己查一下

Pipeline流水线编排

后端流水线pipeline脚本
import java.text.SimpleDateFormat
import java.util.TimeZone

// 构建版本
def createVersion() {
    def simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss")
    simpleDateFormat.timeZone = TimeZone.getTimeZone("Asia/Shanghai")
    return simpleDateFormat.format(new Date()) + "_${env.branch}"
}

def getTime() {
    def simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss")
    simpleDateFormat.timeZone = TimeZone.getTimeZone("Asia/Shanghai")
    return simpleDateFormat.format(new Date())
}

// 获取远端服务器信息 
def GetRemoteServer(ip, username, password) {
    def remote = [:]
    remote.name = ip
    remote.host = ip
    remote.user = username
    remote.password = password
    remote.allowAnyHosts = true
    return remote
}

pipeline {
    agent none
    environment {
        _version = createVersion()
        _time = getTime()
    }
    stages {
        stage('Git Checkout') {
            agent any
            steps {
                checkout([
	                $class: 'GitSCM', 
	                branches: [[name: "${branch}"]], 
	                doGenerateSubmoduleConfigurations: false, 
	                extensions: [], 
	                gitTool: 'Default', 
	                submoduleCfg: [], 
	                userRemoteConfigs: [[url: '{{git_url}}',credentialsId: '{{credentialsId}}',]]
                ])
            }
        }
        stage('Source Package') {
            agent {
                docker { 
                    image 'local-maven:3.6.3-openjdk-8' 
                    args '-v maven-repo:/usr/share/maven/ref'
                }
            }
            steps {
                sh 'mvn clean install -Dmaven.test.skip=true'
            }
        }
      
        stage('Build Image') {
            agent any
            steps {
                sh 'docker build -f $WORKSPACE/CI/dockerfile --build-arg JARNAME=backend.jar -t 127.0.0.1:18080/library/backend:${_version} $WORKSPACE/backend/target/'
                sh 'docker push 127.0.0.1:18080/library/backend:${_version}'
                sh 'docker rmi 127.0.0.1:18080/library/backend:${_version}'
            }
        }

        stage('Publish To Env') {
            agent any
            steps {
                script {
                    def remote = [:]
                    remote = GetRemoteServer('127.0.0.1', 'username', 'password')
                  	sshCommand remote: remote, command: "python3 updateImageLabel.py docker-compose.yml backend 127.0.0.1:18080/library/backend:${_version}"
                  	sshCommand remote: remote, command: "docker-compose -f docker-compose.yml up -d --build backend"
                }
            }
        }
          
        stage('Archive Package') {
            agent any
            steps {
                sh 'mkdir -p /data/archive/backend/${branch}/${_time}'
                sh 'cp $WORKSPACE/backend/backend.jar /data/archive/backend/${branch}/${_time}'
            }
        }
    }
}

解释一下这个脚本

  • 首选镜像的版本是时间戳+分支的格式,类似20231026095511_dev,可以根据项目组的要求进行生成。

  • GetRemoteServer方法主要是提供获取远端服务器的信息,主要使用了SSH Pipeline Steps这个插件的能力,传入ip,username,password三个参数,这边密码是明文写死在脚本里面的,这个插件也支持密码加密保存,如果安全性要求比较高的可以换成加密的方式。

  • Git Checkout 这个stage主要是进行代码的下载,根据${branch}这个参数来指定代码仓库的版本,参数的具体配置可以看下Jenkins参数化构建的相关指导和文章。

  • Source Package就是代码仓库的打包,这边指定使用Docker镜像作为执行的Agent,只要指定镜像和编译命令就可以。这边我还挂载了一个maven-repo的volume,主要是为了缓存Jar包,不用每次都去下载。

  • Build Image步骤进行代码的构建,通过docker-build命令去生成镜像,这边的dockerfile文件是内置在我们代码库中的,参考如下:

    FROM 127.0.0.1:18080/library/java:8.0
    ARG JARNAME
    COPY ${JARNAME} /data/
    
  • Publish To Env 推送到环境,这边核心就是连接到远程服务器,通过修改镜像标签的脚本去更新docker-compose.yml文件中的镜像标签,然后重新构建容器

  • Archive Package 是否归档,演示的脚本里面只是归档了编译后的文件,还可以归档镜像等等。归档的路径为分支名/时间戳
    基于Jenkins实现的CI/CD方案,jenkins,ci/cd,运维

前端流水线pipeline脚本
import java.text.SimpleDateFormat
import java.util.TimeZone

// 构建版本
def createVersion() {
    def simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss")
    simpleDateFormat.timeZone = TimeZone.getTimeZone("Asia/Shanghai")
    return simpleDateFormat.format(new Date()) + "_${env.branch}"
}

def getTime() {
    def simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss")
    simpleDateFormat.timeZone = TimeZone.getTimeZone("Asia/Shanghai")
    return simpleDateFormat.format(new Date())
}

// 获取远端服务器信息 
def GetRemoteServer(ip, username, password) {
    def remote = [:]
    remote.name = ip
    remote.host = ip
    remote.user = username
    remote.password = password
    remote.allowAnyHosts = true
    return remote
}

pipeline {
    agent none
    environment {
        _version = createVersion()
        _time = getTime()
    }
    stages {
        stage('Git Checkout') {
            agent any
            steps {
                checkout([
	                $class: 'GitSCM', 
	                branches: [[name: "${branch}"]], 
	                doGenerateSubmoduleConfigurations: false, 
	                extensions: [], 
	                gitTool: 'Default', 
	                submoduleCfg: [], 
	                userRemoteConfigs: [[url: '{{git_url}}',credentialsId: '{{credentialsId}}',]]
                ])
            }
        }
        stage('Source Package') {
            agent {
                docker { 
                    image 'node:8.17.0' 
                }
            }
            steps {
                script {
                    sh 'npm install --registry=http://registry.npm.taobao.org'
                }
            }
        }
        stage('Image Build') {
            agent any
            steps {
                sh 'docker build -f $WORKSPACE/CI/dockerfile -t 127.0.0.1:18080/library/frontend:${_version} $WORKSPACE/target/'
                sh 'docker push 127.0.0.1:18080/library/frontend:${_version}'
                sh 'docker rmi 127.0.0.1:18080/library/frontend:${_version}'
            }
        }
        stage('Publish To Env') {
            agent any
            steps {
                script {
                    def remote = [:]
                    remote = GetRemoteServer('127.0.0.1', 'username', 'password')
                    // 更新docker-compose.yml文件,修改镜像
                    sshCommand remote: remote, command: "python3 updateImageLabel.py docker-compose.yml frontend 127.0.0.1:18080/library/frontend:${_version}"
                    sshCommand remote: remote, command: "docker-compose -f docker-compose.yml up -d --build frontend"

                }
            }
        }
        stage('Archive Package') {
            agent any
            steps {
                sh 'mkdir -p /data/archive/frontend/${branch}/${environment}/${_time}'
                sh 'cd $WORKSPACE/target/dist/ && zip -r dist.zip *'
                sh 'cp $WORKSPACE/target/dist/dist.zip /data/archive/frontend/${branch}/${environment}/${_time}'
            }
        }
    }
}

前端和后端除了构建方式不一样,其他基本都相同。

结语

参考地址:

https://www.jenkins.io/doc/book/pipeline/

https://www.jenkins.io/doc/pipeline/steps/ssh-steps/文章来源地址https://www.toymoban.com/news/detail-836122.html

到了这里,关于基于Jenkins实现的CI/CD方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Jenkins CI/CD

    1、 Jenkins CI/CD 流程图 说明:这张图稍微更形象一点,上线之前先把代码git到版本仓库,然后通过Jenkins 如Java项目通过maven去构建,这是在非容器之前,典型的自动化的一个版本上线流程。那它有哪些问题呢? 如:它的测试环境,预生产环境,测试环境。会存在一定的兼容性

    2024年02月05日
    浏览(45)
  • Jenkins与CI/CD

    Continuous  Integration是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。 Continuous Delivery一种软件

    2024年02月12日
    浏览(43)
  • nodejs前端项目的CI/CD实现(二)jenkins的容器化部署

    docker安装jenkins,可能你会反问,这太简单了,有什么好讲的。 我最近就接手了一个打包项目,它是一个nodejs的前端项目,jenkins已在容器里部署且运行OK。 但是,前端组很追求新技术,不断地升级Nodejs的版本,之前是14,现在需要升级到16。 也就是说,原本运行顺畅的打包不

    2024年01月20日
    浏览(54)
  • [Docker实现测试部署CI/CD----Jenkins集成相关服务器(3)]

             SonarScanner 是一种代码扫描工具,专门用来扫描和分析项目代码质量。扫描和分析完 成之后,会将结果写入到 SonarQube 服务器的数据库中,并在 SonarQube 平台显示这些数 据。         在 SonarQube 官网的帮助文档中可以下载 SonarScanner。这里下载一个 Linux 系统下使

    2024年02月14日
    浏览(43)
  • Jenkins分布式实现: 构建弹性和可扩展的CI/CD环境!

    Jenkins是一个流行的开源持续集成(Continuous Integration,CI)和持续交付(Continuous Delivery,CD)工具,它通过自动化构建、测试和部署过程,帮助开发团队更高效地交付软件。Jenkins的分布式实现允许将任务分散到多个计算机上执行,从而提高系统的弹性和可扩展性。本文将深入

    2024年02月01日
    浏览(63)
  • CI/CD持续集成持续发布(jenkins)

            在实际开发中,我们经常要一边开发一边测试,当然这里说的测试并不是程序员对自己代码的单元测试,而是同组程序员将代码提交后,由测试人员测试; 或者前后端分离后,经常会修改接口,然后重新部署; 这些情况都会涉及到频繁的打包部署; 手动打包常规步

    2024年02月14日
    浏览(68)
  • jenkins容器内CI/CD 项目失败问题

    1.1 原因:jenkins容器内: docker.sock 权限 1.2 问题解决方案 文件权限如下: srw-rw---- 1 root 994 0 Jun 30 06:51 docker.sock 进行权限修改 最终权限修改成功为:srw-rw-rw- 1 root root 0 Jun 30 06:51 docker.sock 2.1 问题原因 项目为前端vue,依赖于nodejs 和 npm, 需要为容器安装npm, nodejs 2.2 问题解决方

    2024年02月13日
    浏览(49)
  • Jenkins CI/CD 持续集成专题三 Jenkins 使用shell脚本打包组件配置流程

    第六步 查看编译状态和产物 到这里,jenkins 配置shell脚本打包组件的完整配置流程就已经完成

    2024年04月29日
    浏览(58)
  • 基于SNAT+DNAT发布内网K8S及Jenkins+gitlab+Harbor模拟CI/CD的综合项目

    目录 项目名称 项目架构图 项目环境 项目概述 项目准备 项目步骤 一、修改每台主机的ip地址,同时设置永久关闭防火墙和selinux,修改好主机名,在firewalld服务器上开启路由功能并配置snat策略。 1. 在firewalld服务器上配置ip地址、设置永久关闭防火墙和selinux,并修改好主机名

    2024年02月09日
    浏览(58)
  • Rancher2.7 + Jenkins CI/CD全流程保姆级最佳实践

    CI方面,官方推荐的视频教程等多是使用极狐Gitlab CI,但社区版极狐每月仅400分钟构造时间,额外购买价格为1000分钟/68元,而私有化部署极狐Gitlab对比部署使用Jenkins,具有更高的成本、更狭窄的适用面,且如果个人使用其代码仓库功能,并不比Gitee可靠。 Gitee 同样提供CI服务

    2024年02月05日
    浏览(82)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包