一、Jenkins基础
1. 概述
Jenkins是一款基于Java开发的CI(持续集成)和CD(持续部署)平台。
Jenkins无需数据库支持,服务的存储是基于xml文件的方式。
2. Jenkins主要文件
- /etc/init.d/jenkins - 服务启动/停止脚本
- /etc/logrotate.d/jenkins - 服务日志切割脚本
- /etc/sysconfig/jenkins - 服务主配置文件
- /usr/lib/jenkins/jenkins.war - 替换相应war包,升级Jenkins版本
- /usr/sbin/rcjenkins - 服务重启脚本(为/etc/init.d/jenkins文件的软连接)
- /var/cache/jenkins - 服务缓存目录
- /var/lib/jenkins - 服务工作目录
- /var/log/jenkins - 服务日志目录
[root@jenkins ~]# rpm -ql jenkins
/etc/init.d/jenkins
/etc/logrotate.d/jenkins
/etc/sysconfig/jenkins
/usr/lib/jenkins
/usr/lib/jenkins/jenkins.war
/usr/sbin/rcjenkins
/var/cache/jenkins
/var/lib/jenkins
/var/log/jenkins
3. Jenkins安装
离线安装包 提取码:17tu |
安装方式
- YUM安装
- war安装
- 容器安装(docker)
使用Tomcat 8.0及以上直接运行war包时,请注意修改 /安装目录/bin/catalina.sh 文件中的 UMASK ; |
if [ -z "$UMASK" ]; then
UMASK="0022"
fi
step 01 安装Java
yum install -y java |
[root@jenkins ~]# yum install java -y
Loaded plugins: fastestmirror
Determining fastest mirrors
......
xorg-x11-font-utils.x86_64 1:7.5-21.el7
xorg-x11-fonts-Type1.noarch 0:7.5-9.el7
Complete!
step 02 安装Jenkins
yum localinstall -y jenkins-*.rpm |
[root@jenkins ~]# cd /tmp/
[root@jenkins /tmp]# rz -E
rz waiting to receive.
[root@jenkins /tmp]# ls
jenkins-2.176.1-1.1.noarch.rpm jenkins_plugins_new.tar.gz
[root@jenkins /tmp]# yum localinstall jenkins-2.176.1-1.1.noarch.rpm -y
Loaded plugins: fastestmirror
Examining jenkins-2.176.1-1.1.noarch.rpm: jenkins-2.176.1-1.1.noarch
Marking jenkins-2.176.1-1.1.noarch.rpm to be installed
......
Installed:
jenkins.noarch 0:2.176.1-1.1
Complete!
step 03 修改配置文件
# /etc/sysconfig/jenkins JENKINS_HOME="工作目录" #指定Jenkins服务的工作目录 JENKINS_USER="用户名" #指定Jenkins服务进程的运行用户 JENKINS_JAVA_OPTIONS=" - Djava.awt.headless=true" #Jenkins服务的Java启动参数(保持默认) JENKINS_PORT="端口" #指定Jenkins运行端口(默认8080) JENKINS_LISTEN_ADDRESS="" #指定Jenkins监听地址(默认监听0.0.0.0) |
[root@jenkins ~]# grep -Ev '^$|^#' /etc/sysconfig/jenkins
JENKINS_HOME="/var/lib/jenkins"
JENKINS_JAVA_CMD=""
JENKINS_USER="jenkins"
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"
JENKINS_PORT="8080"
JENKINS_LISTEN_ADDRESS=""
JENKINS_HTTPS_PORT=""
JENKINS_HTTPS_KEYSTORE=""
JENKINS_HTTPS_KEYSTORE_PASSWORD=""
JENKINS_HTTPS_LISTEN_ADDRESS=""
JENKINS_DEBUG_LEVEL="5"
JENKINS_ENABLE_ACCESS_LOG="no"
JENKINS_HANDLER_MAX="100"
JENKINS_HANDLER_IDLE="20"
JENKINS_ARGS=""
step 04 启动Jenkins
systemctl start jenkins systemctl enable jenkins |
[root@jenkins ~]# systemctl enable jenkins
jenkins.service is not a native service, redirecting to /sbin/chkconfig.
Executing /sbin/chkconfig jenkins on
[root@jenkins ~]# systemctl start jenkins
step 05 访问Jenkins
netstat -lntup |
[root@jenkins ~]# netstat -lntup| grep 8080
tcp6 0 0 :::8080 :::* LISTEN 8301/java
step 06 解锁Jenkins
cat /var/lib/jenkins/secrets/initialAdminPassword |
[root@jenkins ~]# cat /var/lib/jenkins/secrets/initialAdminPassword
c59cf575b9354c639aa5d5ba89ff9f81
step 07 配置Jenkins
step 08 修改管理员密码
在未配置admin账户的情况下,请使用初始(解锁)密码,登录admin账户。
4. Jenkins插件安装
插件安装方式: 1. 在线安装 - 加速安装插件(替换安装源) jenkins插件下载加速最终方案[转自vasks博客] 2. 本地安装 - 上传一个插件(支持.hpi文件) 3. 导入插件 - 将其他服务器jenkins服务的插件包导入到指定插件目录 在Jenkins服务中,新安装的插件可直接使用,但是已安装的插件升级,需要重启Jenkins服务。 |
本文以方式3为例,安装插件
step 01 停止jenkins服务
systemctl stop jenkins |
[root@jenkins ~]# systemctl stop jenkins.service
step 02 解压导入插件
Jenkins插件目录: /var/lib/jenkins/plugins/ |
tar xf jenkins_*_plugins.tar.gz \cp -rp plugins/* /var/lib/jenkins/plugins/ |
[root@jenkins ~]# cd /tmp/
[root@jenkins /tmp]# tar xf jenkins_plugins_new.tar.gz
[root@jenkins /tmp]# ls -d plugins/
plugins/
[root@jenkins /tmp]# \cp -rp plugins/* /var/lib/jenkins/plugins/
[root@jenkins /tmp]# ll /var/lib/jenkins/plugins/ | head -3
total 134684
drwxr-xr-x 7 jenkins jenkins 124 Aug 19 2019 ace-editor
-rw-r--r-- 1 jenkins jenkins 4279042 Aug 19 2019 ace-editor.jpi
step 03 授权插件文件
因为Jenkins服务是由Jenkins用户运行起来的; |
chown -R jenkins.jenkins /var/lib/jenkins/plugins/ |
[root@jenkins /tmp]# chown -R jenkins.jenkins /var/lib/jenkins/plugins/
step 04 启动jenkins服务
systemctl start jenkins |
[root@jenkins /tmp]# systemctl start jenkins
[root@jenkins /tmp]# tail -f /var/log/jenkins/jenkins.log
......
INFO: Obtained the updated data file for hudson.tools.JDKInstaller
Feb 22, 2021 3:57:56 PM hudson.model.AsyncPeriodicWork$1 run
INFO: Finished Download metadata. 7,438 ms
step 05 隐藏Jenkins警告
step 06 Jenkins汉化
Jenkins服务默认不支持中文,需要借助插件实现汉化; |
step 07 更改jenkins运行用户(建议学习期间以root运行)
[root@jenkins ~]# ps aux | grep [j]enkins
jenkins 7451 0.4 27.6 2732732 560492 ? Ssl 08:49 1:45 /etc/alternatives/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon --httpPort=8080 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20
[root@jenkins ~]# grep JENKINS_USER /etc/sysconfig/jenkins
JENKINS_USER="root"
[root@jenkins ~]# systemctl restart jenkins
[root@jenkins ~]# ps aux | grep [j]enkins
root 9145 94.5 14.5 2637048 294552 ? Ssl 15:39 0:17 /etc/alternatives/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon --httpPort=8080 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20
二、Jenkins与Gitlab集成
1. Jenkins部署HTML
step 00 准备web集群环境
# load balance
[root@lb01 ~]# cat /etc/nginx/conf.d/jenkins_test_proxy.conf
upstream aspen {
server 172.16.1.17:80;
server 172.16.1.18:80;
}
server {
listen 80;
server_name html.aspen.com;
location / {
proxy_pass http://aspen;
proxy_set_header Host $http_host;
}
}
[root@lb01 ~]# systemctl restart nginx
# web 01
[root@web01 ~]# cat /etc/nginx/conf.d/jenkins_test_html.conf
server {
listen 80;
server_name html.aspen.com;
location / {
root /html;
index index.html;
}
}
[root@web01 /html]# systemctl restart nginx
[root@web01 ~]# echo "Web01 based on nginx" > /html/index.html
# web 02
root@web02 ~]# cat /etc/nginx/conf.d/jenkins_test_html.conf
server {
listen 80;
server_name html.aspen.com;
location / {
root /html;
index index.html;
}
}
[root@web02 /tmp]# systemctl restart nginx
[root@web02 ~]# echo "Web02 based on nginx" > /html/index.html
# test
[root@jenkins ~]# curl http://html.aspen.com
Web02 based on nginx
[root@jenkins ~]# curl http://html.aspen.com
Web01 based on nginx
step 01 上传代码至Gitlab
示例代码 提取码:t905 |
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git remote -v
origin https://gitee.com/kangjie1209/monitor.git (fetch)
origin https://gitee.com/kangjie1209/monitor.git (push)
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git remote remove origin
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git remote -v
step 02 配置免密环境(代码拉取免密)
[root@jenkins ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
......
[root@jenkins ~]# cat ./.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDsww7jcptgQg5YMOb65UtFPVlKQM1oUgOe5hMSymhNvmDnp4fPHaOafHDl5a8qJFhNLGu6vxqwA9YY7lOm0i4zGHdiliOhAENNg64rrAxYOZSheHzw7zuLF/oFXpQ7kSkpISr3sQ4XeSYb/TtJEk77AQt7X+y+dzoVT8q+p7wx5Xd3ui8oz9x5Y//7i1Nn06fOjFcpxjvl+GllwUXCGBRuekTs+oHRya4u9f6S9VqaJc53VCbYVL6JmjX9pg230RkXux+c/+N3gIU+XOixuCIoSaIlNghgc3bYXRRwgrx9tQYBul3kA4vpIeSXVHBowifJnGPzHVzYpfEwrnb12SdL root@jenkins
step 03 手动上线代码
# 提交代码至Gitlab
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git remote add origin http://gitlab.aspen.com/dev/monitor.git
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git add .
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git commit -m "Initial commit"
On branch master
nothing to commit, working tree clean
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git push -u origin master
libpng warning: iCCP: cHRM chunk does not match sRGB
Enumerating objects: 435, done.
Counting objects: 100% (435/435), done.
Delta compression using up to 12 threads
Compressing objects: 100% (372/372), done.
Writing objects: 100% (435/435), 8.78 MiB | 12.88 MiB/s, done.
Total 435 (delta 53), reused 435 (delta 53)
remote: Resolving deltas: 100% (53/53), done.
To http://gitlab.aspen.com/dev/monitor.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
# 运维部署代码
[root@jenkins ~]# git clone git@gitlab.aspen.com:dev/monitor.git
Cloning into 'monitor'...
remote: Enumerating objects: 438, done.
remote: Counting objects: 100% (438/438), done.
remote: Compressing objects: 100% (375/375), done.
remote: Total 438 (delta 55), reused 434 (delta 53)
Receiving objects: 100% (438/438), 8.78 MiB | 0 bytes/s, done.
Resolving deltas: 100% (55/55), done.
[root@jenkins ~]# ls
anaconda-ks.cfg monitor
[root@jenkins ~]# scp -rp ./monitor/* root@10.0.0.17:/html/
The authenticity of host '10.0.0.17 (10.0.0.17)' can't be established.
ECDSA key fingerprint is SHA256:4O+/HRUt2Qwcz4xXk3y+Y5It07gqAUNy//ju/dZH2Vc.
ECDSA key fingerprint is MD5:5b:e2:99:8c:b6:d6:88:85:2c:4a:84:65:4a:74:78:75.
......
[root@jenkins ~]# scp -rp ./monitor/* root@10.0.0.18:/html/
The authenticity of host '10.0.0.18 (10.0.0.18)' can't be established.
ECDSA key fingerprint is SHA256:4O+/HRUt2Qwcz4xXk3y+Y5It07gqAUNy//ju/dZH2Vc.
ECDSA key fingerprint is MD5:5b:e2:99:8c:b6:d6:88:85:2c:4a:84:65:4a:74:78:75.
......
step 04 创建Job(Jenkins)
# 准备工作
[root@jenkins ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@10.0.0.17
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
......
[root@jenkins ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@10.0.0.18
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
......
[root@jenkins ~]# cat ./.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA7MMO43KbYEIOWDDm+uVLRT1ZSkDNaFIDnuYTEspoTb5g56eH
......
-----END RSA PRIVATE KEY-----
step 05 编写自动构建脚本
[root@jenkins ~]# mkdir /scripts
[root@jenkins ~]# vim /scripts/jenkins_deploy_html.sh
#!/usr/bin/bash
for host in {10.0.0.17,10.0.0.18}
do
scp -rp $WORKSPACE/* root@$host:/html
done
[root@jenkins ~]# chmod +x /scripts/jenkins_deploy_html.sh
[root@jenkins ~]# ll /scripts/jenkins_deploy_html.sh
-rwxr-xr-x 1 root root 100 Mar 1 14:37 /scripts/jenkins_deploy_html.sh
step 06 优化job
#!/usr/bin/bash
Date=$(date +%F-%H-%M)
Web_Host="10.0.0.17 10.0.0.18"
Project_Name="HTML-monitor-$Date"
Sdir=/opt
Ddir=/Code
WorkDir=/Web
function_tar() {
cd $WORKSPACE
tar czf $Sdir/${Project_Name}.tar.gz ./*
}
function_scp() {
for host in ${Web_Host}
do
scp -rp $Sdir/${Project_Name}.tar.gz root@$host:/opt
ssh root@$host "mkdir -p ${Ddir}${WorkDir}/${Project_Name} && \
tar xf /opt/${Project_Name}.tar.gz -C ${Ddir}${WorkDir}/${Project_Name} && \
rm -f /opt/${Project_Name}.tar.gz && \
rm -rf /html && \
ln -s ${Ddir}${WorkDir}/${Project_Name} /html"
done
}
function_deploy() {
function_tar
function_scp
}
function_deploy
step 07 模拟更新代码
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ vim index.html
...
<a class="logo pull-left" href="index.html" style="width: 233px">Monitor Plat v1.0</a>
...
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git add .
warning: LF will be replaced by CRLF in index.html.
The file will have its original line endings in your working directory
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git commit -m "Monitor Plat v1.0"
[master e9b7d61] Monitor Plat v1.0
1 file changed, 1 insertion(+), 1 deletion(-)
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git push -u origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 334 bytes | 334.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To http://gitlab.aspen.com/dev/monitor.git
a371858..e9b7d61 master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
step 08 基于参数化构建优化
#!/usr/bin/bash
Date=$(date +%F-%H-%M)
Web_Host="10.0.0.17 10.0.0.18"
Project_Name="HTML-monitor-$Date-${git_version}"
Sdir=/opt
Ddir=/Code
WorkDir=/Web
function_tar() {
cd $WORKSPACE
tar czf $Sdir/${Project_Name}.tar.gz ./*
}
function_scp() {
for host in ${Web_Host}
do
scp -rp $Sdir/${Project_Name}.tar.gz root@$host:/opt
ssh root@$host "mkdir -p ${Ddir}${WorkDir}/${Project_Name} && \
tar xf /opt/${Project_Name}.tar.gz -C ${Ddir}${WorkDir}/${Project_Name} && \
rm -f /opt/${Project_Name}.tar.gz && \
rm -rf /html && \
ln -s ${Ddir}${WorkDir}/${Project_Name} /html"
done
}
function_deploy() {
function_tar
function_scp
}
function_deploy
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ vim index.html
......
<a class="logo pull-left" href="index.html" style="width: 233px">Monitor Plat v1.3</a>
......
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git add .
gwarning: LF will be replaced by CRLF in index.html.
The file will have its original line endings in your working directory
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git commit -m "ver 1.3"
[master 7096ce8] ver 1.3
1 file changed, 1 insertion(+), 1 deletion(-)
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 311 bytes | 311.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
To http://gitlab.aspen.com/dev/monitor.git
eac358d..7096ce8 master -> master
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git tag -a "v1.3" -m "tag ver 1.3"
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/monitor (master)
$ git push --tags
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 157 bytes | 157.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://gitlab.aspen.com/dev/monitor.git
* [new tag] v1.3 -> v1.3
step 09 基于git paremeter插件构建优化
step 10 实现代码回退
#!/bin/bash
Web_Host="10.0.0.17 10.0.0.18"
Backup_File=$(ssh root@10.0.0.18 "find /Code/Web -iname *-${git_version} -type d")
function_rollback() {
for i in ${Web_Host}
do
ssh root@$i "rm -rf /html && \
ln -s ${Backup_File} /html"
done
}
function_rollback
2. Jenkins部署Java
step 00 准备环境(Nginx+Tomcat)
[root@lb01 ~]# cat /etc/nginx/conf.d/jenkins_test_proxy.conf
upstream aspen {
server 172.16.1.17:8080;
server 172.16.1.18:8080;
}
server {
listen 80;
server_name html.aspen.com;
location / {
proxy_pass http://aspen;
proxy_set_header Host $http_host;
}
}
[root@lb01 ~]# systemctl restart nginx
[root@web01 ~]# netstat -lntp | grep 8080
tcp6 0 0 :::8080 :::* LISTEN 8190/java
[root@web02 ~]# netstat -lntp | grep 8080
tcp6 0 0 :::8080 :::* LISTEN 7961/java
step 01 上传代码至Gitlab
示例代码 提取码:t905 |
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git remote remove origin
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git remote -v
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git remote add origin http://gitlab.aspen.com/dev/java.git
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git add .
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git commit -m "first commit"
On branch master
nothing to commit, working tree clean
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git push -u origin master
......
Branch 'master' set up to track remote branch 'master' from 'origin'.
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git tag -a v1.0 -m "java_code 1.0"
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git push --tags
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 160 bytes | 160.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://gitlab.aspen.com/dev/java.git
* [new tag] v1.0 -> v1.0
step 02 手动拉取代码
[root@jenkins ~]# git clone git@gitlab.aspen.com:dev/java.git
Cloning into 'java'...
remote: Enumerating objects: 20, done.
remote: Counting objects: 100% (20/20), done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 20 (delta 2), reused 0 (delta 0)
Receiving objects: 100% (20/20), done.
Resolving deltas: 100% (2/2), done.
[root@jenkins ~]# cd java/
[root@jenkins ~/java]# tree .
.
├── dist
│ └── hello-world.war
├── pom.xml
├── README.md
└── src
└── main
└── webapp
├── index.jsp
└── WEB-INF
└── web.xml
5 directories, 5 files
step 03 安装编译插件
maven插件依赖于Java程序运行。 |
yum install -y maven |
[root@jenkins ~/java]# yum install -y maven
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
......
Installed:
maven.noarch 0:3.0.5-17.el7
......
Complete!
[root@jenkins ~/java]# java -version
openjdk version "1.8.0_282"
OpenJDK Runtime Environment (build 1.8.0_282-b08)
OpenJDK 64-Bit Server VM (build 25.282-b08, mixed mode)
[root@jenkins ~/java]# mvn -version
Apache Maven 3.0.5 (Red Hat 3.0.5-17)
Maven home: /usr/share/maven
Java version: 1.8.0_282, vendor: Red Hat, Inc.
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-1.el7_9.x86_64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-957.el7.x86_64", arch: "amd64", family: "unix"
step 04 配置maven国内源
可以使用Nexus服务搭建本地的Maven仓库。 |
# /etc/maven/settings.xml < mirrors > < mirror >
< id >alimaven< /id >
< mirrorOf >central< /mirrorOf >
< name >aliyun maven< /name >
< url >http://maven.aliyun.com/nexus/content/repositories/central< /url >
< /mirror > |
[root@jenkins ~/java]# awk '/<mirrors>/,/<\/mirrors>/' /etc/maven/settings.xml
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven.</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central</url>
</mirror>
</mirrors>
step 05 编译
执行编译时,需进入项目目录。 |
mvn clean package |
[root@jenkins ~/java]# mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Hello World Web Application Repository 1.0.0
[INFO] ------------------------------------------------------------------------
Downloading: http://maven.aliyun.com/nexus/content/repositories/central/org/apache/maven/plugins/maven-clean-plugin/2.4.1/maven-clean-plugin-2.4.1.pom
......
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 31.407s
[INFO] Finished at: Fri Mar 05 15:29:55 CST 2021
[INFO] Final Memory: 10M/31M
[INFO] ------------------------------------------------------------------------
[root@jenkins ~/java]# ls
dist pom.xml README.md src target
[root@jenkins ~/java]# tree target/
target/
├── hello-world-war-1.0.0
│ ├── index.jsp
│ ├── META-INF
│ └── WEB-INF
│ ├── classes
│ └── web.xml
├── hello-world-war-1.0.0.war
├── maven-archiver
│ └── pom.properties
└── surefire
6 directories, 4 files
编译缓存jar包存放目录
缓存编译的jar包存放在当前用户下.m2目录下。 |
[root@jenkins ~]# du -sh ./.m2/
4.0M ./.m2/
[root@jenkins ~]# find ./.m2 -iname *.jar | head -4
./.m2/repository/org/apache/maven/plugins/maven-clean-plugin/2.4.1/maven-clean-plugin-2.4.1.jar
./.m2/repository/org/apache/maven/plugins/maven-resources-plugin/2.5/maven-resources-plugin-2.5.jar
./.m2/repository/org/apache/maven/plugins/maven-compiler-plugin/2.3.2/maven-compiler-plugin-2.3.2.jar
./.m2/repository/org/apache/maven/plugins/maven-surefire-plugin/2.10/maven-surefire-plugin-2.10.jar
step 06 手动上线代码
[root@jenkins ~/java]# ssh root@10.0.0.17 'rm -rf /application/tomcat/webapps/*'
[root@jenkins ~/java]# ssh root@10.0.0.18 'rm -rf /application/tomcat/webapps/*'
[root@jenkins ~/java]# scp target/hello-world-war-1.0.0.war root@10.0.0.17:/application/tomcat/webapps/ROOT.war
hello-world-war-1.0.0.war 100% 2403 1.1MB/s 00:00
[root@jenkins ~/java]# scp target/hello-world-war-1.0.0.war root@10.0.0.18:/application/tomcat/webapps/ROOT.war
hello-world-war-1.0.0.war
[root@jenkins ~/java]# ssh root@10.0.0.18 'ls /application/tomcat/webapps/'
ROOT
ROOT.war
[root@jenkins ~/java]# ssh root@10.0.0.17 'ls /application/tomcat/webapps/'
ROOT
ROOT.war
step 07 重启Tomcat服务
[root@jenkins ~/java]# ssh root@10.0.0.17 'pkill java && /application/tomcat/bin/startup.sh'
Tomcat started.
[root@jenkins ~/java]# ssh root@10.0.0.18 'pkill java && /application/tomcat/bin/startup.sh'
Tomcat started.
step 08 创建Job(Jenkins)
[root@jenkins ~/java]# mvn -version
Apache Maven 3.0.5 (Red Hat 3.0.5-17)
Maven home: /usr/share/maven
Java version: 1.8.0_282, vendor: Red Hat, Inc.
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-1.el7_9.x86_64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-957.el7.x86_64", arch: "amd64", family: "unix"
step 09 编写自动构建脚本
[root@jenkins ~]# cat /scripts/jenkins_deploy_java.sh
#!/usr/bin/bash
Date=$(date +%F-%H-%M)
Web_Host="10.0.0.17 10.0.0.18"
Project_Name="Java-ROOT-$Date-${git_version}"
Sdir=/opt/Java_Project
Ddir=/Code/Java
Tomcat_Path=/application/tomcat/webapps
function_deploy() {
for host in ${Web_Host}
do
ssh root@$host "mkdir -p ${Sdir}"
scp -rp ${WORKSPACE}/target/*.war root@$host:${Sdir}/${Project_Name}.war
ssh root@$host "mkdir -p ${Ddir} && \
cd ${Sdir} && \
unzip ${Project_Name}.war -d ${Ddir}/${Project_Name} && \
rm -f ${Sdir}/${Project_Name}.war && \
rm -rf ${Tomcat_Path}/ROOT && \
ln -s ${Ddir}/${Project_Name} ${Tomcat_Path}/ROOT && \
pkill java; \
/application/tomcat/bin/startup.sh "
done
}
function_deploy
step 10 模拟更新代码
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ sed -i 's#Aspen_Han v1.2#Yong_Han v1.3#g' src/main/webapp/index.jsp
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ sed -n 6p src/main/webapp/index.jsp
<h1>Hello World! Yong_Han v1.3</h1>
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git add .
warning: LF will be replaced by CRLF in src/main/webapp/index.jsp.
The file will have its original line endings in your working directory
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git commit -m "new version"
[master 45e6601] new version
1 file changed, 1 insertion(+), 1 deletion(-)
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git push origin master
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 12 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 460 bytes | 230.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0)
To http://gitlab.aspen.com/dev/java.git
8a43fb4..45e6601 master -> master
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git tag -a "v1.3" -m "Young_Han"
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git push origin --tags
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 160 bytes | 160.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://gitlab.aspen.com/dev/java.git
* [new tag] v1.3 -> v1.3
三、扩展
1. 钉钉通知
该功能依赖Jenkins的DingDing插件实现。 |
step 1 添加群组机器人
step 2 Jenkins集成钉钉
step 3 测试
2. 邮件通知
未完待续...
3. Gitlab自动触发Jenkins
该功能基于Gitlab的Webhook实现,常用于企业测试环境的代码部署,不建议使用在生产环境中。 |
step 1 改造jenkins项目
step 2 gitlab允许访问本地Web钩子
step 3 gitlab增加Webhook
step 4 模拟提交代码
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ sed 's#Yong_Han v1.3#Aspen_Han WEB_HOOK Test#g' src/main/webapp/index.jsp -i
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ sed -n 6p src/main/webapp/index.jsp
<h1>Hello World! Aspen_Han WEB_HOOK Test</h1>
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git add .
warning: LF will be replaced by CRLF in src/main/webapp/index.jsp.
The file will have its original line endings in your working directory
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git commit -m "WEB_Hook"
[master b5cfefd] WEB_Hook
1 file changed, 1 insertion(+), 1 deletion(-)
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git push origin
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 12 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 471 bytes | 235.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0)
To http://gitlab.aspen.com/dev/java.git
step 5 验证
4. 分布式构建
Slave节点插件应与Master节点插件一致,并需要与各个关联节点实现免密。 |
step1 增加Slave节点
系统管理 -> 节点管理 -> 新建节点 |
step2 启用Slave节点
系统管理 -> 节点管理 -> 指定节点 -> 启动代理 |
step3 测试主从关系
注意各种工具插件配置文件的同步以及各种部署脚本的同步 |
step 4 将指定任务分配至指点节点
pipeline {
// agent any
agent { label 'Branch01' } //分配指定节点执行任务
parameters {
string(name: 'git_version', defaultValue: 'v1.0', description: 'Gitlab项目Tag')
}
......
}
四、Pipeline
Pipeline是运行在Jenkins上的工作框架,通过“代码的方式”将多个任务链接起来。 |
1. 优势
- 直观展示每个阶段的任务
- 直观展示每个阶段的执行时间
- 快速定位任务出现错误的位置
2. 作用
传统的Jenkins任务部署流程,需在图形界面下进行点击(交互式操作),使用pipeline能够实现每一步自动化,不需要人为干预。
3. 基础语法
Pipeline是一种固定格式,必须遵行。 |
pipeline { #所有代码包含在pipeline{}内
agent any #agent{}定义任务在哪台主机上运行,可以是any,none等
environment { #environment{}用于定义环境变量
变量名='变量值'
}
stages { #stages{}类似一个大项目的集合,主要用于包含所有stage子任务
stage('任务名1'){ #stage{}类似单个子任务,主要用来包含steps子层
steps { #steps{} 用来实现具体执行的操作
执行命令
}
}
stage('任务名2'){
steps {
执行命令
}
}
}
post { #satges所有任务执行后,出发post任务
failure { #构建失败钉钉通知
dingTalk accessToken: '令牌',imageUrl: '',jenkinsUrl: 'jenkins服务地址',message: '消息', notifyPeople: ''
}
success { #构建成功钉钉通知
dingTalk accessToken: '令牌',imageUrl: '',jenkinsUrl: 'jenkins服务地址',message: '消息', notifyPeople: ''
}
}
} |
4. pipeline项目改造
以Java项目为示例
step 1 创建pipeline项目
step 2 语法查询
step 3 编写pipeline 脚本
pipeline {
agent any
parameters {
string(name: 'git_version', defaultValue: 'v1.0', description: 'Gitlab项目Tag')
}
stages {
stage('获取代码'){
steps {
checkout([$class: 'GitSCM', branches: [[name: '${git_version}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '0776c87e-9d98-4023-a9ac-df5384d499ee', url: 'git@gitlab.aspen.com:dev/java.git']]])
}
}
stage('质量检测'){
steps {
sh '/usr/local/sonar-scanner/bin/sonar-scanner -Dsonar.projectKey=${JOB_NAME} -Dsonar.sources=. -Dsonar.java.binaries=target/sonar'
}
}
stage('代码编译'){
steps {
sh 'mvn clean package'
}
}
stage('代码部署'){
steps {
sh 'sh -x /scripts/jenkins_deploy_java.sh'
}
}
}
post {
failure {
dingTalk accessToken: '620c7530a39fe8be70ba2c55d4e4b4adbd2806502bf61f13f6def25debeba229', imageUrl: '', jenkinsUrl: 'http://jenkins.aspen.com:8080/', message: '代码构建失败', notifyPeople: ''
}
success {
dingTalk accessToken: '620c7530a39fe8be70ba2c55d4e4b4adbd2806502bf61f13f6def25debeba229', imageUrl: '', jenkinsUrl: 'http://jenkins.aspen.com:8080/', message: '代码构建成功', notifyPeople: ''
}
}
}
- git拉取代码
- 钉钉通知
step 4 测试pipeline
- 常规视图
- Blue Ocean
5.pipeline scripts from SCM
step 1 项目改造
step 2 编写脚本
pipeline {
agent any
parameters {
string(name: 'git_version', defaultValue: 'v1.0', description: 'Gitlab项目Tag')
}
stages {
stage('获取代码'){
steps {
checkout([$class: 'GitSCM', branches: [[name: '${git_version}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '0776c87e-9d98-4023-a9ac-df5384d499ee', url: 'git@gitlab.aspen.com:dev/java.git']]])
}
}
stage('质量检测'){
steps {
sh '/usr/local/sonar-scanner/bin/sonar-scanner -Dsonar.projectKey=${JOB_NAME} -Dsonar.sources=. -Dsonar.java.binaries=target/sonar'
}
}
stage('代码编译'){
steps {
sh 'mvn clean package'
}
}
stage('代码部署'){
steps {
sh 'sh -x /scripts/jenkins_deploy_java.sh'
}
}
}
post {
failure {
dingTalk accessToken: '620c7530a39fe8be70ba2c55d4e4b4adbd2806502bf61f13f6def25debeba229', imageUrl: '', jenkinsUrl: 'http://jenkins.aspen.com:8080/', message: '代码构建失败', notifyPeople: ''
}
success {
dingTalk accessToken: '620c7530a39fe8be70ba2c55d4e4b4adbd2806502bf61f13f6def25debeba229', imageUrl: '', jenkinsUrl: 'http://jenkins.aspen.com:8080/', message: '代码构建成功', notifyPeople: ''
}
}
}
step 3 提交项目
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ vim Jenkinsfile
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git add .
warning: LF will be replaced by CRLF in Jenkinsfile.
The file will have its original line endings in your working directory
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git commit -m "SCM mode for pipeline"
[master 824ad6d] SCM mode for pipeline
1 file changed, 36 insertions(+)
create mode 100644 Jenkinsfile
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git push origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 946 bytes | 946.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To http://gitlab.aspen.com/dev/java.git
b5cfefd..824ad6d master -> master
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git tag -a "v1.4" -m "tag ver 1.4 add SCM"
Aspen_Han@DESKTOP-QQSLJ85 MINGW64 /f/code/java (master)
$ git push --tags
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 164 bytes | 164.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To http://gitlab.aspen.com/dev/java.git
* [new tag] v1.4 -> v1.4