一、安装jenkins
开源 Devops 工具 Jenkins 宣布:从 6 月 22 日发布的 Jenkins 2.356 和即将发布的 9 月 LTS 版本开始,Jenkins 最低需要 Java 11。
如果出现版本问题导致插件无法安装,可在下面链接下载后手动安装
http://updates.jenkins-ci.org/download/plugins/
0、前提
安装jdk和maven并配置环境
安装git
yum install -y git
1、war 包安装
(1)配置数据存储路径
配置环境变量
vim /etc/profile
最后一行添加
export JENKINS_HOME=/data/jenkins_data/
刷新环境变量
source /etc/profile
如果用 java -jar
方式启动
nohup java -DJENKINS_HOME=/data/jenkins_data/ -jar jenkins.war --httpPort=8080 &
配置访问前缀
nohup java -jar jenkins.war --httpPort=8080 --prefix="/jenkins" > jenkins.log 2>&1 &
(2)下载
https://www.jenkins.io/download/
并上传到linux服务器,并复制到tomcat的webapps目录下
(3)启动tomcat
- 启动后,访问
服务器主机名:8080/jenkins
- 根据网页提示信息到服务器的相应路径下获取密码,解锁jenkins
- 关闭网页
(4)配置镜像源
进入更新配置位置
cd /root/.jenkins/updates
输入以下命令
sed -i 's/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
(5)重启tomcat
访问刚才的网页,选择安装推荐插件
安装完后,创建用户,实例配置为默认
2、yum安装
二、docker安装
1、安装
拉取镜像,不要docker pull jenkins ,jenkins版本太旧已不维护了。
docker pull jenkins/jenkins
创建挂载数据的文件夹
mkdir /data/docker/jenkins
设置权限
chmod -R 777 /data/docker/jenkins
运行容器
docker run -d --name jenkins \
-p 8888:8080 -p 50000:50000 \
--restart=always --privileged=true \
-e TZ="Asia/Shanghai" \
-e JENKINS_OPTS="--prefix=/jenkins" \
-e JENKINS_ARGS="--prefix=/jenkins" \
-e JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=utf-8 -Xms128m -Xmx128m -XX:MaxPermSize=64M" \
-v /etc/localtime:/etc/localtime:ro \
-v /data/docker/jenkins:/var/jenkins_home \
jenkins/jenkins
参数解析:
-d 后台运行容器,并返回容器ID;
–name 为容器起一个容易区分且容易书写的名字
-p 映射宿主机端口到容器端口,宿主机端口:容器端口
–restart=always 机器重启时自动启动容器
-e 设定一些必须的环境变量。
-e TZ="Asia/Shanghai"
设定时区为上海,强烈建议国内设定,否则容器内打印的所有日志时间都会差8小时。-e JENKINS_OPTS="--prefix=/jenkins" -e JENKINS_ARGS="--prefix=/jenkins"
设定jenkins访问的路径,非必选,如果是直接根目录或ip地址访问,则不需要添加,如果是想nginx反向代理且不在根目录下,则必须,否则只配置nginx会报静态文件404错误,此处名字应与文件夹名称一致。
-v 挂载宿主机文件到容器。本例两个分别为:
-v /etc/localtime:/etc/localtime:ro
挂载宿主机时间,保持容器时间正确。-v /data/docker/jenkins:/var/jenkins_home
绑定挂载文件
-u 0 因为Jenkins镜像内部使用的用户是jenkins,但是我们启动容器时的账号是root,导致没有权限操作内部目录,所以加上参数 -u 0 就能解决了:
- -u :覆盖容器中内置的账号
- 0:root账号id
--privileged=true
解决访问目录无权限
2、配置镜像源
cd /data/docker/jenkins/updates
配置清华镜像
sed -i 's/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
重启docker
docker restart jenkins
3、汉化
安装 Localization: Chinese (Simplified)
插件
三、配置jenkins
1、获取jdk、maven、git安装路径
在服务器中输入which jdk
,获取jdk和maven的安装目录
输入which git
获取git的安装目录
2、配置jdk、maven
进入全局配置
按以下配置jdk、git、maven(maven有两个,改下面的)


