Jenkins
一、Jenkins安装
基础环境准备
#关闭防火墙和SELinux
#设置语言环境,防止后期Jenkins汉化出问题
[root@jenkins ~]# localectl set-locale LANG=en_US.UTF-8
# 准备java环境
https://www.jenkins.io/doc/book/platform-information/support-policy-java/
apt update && apt -y install openjdk-21-jdk
#新版jenkins_2.479.1后要求安装JDK-17版
[root@ubuntu2404 ~]#apt update && apt -y install openjdk-17-jdk
[root@rocky8 ~]#yum -y install java-17-openjdk
#要求安装JDK-11版的基础环境配置
[root@ubuntu2004 ~]#apt update && apt -y install openjdk-11-jdk
[root@rocky8 ~]#yum -y install java-11-openjdk
#旧版安装JDK-8版
[root@ubuntu1804 ~]#apt update
[root@ubuntu1804 ~]#apt -y install openjdk-8-jdk
#或者安装oracle的jdk
[root@ubuntu1804 /usr/local/src]# tar xvf jdk-8u192-linux-x64.tar.gz
[root@ubuntu1804 /usr/local/src]# ln -sv /usr/local/src/jdk1.8.0_192/
/usr/local/jdk
[root@ubuntu1804 /usr/local/src]# ln -sv /usr/local/jdk/bin/java /usr/bin/ #java
命令软连接
[root@ubuntu1804 /usr/local/src]# vim /etc/profile
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
[root@ubuntu1804 /usr/local/src]# source /etc/profile
[root@ubuntu1804 /usr/local/src]# java -version
包安装Jenkins
# 一、Ubuntu系统
apt -y install openjdk-11-jdk
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
apt-get update
apt-get install jenkins
apt list jenkins -a
deb 包下载地址国内镜像站点
https://mirrors.aliyun.com/jenkins/debian-stable/
https://mirror.tuna.tsinghua.edu.cn/jenkins/debian-stable/
# 二进制包安装jenkins
apt update && apt -y install openjdk-17-jdk
wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/debian-stable/jenkins_2.492.1_all.deb
dpkg -i jenkins_2.492.1_all.deb
# ubuntu安装后默认会自启动
systemctl status jenkins.service
cat /var/lib/jenkins/secrets/initialAdminPassword
# 二、CentOS系统
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install jenkins
# rpm包国内镜像下载链接
https://mirrors.aliyun.com/jenkins/redhat-stable/
https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/
#CentOS二进制包安装jenkins
yum install java
wget https://mirrors.aliyun.com/jenkins/redhat-stable/jenkins-2.289.2-1.1.noarch.rpm
yum -y install jenkins-2.289.2-1.1.noarch.rpm
rpm -ql jenkins
systemctl start jenkins.service
grep -A2 password /var/log/jenkins/jenkins.log
#查看第一次的登录密码
cat /var/lib/jenkins/secrets/initialAdminPassword
#默认配置
[root@centos8 ~]#grep -v "#" /etc/sysconfig/jenkins | grep -v "^$"
基于war包安装Jenkins
下载链接
官网: https://get.jenkins.io/war-stable/
国内镜像代理站: https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/
安装
1、直接java -jar启动
wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/latest/jenkins.war
apt update && apt install openjdk-11-jdk -y
java -jar jenkins.war --httpPort=9090
2、基于tomcat启动
apt update && apt install openjdk-21-jre tomcat10
cp jenkins.war /var/lib/tomcat10/webapps/
vim /lib/systemd/system/tomcat10.service
# Security #修改为root启动,否则提示Caused by: java.nio.file.FileSystemException:
/var/lib/tomcat: Read-only file system
#User=tomcat
#Group=tomcat
systemctl daemon-reload && systemctl restart tomcat10
基于Docker安装Jenkins
# 方式1
docker run -d --name jenkins -p 8080:8080 -p 50000:50000 --restart=always -v jenkins_home:/var/jenkins_home jenkins/jenkins:2.401.1-lts-jdk11
# 方式2
docker run -u root \
-d -p 8080:8080 \
-p 50000:50000 \
-v jenkins-data:/var/jenkins_home \
-v /etc/localtime:/etc/localtime:ro \
-v /var/run/docker.sock:/var/run/docekr.sock \
--restart=always \
jenkinsci/blueocean
#镜像jenkinsci/jenkins 是没有blueocean插件的,需要自己装
#镜像jenkinsci/blueocean:内置bluecocean插件
#/var/run/docker.sock 表示Docker守护程序通过其监听的基于Unix的套接字。该映射允许jenkinsci/blueocean容器与Docker守护进程通信,如果jenkinsci/blueocean容器需要实例化其他Docker容器,则该守护进程是必需的。如果运行声明式管道,其语法包含agent部分用docker;例如,agent{ docker {... }}此选项是必需的。
基于Kubernetes安装Jenkins
#Helm安装
https://www.jenkins.io/doc/book/installing/kubernetes/#install-jenkins-with-helm-v3
#YAML文件安装
https://www.jenkins.io/doc/book/installing/kubernetes/#install-jenkins-with-yaml-files
#Operator安装
https://www.jenkins.io/doc/book/installing/kubernetes/#install-jenkins-with-jenkins-operator
示例基于Storage class 的部署yaml
cat jenkins-deployment-service-pvc-sc-rbac.yaml
apiVersion: v1
kind: Namespace
metadata:
name: jenkins
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: jenkins
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: sc-nfs #需要提前准备名称为 sc-nfs的StorageClass
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-master
namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: jenkins-master
rules:
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- apiGroups: [""]
resources: ["services"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins-master
roleRef:
kind: ClusterRole
name: jenkins-master
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: jenkins-master
namespace: jenkins
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
serviceAccountName: jenkins-master
containers:
- name: jenkins
image: jenkins/jenkins:lts
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 50000
name: agent
protocol: TCP
volumeMounts:
- name: jenkins-volume
mountPath: /var/jenkins_home
volumes:
- name: jenkins-volume
persistentVolumeClaim:
claimName: jenkins-pvc
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: jenkins
spec:
type: LoadBalancer #需要提前准备名OpenELB服务
ports:
- name: http
port: 8080
targetPort: 8080
- name: agent
port: 50000
targetPort: 50000
selector:
app: jenkins
二、Jenkins插件管理
官网插件地址: https://plugins.jenkins.io/
# 插件安装目录
ls /var/lib/jenkins/plugins/
# 加速插件安装速度
# 方案一:更改 Jenkins 的镜像源为国内镜像站
# 注意:此修改只是临时性,服务重启后会自动还原
sed -i.bak 's#updates.jenkins.io/download#mirror.tuna.tsinghua.edu.cn/jenkins#g' /var/lib/jenkins/updates/default.json
sed -i 's#www.google.com#www.baidu.com#g' /var/lib/jenkins/updates/default.json
#注意:如果是tomcat运行war包方式需要下面路径
sed -i.bak
's#https://updates.jenkins.io/download#https://mirror.tuna.tsinghua.edu.cn/jenkins#g' /root/.jenkins/updates/default.json
# 将升级站点URL替换成下面国内镜像地址
Jenkins页面-->Manage Jeninks-->Plugins
将升级站点URL替换成下面国内镜像地址,提交后再次安装插件即可
#查看镜像源
http://mirrors.jenkins-ci.org/status.html
#默认镜像源
https://updates.jenkins.io/update-center.json
#国内镜像源
https://mirror.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
https://mirrors.aliyun.com/jenkins/updates/update-center.json
# 重启服务
# 方案二:加速插件更新和安装
# 参考项目
https://github.com/lework/jenkins-update-center
#测试各镜像站点的速度:
~# curl -sSL https://cdn.jsdelivr.net/gh/lework/jenkins-update-center/speed-test.sh | bash
#关闭数字证书签名认证:
~# sed -i 's#$JENKINS_JAVA_OPTIONS#$JENKINS_JAVA_OPTIONS -Dhudson.model.DownloadService.noSignatureCheck=true#g' /etc/init.d/jenkins
~# systemctl daemon-reload
#替换引用的更新配置文件:
~# sed -i 's#https://updates.jenkins.io/update-center.json#https://cdn.jsdelivr.net/gh/lework/jenkins-update-center@master/updates/ustc/update-center.json#gi' /var/lib/jenkins/hudson.model.UpdateCenter.xml
~# rm -f /var/lib/jenkins/updates/default.json
~# systemctl restart jenkins
# 方案三:Jenkins 官网或镜像网站下载想要的插件文件,再导入到 Jenkins 中
# 国内镜像站点插件下载地址:
http://updates.jenkins-ci.org/download/plugins/
https://updates.jenkins.io/download/plugins/
https://mirrors.aliyun.com/jenkins/plugins/
https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/
# 方案四: 离线插件包复制至插件安装目录
可以将其它主机的已安装好的插件打包后,再将之导入到安装插件目录即可
[root@jenkins ~]#systemctl stop jenkins
[root@jenkins ~]#tar jenkins_plugins.tar.gz -C /var/lib/jenkins/plugins/
[root@jenkins ~]#chown -R jenkins.jenkins /var/lib/jenkins/plugins/
[root@jenkins ~]#systemctl start jenkins
三、JenkinsCICD相关
一、Jenkins内置环境变量
# Jenkins内置的常用的环境变量
JENKINS_HOME:Jenkins的家目录
JENKINS_URL:Jenkins服务的URL
JOB_NAME:当前作业的名称
BUILD_NUMBER:构建号,递增的整数值;打包时,经常用作制品名称的一部分
BRANCH_NAME:在多分支pipeline中,需要根据不同的分支施加不同的操作时较为常用
BUILD_URL:当前构建页面的URL,常用于邮件通知中
GIT_BRANCH:基于git拉取的源码进行构建时使用该变量
注意:Jenkins的环境变量和root用户看到环境变量不完全相同
Jenkins的管理页面查看到内置变量
http://jenkins-server:8080/env-vars.html/
http://jenkins.wang.org:8080/systemInfo
二、Pipeline
Pipeline基本结构
pipeline
流水线的最外层结构,代表整条pipeline,包含着pipeline的完整逻辑;是声明式流水线语法的关健特征
node和agent
用于定义任务在哪里执行
每个node都是一个 Jenkins 节点,可以是 Jenkins master也可以是 Jenkins agent,node是执行step的具体服务器。node 代码块也是脚本式pipeline语法的关健特性,声明式pipeline使用 agent 关健字
stages
用于包含所有stage的定义
stage
属于stages的子语句块
指定 stage 的名称, 用于定义每个阶段 stage 的主要任务
一个pipeline可以划分为若干个stage,每个stage都是一个完整的操作,比如: clone代码、代码编译、代码测试和代码部署,阶段是一个逻辑分组,可以跨多个node执行。
steps
属于stage的子语句块
每个阶段stage中定义完成该阶段功能所需要经历的一系列步骤
步骤 steps 是jenkins pipeline最基本的操作单元,从在服务器创建目录到构建容器镜像,由各类Jenkins 插件提供实现,例如: sh “make”
能够把这些步骤steps 同该stage中的其它定义(如环境的定义,Post 等)分隔开
post
用在stage 代码块(和steps 同级)或整个pipeline执行完成后的附加步骤,此指令非必须项
脚本式流水线语法
node {
stage('Source') {
//git clone
}
stage('Build') {
//mvn
}
stage('Test') {
//mvn test
}
stage('Deploy') {
// scp
// java -jar
}
}
#特点:最外层是node {}
声明式流水线语法
声明式流水线是在”Pipeline plugin”的2.5版本添加到 Jenkins 流水线的 ,它在流水线子系统之上提供了一种更简单,更常见的语法。
所有有效的声明式流水线必须包含在一个 pipeline 块中, 比如:
pipeline {
agent any
stages {
stage('Build') {
steps {
//
}
}
stage('Test') {
steps {
//
}
}
stage('Deploy') {
steps {
//
}
}
}
}
Jenkins内置语法帮助,不会写的流水线可参考帮助文档
http://jenkins-server:8080/job/<job-name>/pipeline-syntax/
#注意:需要安装pipeline插件并且是pipeline风格的任务
Jenkinsfile
可以将pipeline的语句写到代码仓库中的 Jenkinsfile 文件,这样更加方便维护和版本控制
注意:使用Jenkinsfile后无需再执行git clone代码这一步骤,直接执行后面的mvn test即可
Pipeline部署Docker服务示例
pipeline {
agent any
environment {
codeRepo="git@gitlab.wang.org:devops/spring-boot-helloworld.git"
credential="gitlab-wang-sshkey"
harborServer='harbor.wang.org'
projectName='spring-boot-helloworld'
imageUrl="${harborServer}/example/${projectName}"
imageTag="${BUILD_ID}"
}
stages {
stage('Source') {
steps {
git branch: 'main', credentialsId: "${credential}", url: "${codeRepo}"
}
}
stage('Test') {
steps {
//注意:不要修改hello()函数,否则会导致下面失败
sh 'mvn test'
}
}
stage('Build') {
steps {
//sh 'mvn -B -DskipTests clean package'
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
stage('Build Docker Image') {
steps {
sh 'docker build . -t "${imageUrl}:${imageTag}"'
}
}
stage('Push Docker Image') {
steps {
withCredentials([usernamePassword(credentialsId: 'harbor-user-password', \
usernameVariable: 'harborUserName',passwordVariable: 'harborPassword')]) {
sh "echo ${harborPassword} | docker login -u ${env.harborUserName} --password-stdin ${harborServer}"
//sh "docker login -u ${env.harborUserName} -p ${harborPassword} ${harborServer}"
sh "docker push ${imageUrl}:${imageTag}"
echo "username=${env.harborUserName}"
echo "password=${harborPassword}"
}
}
}
stage('Run Docker ') {
steps {
sh 'ssh root@10.0.0.101 "docker rm -f ${projectName} ; docker run --name ${projectName} --restart always -p 80:8888 -d ${imageUrl}:${imageTag}"'
sh 'ssh root@10.0.0.102 "docker rm -f ${projectName} ; docker run --name ${projectName} --restart always -p 80:8888 -d ${imageUrl}:${imageTag}"'
//sh "docker -H 10.0.0.101 rm -f ${projectName} ; docker -H 10.0.0.101 run --name ${projectName} --restart always -p 80:8888 -d ${imageUrl}:${imageTag}"
//sh "docker -H 10.0.0.102 rm -f ${projectName} ; docker -H 10.0.0.102 run --name ${projectName} --restart always -p 80:8888 -d ${imageUrl}:${imageTag}"
}
}
}
}
pipeline选项参数示例
pipeline {
agent any
parameters {
string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
text(name: 'BIOGRAPHY', defaultValue: '', description: 'Enter some information about the person')
booleanParam(name: 'TOGGLE', defaultValue: true, description: 'Toggle this value')
choice(name: 'CHOICE', choices: ['One', 'Two', 'Three'], description: 'Pick something')
password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'Enter a password')
}
stages {
stage('Example') {
steps {
echo "Hello ${params.PERSON}"
echo "Biography: ${params.BIOGRAPHY}"
echo "Toggle: ${params.TOGGLE}"
echo "Choice: ${params.CHOICE}"
echo "Password: ${params.PASSWORD}"
}
}
}
}
综合示例:
pipeline {
agent any
environment {
codeRepo="http://gitlab.wang.org/devops/spring-boot-helloworld.git"
credential="gitlab-wang-password"
harborServer='harbor.wang.org'
projectName='spring-boot-helloworld'
imageUrl="${harborServer}/example/${projectName}"
imageTag="${BUILD_ID}"
}
triggers {
gitlab(triggerOnPush: true,
acceptMergeRequestOnSuccess: true,
triggerOnMergeRequest: true,
branchFilterType: 'All',
addVoteOnMergeRequest: true,
secretToken: '62dad2cd1d9ae62686ada8dc4cdOaabb')
}
stages {
stage('Source') {
steps {
git branch: 'main', credentialsId: "${credential}", url: "${codeRepo}"
}
}
stage('Build') {
steps {
sh 'mvn -B -DskipTests clean package'
}
}
stage('Test') {
steps {
//注意:不要修改hello()函数,否则会导致下面失败
sh 'mvn test'
}
}
stage('Build Docker Image') {
steps {
sh 'docker build . -t "${imageUrl}:${imageTag}"'
}
}
stage('Push Docker Image') {
agent any
steps {
withCredentials([usernamePassword(credentialsId: 'harbor-user-password', \
passwordVariable: 'harborPassword', usernameVariable: 'harborUserName')]) {
sh "echo ${harborPassword} | docker login -u ${env.harborUserName} --password-stdin ${harborServer}"
//sh "docker login -u ${env.harborUserName} -p ${harborPassword} ${harborServer}"
sh "docker push ${imageUrl}:${imageTag}"
echo "username=${env.harborUserName}"
echo "password=${harborPassword}"
}
}
}
stage('Run Docker ') {
steps {
sh 'ssh root@10.0.0.101 "docker rm -f ${projectName} ; docker run --name ${projectName} -p 80:8888 -d ${imageUrl}:${imageTag}"'
sh 'ssh root@10.0.0.102 "docker rm -f ${projectName} ; docker run --name ${projectName} -p 80:8888 -d ${imageUrl}:${imageTag}"'
}
}
}
post {
failure {
mail to: 'root@wangxiaochun.com',
subject: "Status of pipeline: ${currentBuild.fullDisplayName}",
body: "${env.BUILD_URL} has result ${currentBuild.result}"
}
success{
qyWechatNotification failNotify: true, webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=29d3caa7-340e-410d-8599-56e031234567'
}
}
}
作者:于浩 创建时间:2026-06-11 17:00
最后编辑:于浩 更新时间:2026-07-12 22:32
最后编辑:于浩 更新时间:2026-07-12 22:32