# jenkins **Repository Path**: guojianwang/jenkins ## Basic Information - **Project Name**: jenkins - **Description**: Jenkins教程(从配置到实战) - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: https://www.bilibili.com/list/watchlater?bvid=BV1bS4y1471A&oid=729248896&p=1 - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2024-06-18 - **Last Updated**: 2025-11-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #
Jenkins
*** ## 目录 - [Jenkins](#jenkins) - [目录](#目录) - [1.GitLab安装使用](#1gitlab安装使用) - [1.1.在ssh下安装](#11在ssh下安装) - [1.1.1.安装依赖](#111安装依赖) - [1.1.2.配置镜像](#112配置镜像) - [1.1.3.开始安装](#113开始安装) - [1.1.4.gitlab常用命令](#114gitlab常用命令) - [1.2.在docker下安装](#12在docker下安装) - [1.2.1.安装docker](#121安装docker) - [1.2.2.使用容器安装gitlab](#122使用容器安装gitlab) - [1.2.3.访问](#123访问) - [1.2.4.管理员账号登录](#124管理员账号登录) - [2.Jenkins安装](#2jenkins安装) - [2.1.安装JDK](#21安装jdk) - [2.2.Maven安装](#22maven安装) - [3.Jenkins + Git + Maven 自动化部署配置](#3jenkins--git--maven-自动化部署配置) - [1.Git配置](#1git配置) - [2.Maven配置](#2maven配置) - [3.Pom.xml配置](#3pomxml配置) - [4.git安装](#4git安装) - [3.4.1.javahome配置(可选)](#341javahome配置可选) - [3.4.2.报错找不到jdk?](#342报错找不到jdk) - [3.4.3.Maven阿里云镜像](#343maven阿里云镜像) - [5.publish over ssh 配置](#5publish-over-ssh-配置) - [3.5.1.超时机制](#351超时机制) - [3.5.2.shell的日志输出](#352shell的日志输出) - [3.5.3.数据流重定向](#353数据流重定向) - [6.运行前清理](#6运行前清理) - [7.几种构建方式](#7几种构建方式) - [3.7.1.触发远程构建/gitlab上改动自动构建](#371触发远程构建gitlab上改动自动构建) - [3.7.2.定时构建](#372定时构建) - [Jenkins cron表达式](#jenkins-cron表达式) - [3.7.3.源码变更构建](#373源码变更构建) - [8.测试报告邮件通知](#8测试报告邮件通知) - [9.自动化部署到docker容器中](#9自动化部署到docker容器中) - [3.9.1.docker外挂目录](#391docker外挂目录) - [3.9.2.打包到容器内](#392打包到容器内) - [4.Jenkins集群/并发构建](#4jenkins集群并发构建) - [5.流水线 pipeline](#5流水线-pipeline) - [5.1.完整语法](#51完整语法) - [5.2.测试脚本](#52测试脚本) - [5.2.1.基础框架](#521基础框架) - [5.2.2.阶段视图 Stage View](#522阶段视图-stage-view) - [5.2.3.blue ocean可视化界面](#523blue-ocean可视化界面) - [5.2.4.post](#524post) - [5.2.5.agent](#525agent) - [5.3.pipeline中执行自动化构建](#53pipeline中执行自动化构建) - [5.3.1.声明式流水线](#531声明式流水线) - [5.3.2.脚本式流水线](#532脚本式流水线) *** Jenkins,原名 Hudson,2011 年改为现在的名字。它是一个开源的实现持续集成的软件工具。 官方网站 *** ## 1.GitLab安装使用 官方网站: 安装所需最小配置 内存至少4G *** ### 1.1.在ssh下安装 *** 官方安装文档: #### 1.1.1.安装依赖 *** ```shell sudo yum install -y curl policycoreutils-python openssh-server perl sudo systemctl enable sshd sudo systemctl start sshd ``` *** #### 1.1.2.配置镜像 *** ```shell curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash ``` *** #### 1.1.3.开始安装 *** ```shell sudo EXTERNAL_URL="http://192.168.44.103" yum install -y gitlab-jh ``` 除非您在安装过程中指定了自定义密码,否则将随机生成一个密码并存储在 `/etc/gitlab/initial_root_password` 文件中(出于安全原因,24 小时后,此文件会被第一次 `gitlab-ctl reconfigure` 自动删除,因此若使用随机密码登录,建议安装成功初始登录成功之后,立即修改初始密码)。使用此密码和用户名 `root` 登录。 *** #### 1.1.4.gitlab常用命令 *** ```shell gitlab-ctl start # 启动所有 gitlab 组件; gitlab-ctl stop # 停止所有 gitlab 组件; gitlab-ctl restart # 重启所有 gitlab 组件; gitlab-ctl status # 查看服务状态; gitlab-ctl reconfigure # 启动服务; vi /etc/gitlab/gitlab.rb # 修改默认的配置文件; gitlab-ctl tail # 查看日志; ``` *** ### 1.2.在docker下安装 *** 安装所需最小配置 - 内存至少4G - 系统内核至少在3.10以上 `uname -r` 命令可查看系统内核版本 *** #### 1.2.1.安装docker *** 1. 更新yum源 ​ `yum update` 2. 安装依赖 ​ `yum install -y yum-utils device-mapper-persistent-data lvm2` 3. 添加镜像 ```shell //国外镜像 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo //阿里镜像 https://mirrors.aliyun.com/docker-ce/linux/centos/gpg yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo ``` 4. 查看源中可使用版本 ```shell yum list docker-ce --showduplicates | sort -r ``` 5. 安装指定版本 ```shell yum install docker ``` 6. 配置开机启动项 ```shell systemctl start docker systemctl enable docker docker version ``` *** #### 1.2.2.使用容器安装gitlab *** 1. 添加容器 ```shell docker run --detach \ --hostname 192.168.44.103 \ --publish 443:443 --publish 80:80 \ --name gitlab \ --restart always \ --volume $GITLAB_HOME/config:/etc/gitlab:Z \ --volume $GITLAB_HOME/logs:/var/log/gitlab:Z \ --volume $GITLAB_HOME/data:/var/opt/gitlab:Z \ --shm-size 256m \ registry.gitlab.cn/omnibus/gitlab-jh:latest ``` 2. 启动容器 ```shell docker start gitlab ``` 3. 查看已存在的容器 ```shell docker ps -a ``` 4. 进入容器 ```shell docker exec -it gitlab /bin/bash ``` *** #### 1.2.3.访问 *** 当首次运行出现502错误的时候排查两个原因 1. 虚拟机内存至少需要4g 2. 稍微再等等刷新一下可能就好了 *** #### 1.2.4.管理员账号登录 *** 用户名:root 密码存在下面文件中,登录后需要改密码不然24小时之后会失效 ```shell cat /etc/gitlab/initial_root_password ``` *** ## 2.Jenkins安装 *** 官方文档介绍非常详细 安装需求 ```shell 机器要求: 256 MB 内存,建议大于 512 MB 10 GB 的硬盘空间(用于 Jenkins 和 Docker 镜像) 需要安装以下软件: Java 8 ( JRE 或者 JDK 都可以) Docker (导航到网站顶部的Get Docker链接以访问适合您平台的Docker下载) ``` *** ### 2.1.安装JDK *** 1. 检索可用包 ```shell yum search java|grep jdk ``` 2. 安装 ```shell yum install java-1.8.0-openjdk ``` 首次启动war包会在`/root/.jenkins`生成配置文件 待完全启动成功后 访问服务器8080端口完成配置 初始化后的密码: ```shell Jenkins initial setup is required. An admin user has been created and a password generated. Please use the following password to proceed to installation: 4e67bbe261da476abdc63c5b51311646 This may also be found at: /root/.jenkins/secrets/initialAdminPassword ``` 密码文件使用后会自动删除 *** ### 2.2.Maven安装 *** 官网 下载后复制到Jenkins所在服务器解压缩即可 *** ## 3.Jenkins + Git + Maven 自动化部署配置 *** ### 1.Git配置 *** ![image-20220726213303821](images/image-20220726213303821.png) ![image-20220726213505879](images/image-20220726213505879.png) *** ### 2.Maven配置 *** ![image-20220726214239888](images/image-20220726214239888.png) *** ### 3.Pom.xml配置 *** ![image-20220726214200732](images/image-20220726214200732.png) *** ### 4.git安装 *** ```shell yum install -y git ``` *** #### 3.4.1.javahome配置(可选) *** ```shell /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-1.el7_9.x86_64 export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-1.el7_9.x86_64 export JRE_HOME=$JAVA_HOME/jre PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin export JAVA_HOME JRE_HOME CLASS_PATH PATH jdk /etc/alternatives/jre_openjdk source /etc/profile 立即生效 ``` *** #### 3.4.2.报错找不到jdk? *** ```shell 默认yum安装java的时候会显示安装的是openjdk1.8 实则实际上只安装了jre yum install -y java-devel ``` *** #### 3.4.3.Maven阿里云镜像 *** 修改`/usr/local/maven/conf/settings.xml` ```xml ${user.home}/.m2/repository org.mortbay.jetty releases ali ali Snapshots ali ali nexus * http://maven.aliyun.com/nexus/content/groups/public/ nexus-public-snapshots public-snapshots http://maven.aliyun.com/nexus/content/repositories/snapshots/ nexus-public-snapshots1 public-snapshots1 https://artifacts.alfresco.com/nexus/content/repositories/public/ development central http://central true always true always central http://central true always true always public-snapshots public-snapshots http://public-snapshots false true always public-snapshots http://public-snapshots false true always development public-snapshots ``` *** ### 5.publish over ssh 配置 *** 1 安装插件 在Configure System菜单里 往下来 2 添加一台目标服务器 ![image-20220726223917263](images/image-20220726223917263.png) ![image-20220726223937722](images/image-20220726223937722.png) 3 修改配置 ![image-20220727165700419](images/image-20220727165700419.png) *** #### 3.5.1.超时机制 *** 输出命令时一定要注意不要让窗口卡主,不然Jenkins会认为认为一直没完成 *** #### 3.5.2.shell的日志输出 *** ```shell nohup java -jar /root/xxoo/demo*.jar >mylog.log 2>&1 & ``` *** #### 3.5.3.数据流重定向 *** 数据流重定向就是将某个命令执行后应该要出现在屏幕上的数据传输到其他地方 标准输入(stdin):代码为0,使用<或<<; 标准输出(stdout):代码为1,使用>或>>; 标准错误输出(stderr):代码为2,使用2>或2>> \> 覆盖写 \>> 追加写 *** ### 6.运行前清理 *** 配置杀死之前运行的进程 ```shell #!/bin/bash #删除历史数据 rm -rf xxoo appname=$1 #获取传入的参数 echo "arg:$1" #获取正在运行的jar包pid pid=`ps -ef | grep $1 | grep 'java -jar' | awk '{printf $2}'` echo $pid #如果pid为空,提示一下,否则,执行kill命令 if [ -z $pid ]; #使用-z 做空值判断 then echo "$appname not started" else kill -9 $pid echo "$appname stoping...." check=`ps -ef | grep -w $pid | grep java` if [ -z $check ]; then echo "$appname pid:$pid is stop" else echo "$appname stop failed" fi fi ``` *** ### 7.几种构建方式 *** - 快照依赖构建/Build whenever a SNAPSHOT dependency is built - 当依赖的快照被构建时执行本job - 触发远程构建 (例如,使用脚本) - 远程调用本job的restapi时执行本job - job依赖构建/Build after other projects are built - 当依赖的job被构建时执行本job - 定时构建/Build periodically - 使用cron表达式定时构建本job - 向GitHub提交代码时触发Jenkins自动构建/GitHub hook trigger for GITScm polling - Github-WebHook出发时构建本job - 定期检查代码变更/Poll SCM - 使用cron表达式定时检查代码变更,变更后构建本job *** #### 3.7.1.触发远程构建/gitlab上改动自动构建 *** 代码改动自动可以使用gitlab的webhook回调钩子调起Jenkins的启动任务接口 在构建触发器中配置接口和token ![image-20220728170250273](images/image-20220728170250273.png) *** #### 3.7.2.定时构建 *** ##### Jenkins cron表达式 标准cron Jenkins cron不是标准的cron表达式 ```shell 第一个 * 表示每个小时的第几分钟,取值0~59 H * * * * H:每小时执行一次 第二颗 * 表示小时,取值0~23 * 15 * * * 表示每天下午3点 * 1 * * * 表示每天凌晨1点 第三颗 * 表示一个月的第几天,取值1~31 * 1 5 * * 表示每月5日凌晨1点 第四颗 * 表示第几月,取值1~12 * 15 5 1 * 表示每年几月执行 第五颗 * 表示一周中的第几天,取值0~7,其中0和7代表的都是周日 ``` **“/”:** 表示每隔多长时间,比如 */10* ** * 表示 每隔10分钟 **“H”:** hash散列值,以job名取值,获取到以job名为入参的唯一值,相同名称值也相同,这个偏移量会和实际时间相加,获得一个真实的运行时间 意义在于:不同的项目在不同的时间运行,即使配置的值是一样的,比如 都是`15 * * * *` ,表示每个小时的第15分钟开始执行任务,那么会造成同一时间内在Jenkins中启动很多job,换成`H/15 * * * *` ,那么在首次启动任务时,会有随机值参与进来,有的会在17分钟启动 有的会在19分钟启动,随后的启动时间也是这个值。这样就能错开相同cron值的任务执行了。 H的值也可以设置范围 `H * * * *`表示一小时内的任意时间 `*/10 * * * *`每10分钟 `H/10 * * * *`每10分钟,可能是7,17,27,起始时间hash,步长不变 `45 3 * * 1-6` 每个周一至周六,凌晨3点45 执行1次 `45 3-5 * * 1-6` 每个周一至周六,凌晨3点45 ,凌晨4点45,凌晨5点45 各执行1次 `H(40-48) 3-5 * * 1-6` 在40~48之间取值 其他同上 `45 3-5/2 * * 1-6` 每个周一至周六,凌晨3点45 ,凌晨5点45 各执行1次 ` 45 0-6/2 * * 1-6 * * 1-6 ` 0点开始,每间隔2小时执行一次 0:45、2:45、4:45 *** #### 3.7.3.源码变更构建 *** 使用Poll SCM 方式与Build periodically一样 会主动定期检查代码托管服务器上是否有变化,一旦发生变化执行job构建 *** ### 8.测试报告邮件通知 *** 使用163免费邮箱发送邮件时注意密码填认证码,也就是发送手机短信后给的那个,不要用登录邮箱的密码 类似下面。。 ```shell KDWJUWDQBWMOYGDC ``` *** ### 9.自动化部署到docker容器中 *** #### 3.9.1.docker外挂目录 *** ```shell docker run -d -p 8080:8080 --name demo-out -v /root/jarfile/demo-1-0.0.1-SNAPSHOT.jar:/app.jar openjdk:11 java -jar app.jar ``` *** #### 3.9.2.打包到容器内 *** 1. 准备一台测试服务器 docker环境 2. 准备支持jdk的镜像 ```shell FROM openjdk:11 COPY . /usr/src/myapp WORKDIR /usr/src/myapp RUN javac Main.java CMD ["java", "Main"] ``` 1. 把jar包打包到容器内 dockerfile ```dockerfile FROM openjdk:11 EXPOSE 8080 WORKDIR /root ADD jarfile/demo*.jar /root/app.jar ENTRYPOINT ["java","-jar","/root/app.jar"] ``` 打包镜像 ```shell docker build -t demo . ``` 配置国内镜像 修改`/etc/docker/daemon.json`文件,没有的话创建一个 写入 ```json { "registry-mirrors": [ "https://ustc-edu-cn.mirror.aliyuncs.com", "http://hub-mirror.c.163.com", "https://registry.aliyuncs.com" ] } ``` 重启服务 ```shell systemctl daemon-reload systemctl restart docker ``` *** ## 4.Jenkins集群/并发构建 *** 集群化构建可以有效提升构建效率,尤其是团队项目比较多或是子项目比较多的时候,可以并发在多台机器上执行构建。 *** ## 5.流水线 pipeline *** 流水线既能作为任务的本身,也能作为Jenkinsfile 使用流水线可以让我们的任务从ui手动操作,转换为代码化,像docker的dockerfile一样,从shell命令到配置文件,更适合大型项目,可以让团队其他开发者同时参与进来,同时也可以编辑开发Jenkinswebui不能完成的更复杂的构建逻辑,作为开发者可读性也更好。 *** ### 5.1.完整语法 *** 5个必备的组成部分 ```shell pipeline:整条流水线 agent:指定执行器 stages:所有阶段 stage:某一阶段,可有多个 steps:阶段内的每一步,可执行命令 ``` *** ### 5.2.测试脚本 *** #### 5.2.1.基础框架 *** ```shell pipeline { agent any stages { stage('拉取代码') { steps { echo '拉取代码完成' } } stage('执行构建') { steps { echo '执行构建完成' } } } post { always { echo "完成" } failure { echo "失败" } } } ``` *** #### 5.2.2.阶段视图 Stage View *** #### 5.2.3.blue ocean可视化界面 *** 全新的流水线控制ui,可重复执行某阶段代码 插件中心搜索blue ocean安装即可 *** #### 5.2.4.post *** 流水线完成后可执行的任务 - always 无论流水线或者阶段的完成状态。 - changed 只有当流水线或者阶段完成状态与之前不同时。 - failure 只有当流水线或者阶段状态为"failure"运行。 - success 只有当流水线或者阶段状态为"success"运行。 - unstable 只有当流水线或者阶段状态为"unstable"运行。例如:测试失败。 - aborted 只有当流水线或者阶段状态为"aborted "运行。例如:手动取消。 *** #### 5.2.5.agent *** 可以指定执行节点 label 指定运行job的节点标签 any 不指定,由Jenkins分配 ```shell pipeline { agent { node { label "jenkins-02" } } stages { stage('拉取代码') { steps { sh """ sleep 10 """ echo '拉取代码完成' } } stage('执行构建') { steps { echo '执行构建完成' } } } post { always { echo "完成" } failure { echo "失败" } } } ``` *** ### 5.3.pipeline中执行自动化构建 *** ```shell pipeline { agent any tools { maven "maven3" } stages { stage("拉取代码") { steps { git branch: 'main', credentialsId: 'gitlab', url: 'http://192.168.44.103/root/java-project.git' echo '拉取成功' } } stage("执行构建") { steps { // sh "mvn --version" sh """ cd demo-1 mvn clean package """ echo '构建完成' } } stage("clean test server"){ steps{ sshPublisher(publishers: [sshPublisherDesc(configName: 'testserver', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''rm -rf * docker stop demo docker rm demo docker rmi demo ''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '/root')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } } stage("发送jar包到测试服务器") { steps { sshPublisher(publishers: [sshPublisherDesc(configName: 'testserver', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/jarfile', remoteDirectorySDF: false, removePrefix: 'demo-1/target', sourceFiles: '**/demo*.jar'), sshTransfer(cleanRemote: false, excludes: '', execCommand: '''docker build -t demo . docker run -d -p 8080:8080 --name demo demo''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/', remoteDirectorySDF: false, removePrefix: 'demo-1/docker', sourceFiles: 'demo-1/docker/dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) echo 'jar send over!' } } } } ``` *** #### 5.3.1.声明式流水线 *** 好处 - 更像是在Jenkins web ui中的操作 - 可读性比较高 - 可以使用blue ocean自动生成 - 支持语法检查 坏处 - 代码逻辑能力比脚本式弱,不能完成特别复杂的任务 *** #### 5.3.2.脚本式流水线 *** 好处 - 更少的代码和弱规范要求 - 更灵活的自定义代码操作 - 不受约束,可以构建特别复杂的工作流和流水线 坏处 - 读写对编程要求比较高 - 比声明式流水线代码更复杂 ***