3、mvn命令不存在
进入系统设置
在服务器中执行以下命令获取PATH环境变量
echo $PATH
将返回的PATH变量填到jenkins的系统设置中
4、配置svn
当项目不是使用git,而是svn时,需要配置svn
在插件管理中搜索以下插件安装即可
构建任务时

四、自动化部署
1、项目修改
在pom文件添加插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
添加打包方式
<groupId>com.rewind</groupId>
<artifactId>graduation-project</artifactId>
<packaging>jar</packaging> <!--添加这一行-->
<version>0.0.1-SNAPSHOT</version>
2、添加文件Dockerfile
如果直接使用shell脚本启动,可不使用
在项目根目录下(pom的同级目录)下,添加Dockerfile文件(无后缀),内容如下
FROM java:8
EXPOSE 8080
VOLUME /tmp
ADD ./target/renren-fast.jar /app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-jar","/app.jar"]
3、jenkins创建任务
输入任务名称,选择自由风格,确定

添加项目的git仓库,并添加git用户(填写用户名密码即可),选择分支

方式一、docker
找到构建,选择执行shell,并把docker脚本(本文末尾)粘贴到框中,修改下面部分
点击保存
#!/bin/bash
#maven打包
mvn clean package
echo 'package ok!'
echo 'build start!'
# 服务名,镜像名,容器名
service_name="eureka-server"
# 服务端口
service_prot=8080
# 对应宿主机端口
host_port=8888
#查看镜像id
IID=$(docker images | grep "$service_name" | awk '{print $3}')
echo "IID $IID"
if [ -n "$IID" ]
then
echo "exist $SERVER_NAME image,IID=$IID"
#删除镜像
docker rmi -f $service_name
echo "delete $SERVER_NAME image"
#构建
docker build -t $service_name .
echo "build $SERVER_NAME image"
else
echo "no exist $SERVER_NAME image,build docker"
#构建
docker build -t $service_name .
echo "build $SERVER_NAME image"
fi
#查看容器id
CID=$(docker ps | grep "$SERVER_NAME" | awk '{print $1}')
echo "CID $CID"
if [ -n "$CID" ]
then
echo "exist $SERVER_NAME container,CID=$CID"
#停止
docker stop $service_name
#删除容器
docker rm $service_name
else
echo "no exist $SERVER_NAME container"
fi
#启动
docker run -d --name $service_name -p $host_port:$service_prot $service_name
#查看启动日志
#docker logs -f $service_name
方式二、maven

port=8083
#根据端口号查询对应的pid
pid=$(netstat -nlp | grep :$port | awk '{print $7}' | awk -F"/" '{ print $1 }');
#杀掉对应的进程,如果pid不存在,则不执行
if [ -n "$pid" ]; then
kill -9 $pid;
fi
#####################################################################
mvn clean package
#####################################################################
# 禁止jenkins杀死衍生进程,jenkins默认构建完会杀死所有衍生进程
BUILD_ID=DONTKILLME
cd /root/.jenkins/workspace/teway-tms/target
tar -zxvf teway-tms-1.0-SNAPSHOT-assembly.tar.gz
cd /root/.jenkins/workspace/teway-tms/target/c12-tms-1.0-SNAPSHOT/bin
./start.sh
4、构建
如果是docker方式,则需要启动docker

点击此处查看控制台输出

