使用 JENKINS 实现简单的 CICD 教程
前言:
对于JENKINS,博主一直都不喜欢它。JENKINS很强大没错,可惜的是它的强大建立在插件的基础之上,这就是博主不喜欢它的原因,每次看到那一堆的插件告警提示,更新插件不是,不更新也不是,博主相信每个想玩好JENKINS的人,都有被它的插件折磨过!!!
想玩好带插件的JENKINS,是很难的,难的当然还有它的那些各种各样插件所附带的声明式语法;作为一篇简单的入门式的教程,讨论那些内容,那将必定是一场灾难!所以本篇教程,不会有插件,不会有声明式语法(也就是不会有"Pipeline"流水线),在你放弃了插件,放弃了流水线,放弃了声明式脚本,你会发觉,这个世界清静了;本篇教程只会使用JENKINS最基础的功能,从部署JENKINS至部署AGENT,最后实现CI/CD;
所以本篇教程的特点:
1、无插件;教程会教你使用DOCKER快速部署起JENKINS,这个JENKINS不会安装任何插件,即使是最基础的"中文化插件"也不会安装;
2、JENKINS设定为只提供对AGENT的管理,不参与任何实际的"CI/CD"任务,这样JENKINS就能免去所有有关"工具"的配置;
3、所有"CI/CD"任务,由AGENT完成,而AGENT是运行在DOCKER中的,所以教程同样会教你使用DOCKER快速部署起AGENT;
4、由于所有"CI/CD"任务要在AGENT中完成,而AGENT又运行在DOCKER中,所以在部署AGENT之前,需要使用DockerFile设定好AGENT中的环境,这需要你很清楚你所建立的任务,需要一个怎么样的环境;本教程不使用JENKINS中的那些"工具环境"的设定选项,直接根据需求,使用DOCKERFILE设定环境,相比使用JENKINS中的那些可视化设定工具,这种方式易于理解;
一、基础环境要求
本篇博文教程的模拟,你需要准备两台虚拟机,并且两台虚拟机已经安装好"DOCKER" 与"DOCKER-COMPOSE";另外,由于近期国内的很多原来可用的"DOCKER镜像加速"技术已经失效,你需要自行解决DOCKER镜像下载的难题,博主建议使用"设定DOCKER代理 + 科学上网"去解决镜像下载问题;
本教程设定的环境如下:
> 虚拟机(192.168.100.42):已安装好"DOCKER" + "DOCKER-COMPOSE"(Debian 12),并使用DOCKER技术运行"JENKINS";
> 虚拟机(192.168.100.56):已安装好"DOCKER" + "DOCKER-COMPOSE"(Debian 12),并使用DOCKER技术运行"AGENT";
> 目标:编译出"GITHUB - RTTY"项目的二进制可执行文件;
> 博客代码测试日期:2024年11月10日
二、部署 Jenkins (192.168.100.42)
现在,开始部署JENKINS,这里部署的JENKINS在本篇教程的设定中,只用于管理AGENT;要执行以下的命令,你需要先在LINUX系统上安装好"DOCKER"与"DOCKER-COMPOSE",博主相信,既然都看这篇博文了,那么"DOCKER"与"DOCKER-COMPOSE"的安装一定难不到读者;下面开始JENKINS的部署,也算是一个快速部署JENKINS的教程了,见下面命令与提示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# ================================================================ # IP: 192.168.100.42 # > 以下操作在"192.168.100.42"上执行 # ================================================================ # 创建必要的目录 $ mkdir -p DockerServer/jenkins_master/jenkins_home # 创建"docker-compose.yaml"文件(这个文件没有什么值得说明的) $ cat > DockerServer/docker-compose.yaml << "EOF" services: jenkins_master: image: jenkins/jenkins:2.462.3-lts container_name: jenkins_master environment: - TZ=Asia/Shanghai volumes: - /etc/localtime/:/etc/localtime:ro - /usr/share/zoneinfo/:/usr/share/zoneinfo/:ro - ./jenkins_master/jenkins_home/:/var/jenkins_home/ ports: - "50000:50000" - "80:8080" expose: - "50000" - "8080" restart: unless-stopped user: root networks: - cicd_network networks: cicd_network: name: cicd_network driver: bridge ipam: config: - subnet: 192.168.75.0/24 external: false EOF # 进入"DockerServer "目录并启动服务 $ cd DockerServer && docker-compose up -d # 查看运行状态 $ docker-compose ps |
在JENKINS服务启动后,在第一次进入WEB界面时,需要输入初始化密码以进行JENKINS服务的解锁,获取解锁密码的命令见下:
1 |
$ docker exec -it jenkins_master cat /var/jenkins_home/secrets/initialAdminPassword |
在浏览器上访问"http://192.168.100.42"并输入JENKINS的首次解锁密码:
在选择"自定义插件安装"的界面,选择"无"以不安装任何插件;JENKINS的插件安装服务对国内用户非常不友好,假若真的希望安装插件,也建议在正式进入JENKINS后,通过"配置代理"+"科学上网"的方法去下载相关插件,本教程不涉及任何插件的使用;
之后会要求配置JENKINS的域名,在本教程下,保持默认值即可;
三、部署 Agent 代理(192.168.100.56)
在部署AGENT代理之前,需要先在JENKINS的管理平台上(192.168.100.42),先配置好"AGENT NODE"的一些参数,其中最重的一个目的是"为了获取AGENT启动命令中的密钥/令牌",当然,其它参数也很重要;如何新建节点见下图:
配置AGENT代理节点的名称,本处设定为"BuildEnv_Debian12_X64",建议节点名称看起来带意义,能表明这个节点的用途;
配置节点的参数,其中最重要的是配置是AGENT代理节点上的"Name(名称)"与"Remote root Directory(工作目录)"的定义,这将影响"192.168.100.56"上,如何去创建"Dockerfile"与"docker-compose.yaml"(见后文代码说明);可配置选项见下图:
在保存完AGENT节点的配置信息后,相关节点会显示"未连接"状态,原因是我们还未运行相关节点;此时通过点击"节点"即可进入"节点的运行命令的信息界面",在这里,JENKINS会告诉我们应该如何使用命令去运行"agent.jar",其中最重要的信息就是"-secret(密钥/令牌)",当然,其它信息也很重要;
我们可以把启动命令记录在记事本中,以便于之后编写"Dockerfile"与"docker-compose.yaml";
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# AGENT的启动命令 # -jar :... # -url :URL # -secret :AGENT节点要加入JENKINS所使用的密钥/令牌 # -name :节点名称(应该与之前的配置相同) # -workDir :AGENT节点的工作目录 # -webSocket :以"WEBSOCKET"运行 # > JENKINS没提示这个参数,但不使用这个参数,AGENT在使用DOCKER运行很可能连不上JENKINS # > 本教程使用了此参数(见下文的"docker-compose.yaml") $ java -jar agent.jar -url http://192.168.100.42/ \ -secret 812bdcb4465a215713953b77ea75a230b2450523b9e893ae58ca8ad061ad126f \ -name "BuildEnv_Debian12_X64" \ -workDir "/agentWorkDir" |
在有了以上信息后,至"192.168.100.56"上,创建运行"AGENT代理"所需要的相关DOCKER文件;执行以下命令(其中如何去创建"Dockerfile"是最重要的,见说明):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# ================================================================ # IP: 192.168.100.56 # > 以下操作在"192.168.100.56"上执行 # ================================================================ # 创建必要的目录 $ mkdir -p DockerServer/jenkins_agent_01/{build,agentWorkDir} # 创建"docker-compose.yaml"文件 # > 注意"environment"的定义(参照AGENT节点的启动命令进行修改) # > 注意挂载的目录(不是必须但建议) # > 注意启用了"WEBSOCKET" $ cat > DockerServer/docker-compose.yaml << "EOF" # jenkins_agent_01 services: jenkins_agent_01: build: ./jenkins_agent_01/build image: jenkins_agent_01:BuildEnv_Debian12_X64 container_name: jenkins_agent_01 environment: - TZ=Asia/Shanghai - JENKINS_URL=http://192.168.100.42/ - JENKINS_SECRET=812bdcb4465a215713953b77ea75a230b2450523b9e893ae58ca8ad061ad126f - JENKINS_AGENT_NAME=BuildEnv_Debian12_X64 - JENKINS_AGENT_WORKDIR=/agentWorkDir - JENKINS_WEB_SOCKET=true volumes: - /etc/localtime/:/etc/localtime:ro - /usr/share/zoneinfo/:/usr/share/zoneinfo/:ro - ./jenkins_agent_01/agentWorkDir/:/agentWorkDir restart: unless-stopped networks: - cicd_network networks: cicd_network: name: cicd_network driver: bridge ipam: config: - subnet: 192.168.75.0/24 external: false EOF # 创建"Dockerfile"文件 # 1、运行AGENT所使用的基础镜像是"jenkins/inbound-agent:bookworm-jdk17",该镜像只提供了对于"agent.jar"的 # 最基础的运行环境;而作为一个AGENT节点,你需要适当的修改镜像的环境,去适配你所需要做的事;例如,本教程的目标 # 是编译RTTY项目的二进制文件,要实现这个目标,首先编译环境需要补充相关的依赖(ibev-dev、libssl-dev、cmake), # 再次,由于需要到GITHUB拉取源代码,所以我们需要安装"git";有关这些操作,不同项目的需求是不同的; # 2、测试,对于其它项目,你应该先确认使用的DOCKERFILE所创建出来的容器的运行环境,满足你的项目需求,这就需要你 # 测试DOCKEFILE的所建立环境的正确性;博文就测试出"curl"命令不满足"git"命令的运行要求,所以在DOCKERFILE中 # 更新了"curl"命令; # 3、当你,既然你都看JENKINS了,我相信关于项目依赖这些知识点你是懂的,每个项目所依赖的环境都不一样,博主也只 # 像现在这样简单的解释一下,至少下面的DOCKERFILE并不是随便写的; $ cat > DockerServer/jenkins_agent_01/build/Dockerfile << "EOF" FROM jenkins/inbound-agent:bookworm-jdk17 USER root RUN set -ex \ && echo 'deb https://mirrors.aliyun.com/debian bookworm main contrib non-free non-free-firmware' > /etc/apt/sources.list \ && rm /etc/apt/sources.list.d/* \ && apt-get update && apt-get -y install libev-dev libssl-dev busybox RUN set -ex \ && apt-get -y install curl cmake git \ && mkdir -p /agentWorkDir EOF # 进入"DockerServer "目录并启动服务 $ cd DockerServer && docker-compose up -d # 查看运行状态 $ docker-compose ps # ================================================================ |
在成功运行起AGENT代理节点后,返回JENKINS控制台的节点页面(192.168.100.42),你可以发现AGENT节点已经正确连接上JENKINS控制台了;
四、任务创建 (192.168.100.56)
在AGENT节点成功连接上JENKINS控制台后,现在可以开始创建关于"RTTY编译"的任务了,而任务的目标是"成功编译出RTTY项目的二进制文件";之所使用"RTTY"项目,是因为这个项目足够的简单;
本处使用"自由风格的项目/任务"方式(没有"Pipeline(流水线)");本篇教程目标就像你第一次学编辑语言时教你写"HELLO WORLD"一样,目标是让读者知道什么是CICD,如何用最简单的方式去实现一次JENKINS的任务执行流程;再说,很多时候,我们只需要实现目标就可以了,杀鸡真的不需要使用牛刀;再再说,不使用插件,不使用JENKINS推荐的声明式语法,就使用其最默认的功能,其实也可以做很多很的事;
在创建任务之前,应该先至"GITHUB - RTTY"项目上,查看相关文档,看看在编译RTTY之前及之后,我们需要做什么,见下说明:
1 2 3 4 5 6 7 8 9 10 11 12 |
# ================================================================ # GitHub : https://github.com/zhaojh329/rtty # ================================================================ # 1、其中的"${BUILD_ID}"是JENKINS的内置变量,表示"构建的任务号" # 2、访问"RTTY"项目,可以得出要编译出"rtty"二进制可执行文件,需要执行 # 以下命令; # 3、当然,执行这些命令的前置是,AGENT容器内的环境满足要求,这件事在我 # 写DOCKERFILE时已经做了; mkdir -p build_${BUILD_ID} && cd build_${BUILD_ID} git clone --recursive https://github.com/zhaojh329/rtty.git cd rtty && mkdir build && cd build cmake .. && make install |
下面创建一个名为"RTTY_BUILD"的任务,使用"Freestyle Project"类型,见下图;
然后进行任务选项的参数值设定,其中博主定义了:
A、设定任务强制在"BuildEnv_Debian12_X64"的AGENT节点上执行(前面AGENT的名称);
B、建立了一个"Execute Shell"的步骤,然后将相关的编译RTTY所需要的命令填入文本框中(这些命令将会在"BuildEnv_Debian12_X64"的SHELL环境下执行);
C、有需要你可以进行一些其它选项的定义,本教程不额外使用这些功能,避免增加教程复杂度;
在任务的所有需要的选项设定完成后,就可以使用"Build Now"执行之前定义的"RTTY_BUILD"任务了;等待任务执行完成(期间你可以点击"#X"然后从控制台看到任务在AGENT上的执行过程);之后,就可以从"Workspace"查看到任务中的执行结果了,在对应目录中,"rtty"二进制执行文件被成功的编译了出来;
五、总结
至此,本篇教程的简单教学已经写完了;反观之前的博文,整个流程下来,实际上只完成了"CI(持续集成)"的部分,但是,既然你已经会"CI"了,难道还能不会"CD(持续交付/持续部署)"吗?"CD"不就是把上面教程中"CI"的命令换成"CD"的命令就可以了吗?所以,其实看完本篇教程,你已经会"CI/CD"了!剩下的,你只需要把JENKINS中的一些其它功能进行学习及应用就可以了;
本篇博文很少说PIPELINE,这个东西是官方极力推荐的,不算易学也不算难学,但如果你学过,你可以发现其功能的确是非常的强大,不过很可惜的是其强大依赖于插件,更可惜的是所有插件的稳定性真的一言难尽;插件间复杂的依赖关系,各种安全警告,各种更新JENKINS后的不兼容,密集的插件更新频率,这些问题无一让博主讨厌起其PIPELINE,能使用JENKINS的一般是运维,运维最期望的事是稳定,JENKINS的插件就是反运维;再说了,SHELL够强大了,再加上"DOCKER AGENT",能不使用PIPELINE,还是别用了吧!
虽然,博主上面如此评论PIPELINE,但博主实际上在PIPELINE应用上也不算是特别的强,如果你觉得PIPELINE很好,博主也是同意的;但对于JENKINS,博主真的不太喜欢它,一是界面有点过时(官方有相关的插件界面,更时尚,但为什么又是插件);二是使用起来的门槛也不少;三是JAVA项目通病,系统资源占用高;四、还是插件问题;
最近看到一个开源的CICD项目,叫"GoCD",简单看了一下,看上去不错,如果有需要及可能,博主应该会更喜欢"GoCD";写到这里,算了吧~~~
使用 JENKINS 实现简单的 CICD 教程:等您坐沙发呢!