Jenkins 是一款开源 CI&CD 软件,用于自动化各种任务,包括构建、测试和部署软件。
Jenkins 支持各种运行方式,可通过系统包、Docker 或者通过一个独立的 Java 程序。
- 持续集成 (Continuous Integration)
- 持续部署 (Continuous Deployment)
安装 Jenkins
建议使用的 Docker 映像是 jenkinsci/blueocean。该镜像捆绑了所有Blue Ocean插件和功能。这意味着你不需要单独安装Blue Ocean插件。
1
2
3
4
5
6
7
8
9
|
docker run \
-u root --name jenkins-tutorials \
--rm \
-d \
-p 8080:8080 \
-p 50000:50000 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkinsci/blueocean
|
jenkins-data
卷也可以 docker volume create 命令创建: docker volume create jenkins-data 代替映射 /var/jenkins_home 目录转换为Docker卷,还 可以将此目录映射到计算机本地文件系统上的目录。
浏览 Jenkins Web 服务,并等待 解锁 Jenkins 页面出现。
1
2
3
|
docker logs -f jenkins-tutorials
docker exec -it jenkins-tutorials bash
cat /var/jenkins_home/secrets/initialAdminPassword
|
Blue Ocean 主题插件
Blue Ocean 重新思考Jenkins的用户体验,从头开始设计Jenkins Pipeline, 但仍然与自由式作业兼容,Blue Ocean减少了混乱而且进一步明确了团队中每个成员 Blue Ocean 的主要特性包括:
- 持续交付(CD)Pipeline的 复杂可视化 ,可以让您快速直观地理解管道状态。
- Pipeline 编辑器 - 引导用户通过直观的、可视化的过程来创建Pipeline,从而使Pipeline的创建变得平易近人。
- 个性化 以适应团队中每个成员不同角色的需求。
- 在需要干预和/或出现问题时 精确定位 。 Blue Ocean 展示 Pipeline中需要关注的地方, 简化异常处理,提高生产力
- 本地集成分支和合并请求, 在与GitHub 和 Bitbucket中的其他人协作编码时实现最大程度的开发人员生产力。
系统管理»管理插件»可选插件 过滤 Blue Ocean 勾选 直接安装
流水线 Pipeline
Jenkins 流水线 (或简单的带有大写"P"的"Pipeline") 是一套插件,它支持实现和集成 continuous delivery pipelines 到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
|
#!groovy
pipeline {
agent any
tools {
maven 'm3'
jdk 'jdk8'
}
stages {
stage ('Initialize') {
steps {
sh '''
echo "PATH = ${PATH}"
echo "M2_HOME = ${M2_HOME}"
'''
}
}
stage ('Build') {
steps {
echo 'This is a minimal pipeline.'
checkout([$class: 'GitSCM', branches: [[name: '*/TD_sit']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '63b8184b-a84c-4beb-9ccd-1267f7f32c5e', url: 'http://dev.ixdigit.com/bo/Trade_socket.git']]])
sh 'mvn versions:set -DgenerateBackupPoms=false -DnewVersion=1.0.0-SIT-SNAPSHOT'
sh 'mvn --update-snapshots clean deploy -B -e -U -Dmaven.test.skip=true -DreleaseEnv=SIT'
}
}
}
}
|
流水线开发工具
配置
系统设置
Git plugin :
user.name user.email
Gitlab :
Gitlab host URL Credentals GitLab API token
全局工具配置
Git :
Path to Git executable git
Maven :
Maven name m3
MAVEN_HOME /opt/maven
Maven
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
mkdir /opt/maven
cd /opt/maven
wget http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.5.3/binaries/apache-maven-3.5.3-bin.tar.gz
tar -xvf apache-maven-3.5.3-bin.tar.gz
vi /etc/profile
export MAVEN_HOME=/opt/maven/apache-maven-3.5.3
export MAVEN_HOME
export PATH=${PATH}:${MAVEN_HOME}/bin
source /etc/profile
mvn -v
# 更改 maven 用户配置 与全局配置 ${MAVEN_HOME}/conf/settings.xml 共同作用,用户配置优先
vi ~/.m2/settings.xml
|
SSH 免密登陆
1
2
3
4
5
|
# 生成公私密钥 直接回车
ssh-keygen -t rsa
# ssh-keygen -t rsa -C "iwys@qq.com"
# 本机将公钥传输到远程机器
scp -r /root/.ssh/id_rsa.pub 192.168.31.147:/root/.ssh/authorized_keys
|
JDK8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# Ubuntu jdk 8
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer
# 设置默认JDK
sudo apt install oracle-java8-set-default
# vim ~/.bashrc
vi /etc/profile
export JAVA_HOME=/usr/lib/jvm/java-8-oracle
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
source /etc/profile
env
# /usr/lib/jvm/java-8-oracle
java -version
|
Gitlab
建立jenkins 专用账号
登陆 Gitlab Profile Settings
Account Private Token
SSH Keys
maven integration plugin //该插件安装了,才能创建maven项目。
git plugin //从远程拉取代码
deploy to container plugin //发布
publish over ssh ssh远程登录
配置插件
Blue Ocean
Maven Integration
Git plugin
GitLab
系统设置->Gitlab
Connection name gitlab
GitLab host URL http://dev.ixdigit.com
如果报500错误 可能是 API-Level 需要指定
Credentials -> Add -> Jenkins
Kind GitLab API token
写入 API token 点击 Add
登陆 GitLab Profiel Settings-> Account-> Private token LrvCsd1rBjcRRdv5ng19
Gitlab Hook
打开一个Jenkins Job的配置,在“构建触发器”区中选择
“Build when a change is pushed to GitLab. GitLab CI Service URL:”
GitLab webhook URL: http://172.27.2.49:8088/project/Goldoffice_trade_api
这个url 是给gitlab 用
高级选项中生成“Secret token”
登陆GitLab 选择对应的Project “Settings”–》“Integrations”
填入 URL 与 Sercret Token
Deploy to container
Email Extension Plugin
Publish Over SSH
远程部署 jar
Execute shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
cd /opt/projectname/ #进入项目jar包存放目录
#得到进程ID pid,kill该进程
pid=`cat /opt/projectname/pid` #得到该目录下 pid文件中的进程id
if [ -n "$pid" ]
then
echo "kill -9 的pid:" $pid
kill -9 $pid #kill该进程
fi
#执行jar,并将进程挂起,保存进程ID到 pid文件
echo "Execute shell Finish"
BUILD_ID=DONTKILLME nohup java -jar /opt/projectname/jenkins_jar.jar & echo "$!" > pid #执行项目jar包,将进程挂起,然后将进程id写入当前目录下的pid文件中
|
Jenkinsfile
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
|
pipeline {
agent any
stages {
stage('Checkout') {
steps {
echo 'Checkout'
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '500378f5-a6e4-4255-984e-61537fe0e455', url: 'git@gitlab.aniu.so:aniu-yunwei/game-of-life.git']]])
}
}
stage('Build') {
steps {
echo 'Building'
sh 'mvn clean install' # 可以用自己的 mvn clean deploy + 参数替代
}
}
stage('Test') {
steps {
echo 'Testing'
sh 'mvn clean verify sonar:sonar' # 此处可以使用mvn test替代,笔者这步是检测代码的质量同步到自己的代码质量检测平台。
}
}
stage('Deploy') {
steps {
echo 'Deploying'
sh 'mvn clean deploy' # 此处调用脚本或者ansible、saltstak,部署到远程
}
}
}
}
|
运行 jar 发布到远程服务器
Post Steps
Run only if build succeeds
增加 Execute shell script on remote host using ssh
SSH site root@192.168.10.1:22
Command
1
2
3
|
export JAVA_HOME=/usr/local/jdk/jdk1.8.0_144
/opt/projectname/service.sh stop
rm -rf /opt/projectname/*
|
增加 Execute shell
1
2
|
scp -r ${WORKSPASE}/target/spring-ynthm.war root@192.168.10.1:/opt/projectname
scp -r ${WORKSPASE}/service.sh root@192.168.10.1:/opt/projectname
|
增加 Execute shell script on remote host using ssh
SSH site root@192.168.10.1:22
Command
1
2
|
export JAVA_HOME=/usr/local/jdk/jdk1.8.0_144
/opt/projectname/service.sh start
|
service.sh
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
|
#!/bin/sh
## java env
export JAVA_HOME=/usr/local/jdk/jdk1.8.0_144
export JRE_HOME=$JAVA_HOME/jre
## service name
APP_NAME=account
SERVICE_DIR=/usr/local/dubbo-server/$APP_NAME
SERVICE_NAME=medcare-dubbo-$APP_NAME
JAR_NAME=$SERVICE_NAME\.jar
PID=$SERVICE_NAME\.pid
cd $SERVICE_DIR
case "$1" in
start)
nohup $JRE_HOME/bin/java -Xms256m -Xmx512m -jar $JAR_NAME >/dev/null 2>&1 &
echo $! > $SERVICE_DIR/$PID
echo "=== start $SERVICE_NAME"
;;
stop)
kill `cat $SERVICE_DIR/$PID`
rm -rf $SERVICE_DIR/$PID
echo "=== stop $SERVICE_NAME"
sleep 5
##
## edu-service-aa.jar
## edu-service-aa-bb.jar
P_ID=`ps -ef | grep -w "$SERVICE_NAME" | grep -v "grep" | awk '{print $2}'`
if [ "$P_ID" == "" ]; then
echo "=== $SERVICE_NAME process not exists or stop success"
else
echo "=== $SERVICE_NAME process pid is:$P_ID"
echo "=== begin kill $SERVICE_NAME process, pid is:$P_ID"
kill -9 $P_ID
fi
;;
restart)
$0 stop
sleep 2
$0 start
echo "=== restart $SERVICE_NAME"
;;
*)
## restart
$0 stop
sleep 2
$0 start
;;
esac
exit 0
|
附录