五、Publish Over SSH
【Publish Over SSH】插件是通过SSH连接其他Linux机器,远程传输文件及执行Shell命令
有两种验证方式,密码方式和秘钥方式
1、密码方式
Manage Jenkins -> Configure System -> SSH Servers
填写名称、主机ip、ssh用户名、远程的目录(最好写/,后面就可以用绝对路径了)
然后点击高级,勾选【Use password authentication, or use a different key】使用密码登录,填写密码、端口(默认是22)、连接超时(默认300000ms)
点击【Test Configuration】,测试连接,显示Success即可
2、秘钥方式
秘钥方式
Manage Jenkins -> Configure System -> SSH Servers
1、生成一个密钥对,命令:ssh-keygen
把生成的id_rsa.pub(公钥)内容复制到要远程的机器的authorized_keys文件下,.ssh文件夹的权限为600,authorized_keys文件的权限为700;
把id_rsa(私钥)的内容填写在Jenkins SSH Key -> Key 里面
或者指定Path to key(jenkins机器私钥的文件路径)也可以
填写名称、主机ip、ssh用户名、远程的目录(最好写/,后面就可以用绝对路径了)
然后点击高级,填写密码、端口、连接超时即可;不要勾选【Use password authentication, or use a different key】使用密码登录
点击【Test Configuration】,测试连接,显示Success即可;
3、使用方式
项目中增加构建步骤,或者构建后步骤
参数详解:
Name:SSH Sverver的名字列表
Source files:
jenkins本机上的文件,相对 workspace/当前项目
的路径,如上图中表示的是 /root/.jenkins/workspace/项目1/test
下的所有文件和文件名
Remove prefix:文件复制时要过滤的目录,要不然会创建多层目录
Remote directory:
远程机上的目录,此目录是相对于【SSH Server】中的【Remote directory】的,如果不存在将会自动创建,设置为/根目录的话,这里可以用绝对路径
- Exec command:远程机器上执行的命令或脚本
4、远程执行脚本失败
- 执行命令前需要先
source /etc/profile
命令,同步环境 java
、jar包
和 日志文位置都用全路径。- shell 命令加
#!/bin/bash
六、Pipeline流水线构建
1、概念
Pipeline,简单来说,就是一套运行在 Jenkins 上的工作流框架,将原来独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排和可视化的工作。
代码:Pipeline以代码的形式实现,通常被检入源代码控制,使团队能够编辑,审查和迭代其传送流程。
持久:无论是计划内的还是计划外的服务器重启,Pipeline都是可恢复的。
可停止:Pipeline可接收交互式输入,以确定是否继续执行Pipeline。
多功能:Pipeline支持现实世界中复杂的持续交付要求。它支持fork/join、循环执行,并行执行任务的功能。
可扩展:Pipeline插件支持其DSL的自定义扩展 ,以及与其他插件集成的多个选项
如何创建 Jenkins Pipeline
Pipeline 脚本是由 Groovy 语言实现的,但是我们没必要单独去学习 Groovy
Pipeline 支持两种语法:Declarative(声明式)和 Scripted Pipeline(脚本式)语法
Pipeline 也有两种创建方法:
- 可以直接在 Jenkins 的 Web UI 界面中输入脚本;
- 也可以通过创建一个 Jenkinsfifile 脚本文件放入项目源码库中(一般我们都推荐在 Jenkins 中直接从源代码控制(SCM)中直接载入 Jenkinsfifile Pipeline 这种方法)。
安装插件
Manage Jenkins->Manage Plugins->搜索Pipeline
2、Declarative声明式
创建一个流水线项目,脚本选择 Hello world
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
}
}
stages:代表整个流水线的所有执行阶段。通常stages只有1个,里面包含多个stage
stage:代表流水线中的某个阶段,可能出现n个。一般分为拉取代码,编译构建,部署等阶段。
steps:代表一个阶段内需要执行的逻辑。steps里面是shell脚本,git拉取代码,ssh远程发布等任意内容。
编写一个简单声明式Pipeline:
pipeline {
agent any
stages {
stage('拉取代码') {
steps {
echo '拉取代码'
}
}
stage('编译构建') {
steps {
echo '编译构建'
}
}
stage('项目部署') {
steps {
echo '项目部署'
}
}
}
}
点击构建,可以看到整个构建过程
3、Scripted Pipeline脚本式
创建流水线工程,脚本选择”Scripted Pipeline”
node {
def mvnHome
stage('Preparation') { // for display purposes
// 拉取代码
// Get some code from a GitHub repository
git 'https://github.com/jglick/simple-maven-project-with-tests.git'
// Get the Maven tool.
// ** NOTE: This 'M3' Maven tool must be configured
// ** in the global configuration.
mvnHome = tool 'M3'
}
stage('Build') {
// 编译构建
// Run the maven build
withEnv(["MVN_HOME=$mvnHome"]) {
if (isUnix()) {
sh '"$MVN_HOME/bin/mvn" -Dmaven.test.failure.ignore clean package'
} else {
bat(/"%MVN_HOME%\bin\mvn" -Dmaven.test.failure.ignore clean package/)
}
}
}
stage('Results') {
// 部署
junit '**/target/surefire-reports/TEST-*.xml'
archiveArtifacts 'target/*.jar'
}
}
Node:节点,一个 Node 就是一个 Jenkins 节点,Master 或者 Agent,是执行 Step 的具体运行环境,后续讲到Jenkins的Master-Slave架构的时候用到。
Stage:阶段,一个 Pipeline 可以划分为若干个 Stage,每个 Stage 代表一组操作,比如:Build、Test、Deploy,Stage 是一个逻辑分组的概念。
Step:步骤,Step 是最基本的操作单元,可以是打印一句话,也可以是构建一个 Docker 镜像,由各类 Jenkins 插件提供,比如命令:sh ‘make’,就相当于我们平时 shell 终端中执行 make 命令一样。
4、SCM脚本
刚才我们都是直接在Jenkins的UI界面编写Pipeline代码,这样不方便脚本维护,建议把Pipeline脚本放在项目中(一起进行版本控制)
1)在项目根目录建立Jenkinsfifile文件,把脚本内容复制到该文件中
2)在项目中引用该文件
5、脚本语法
可以通过下面的流水线语法自动生成脚本

(1)拉取代码
流水线语法页面选择
填入信息生成脚本
checkout([$class: 'GitSCM', branches: [[name: '*/分支名']], extensions: [], userRemoteConfigs: [[credentialsId: '用户凭据id', url: 'git地址']]])
(2)执行shell脚本
sh 'mvn clean package'
(3)执行publish over ssh
sshPublisher(publishers: [sshPublisherDesc(configName: 'prod', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: """
source /etc/profile
BUILD_ID=DONTKILLME
touch 1.txt
""", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
重点:execCommand后面必须使用三个双引号,不能使用单引号,否则无法获取到环境变量
(4)docker
七、构建触发器
Jenkins内置4种构建触发器:
触发远程构建
其他工程构建后触发(Build after other projects are build)
定时构建(Build periodically)
轮询SCM(Poll SCM)
1、触发远程构建
只需请求一下路径即可触发构建
JENKINS_URL/job/pipeline-test/build?token=自定义的TOKEN
2、其他工程构建后触发
3、定时构建
定时字符串从左往右分别为:
分 时 日 月 周一些定时表达式的例子:
每30分钟构建一次:H代表形参 H/30 * * * * 10:02 10:32
每2个小时构建一次: H H/2 * * *
每天的8点,12点,22点,一天构建3次: (多个时间点中间用逗号隔开) 0 8,12,22 * * *
每天中午12点定时构建一次 H 12 * * *
每天下午18点定时构建一次 H 18 * * *
在每个小时的前半个小时内的每10分钟 H(0-29)/10 * * * *
每两小时一次,每个工作日上午9点到下午5点(也许是上午10:38,下午12:38,下午2:38,下午4:38) H H(9-16)/2 * * 1-5
4、轮询SCM
轮询SCM,是指定时扫描本地代码仓库的代码是否有变更,如果代码有变更就触发项目构建。
注意:这次构建触发器,Jenkins会定时扫描本地整个项目的代码,增大系统的开销,不建议使用。
5、Git hook
利用Git的webhook实现代码push到仓库,立即触发项目自动构建。