Jenkins 介绍
Jenkins(原名 Hudson)是开源的 CI/CD 工具。
官网: https://jenkins.io 插件: https://plugins.jenkins.io
Jenkins 是一个持续集成和持续交付工具,可用作简单的 CI 服务器,或者变成任何项目的持续交付中心。 Jeninks 是一个基于 Java 的独立程序,可以立即运行,包含 Windows、Mac OS X 和其他类 Unix 操作系统。 Jenkins 可以通过 web 界面轻松配置,包括及时错误检查和内置帮助。 Jenkins 支持插件扩展。
特性:
- 变更支持: Jenkins 能从代码仓库中获取代码更新列表。
- 永久链接: Jenkins 的 web 链接地址都是永久链接地址。因此,可以在各文档中直接使用。
- 消息通知: Jenkins 可集成 Email/RSS/IM。
- 测试报告: Jenkins 可以用图标等形式提供详细的 Junit/TestNG 测试报告。
- 分布式构建: Jenkins 可以把集成构建等工作分发到多台计算机中完成。
- 文件指纹: Jenkins 会保存每次构建过程中使用的文件信息、构建产生的文件信息。
- 三方插件
参考:
https://www.bilibili.com/video/BV1R54y117MD杂- https://www.bilibili.com/video/BV17T4y1m7o2
- todo https://www.bilibili.com/video/BV1z34y1q738
- todo https://www.bilibili.com/video/BV1144y1j77n
- todo https://www.bilibili.com/video/BV1V1421b7CK/ (进阶)
概念
软件开发生命周期(Software Development Life Cycle, SDLC)集合了需求分析、设计、开发、测试、部署等过程。
持续集成(Continuous Integration,CI)
持续交付(Continuous Delivery,CD)
持续部署(Continuous Deployment,CD)
安装
https://www.jenkins.io/doc/book/installing/
war
Jenkins war 捆绑了 winstone 和 jetty servlet container。所以可以直接运行,启动 web 服务。
参数: https://www.jenkins.io/doc/book/installing/initial-settings/
环境准备
# userdel jenkins
# groupdel ci
groupadd ci
useradd jenkins -g ci # usermod -G ci jenkins
# passwd jenkins
mkdir -p /data/software
chown -R jenkins:ci /data/software
su jenkins
cd /data/software
wget http://mirrors.jenkins.io/war-stable/lastest/jenkins.war # 2.249.1
# https://mirrors.jenkins.io/war-stable/2.249.1/jenkins.war
$ vim /etc/profile
# JDK
export JAVA_HOME=/usr/local/java/jdk1.8.0_181
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarjava -jar jenkins.war --httpPort=8888
# nohup java -jar /data/software/jenkins.war --httpPort=8777 --httpsPort=8778 > /data/software/jenkins.log 2>&1 &
# 开放端口
# 如果是云服务器,开放安全组即可
# 如果是虚拟机,则防火墙开放端口
firewall-cmd --zone=public --add-port=8777/tcp --permanent
firewall-cmd --reloadmaven clean install -DskipTests
java -jar app.jarDocker
成熟的部署方式肯定是镜像方式,如:k8s
# 版本选择例子:
# 最新镜像
docker pull jenkins/jenkins:2.235.5-alpine
docker pull jenkins/jenkins:2.253-centos7
# 推荐
docker pull jenkins/jenkins:2.204.5
docker pull jenkins/jenkins:2.204.5-alpine# docker pull jenkins/jenkins:lts
# docker run -di --name=jenkins -p 8080:8080 -v /mydata/jenkins_home/:/var/jenkins_home jenkins/jenkins:lts
mkidr -p /data/jenkins && chown -R 1000:1000 /data/jenkins
docker run -itd --name jenkins -p 8080:8080 -p 5000:5000 -u root \
-e JAVA_OPTS=-Duser.timezone=Asia/Shanghai \
-v /data/jenkins/:/var/jenkins_home/ \
--restart always jenkins/jenkins:2.204.5-alpine
# 💡端口 5000 用于 jnlp4 协议连接 agent 节点中文镜像制作
Jenkins 中文社区
官网: https://bintray.com/jenkins-zh/generic/jenkins
docker: https://hub.docker.com/r/jenkinszh/jenkins-zh
github: https://github.com/jenkins-zh/jenkins-formulasFROM jenkins/jenkins:2.204.5-alpine
# 修改源
RUN echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories && \
echo "http://mirrors.aliyun.com/alpine/latest-stable/community" >> /etc/apk/repositories
# 安装需要的软件,解决时区问题
RUN apk --update add curl bash tzdata && \
rm -rf /var/cache/apk/*
# 参考中文社区的 Dockerfile
# https://github.com/jenkins-zh/jenkins-formulas/blob/2.190.3/Dockerfile
ENV TZ Asia/Shanghai
ENV JENKINS_UC https://updates.jenkins-zh.cn
ENV JENKINS_UC_DOWNLOAD https://mirrors.tuna.tsinghua.edu.cn/jenkins
ENV JENKINS_OPTS="-Dhudson.model.UpdateCenter.updateCenterUrl=https://updates.jenkins-zh.cn/update-center.json"
ENV JENKINS_OPTS="-Djenkins.install.runSetupWizard=false"
COPY init.groovy /usr/share/jenkins/ref/init.groovy.d/init.groovy
COPY hudson.model.UpdateCenter.xml /usr/share/jenkins/ref/hudson.model.UpdateCenter.xml
COPY mirror-adapter.crt /usr/share/jenkins/ref/mirror-adapter.crtother
BUILD_ID=dontKillMe
cd target
ps -ef | grep demo-0.0.1-SNAPSHOT.jar | grep -v grep | awk '{print "kill -l5 $2"}' | sh
nohup java -jar demo-0.0.1-SNAPSHOT.jar > app.log 2>&1 &http://128.0.0.1:8080/restart 重启
参考:
常用设置
系统管理
全局工具设置
# 系统管理/全局工具设置/Maven|JDK|Git|...JDK
todo
Maven
todo
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
<localRepository>/data/software/repository</localRepository>
<mirrors>
<mirror>
<id>aliyun-maven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven mirror</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
</mirrors>
</settings>安全
重置用户密码
常用于:忘记密码
修改 useSecurity 为 false
<useSecurity>true</useSecurity>相关信息
每次重启后,这个值会变回 true
重启 127.0.0.1:8777/restart
# 开启用户模式(这样才能改用户密码)
Manage Jenkins/Configure Global Security/安全域/Jenkins' own user database
# 开启登录检查
Manage Jenkins/Configure Global Security/授权策略/Logged-in users can do anything凭证配置
todo Credentials Binding 用户凭证插件安装
角色权限管理
Role-based Authorization Strategy
todo
Extra CSS在文本框内贴上 CSS 样式Git Parameter Plugin安装后可以选择按照git tag或者branch发布版本NodeJS Plugin安装后可以执行npm指令,打包和发布前端代码SonarQube Scanner for Jenkins安装后可以执行sonar scanner指令,跑 CI 时检查代码质量Maven Integration Plugin设置maven指令的classpath和指令路径Workspace Cleanup Plugin可以指定workspace最多保留多少个历史命令
插件管理
节点配置
todo https://www.bilibili.com/video/BV17T4y1m7o2
流水线(Pipline)
Pipeline 是一套运行在 Jenkins 上的工作流框架,将原来独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排和可视化工作。
特性:
- 代码化 —— Pipeline 以代码的形式实现,方便编辑、审查和迭代
- 持久 —— Pipeline 计划外重启服务器,可恢复任务
- 可停止 —— Pipeline 可接入交互式输入,以确定是否继续执行 Pipeline
- 可计划 —— Pipeline 支持复杂的持续交付要求。支持
fork/join、循环执行、并行执行任务。 - 可扩展 —— Pipeline 插件支持其 DSL 的自定义扩展,以及与其他插件集成的多个选项
相关信息
参考:
- Jenkins2 Pipeline Docs - http://zeyangli.github.io/chapter5/1/
相关插件
git 插件:
jenkins/系统管理/节点管理/可选插件/git
pipeline 插件:(安装插件后,创建任务的时候多了 “流水线” 类型)
jenkins/系统管理/节点管理/可选插件/pipeline流水线编写
Pipeline 脚本由 Grovvy 语言实现。
支持两种语法:
Declarative声明式 (推荐)Scripted Pipeline脚本式
脚本式(Scripted)
node('jenkinsagent-154') {
stage('Preparation') { // for display purpose
echo 'Hello Scripted Pipeline'
}
}声明式(Declarative)
pipeline {
// agent any
agent none
stages {
stage('Hello') {
steps {
echo 'Hello Declarative Pipeline'
}
}
}
}Jenkinsfile
Pipeline 有两种创建方法:
- 直接在 Jenkins 的 Web UI 界面中输入脚本
- 通过创建一个 Jenkinsfile 脚本文件放入项目源库(SCM)中
共享库(Shared Library)
共享库(shared library)是一些独立的 Groovy 脚本集合。我们可以在运行 Pipeline 的时候获取这些共享库代码。
导入共享库
Library 'your-shared-library'@Library('your-shared-library')—— sharelibrary 基本概念,配置 sharelibrary,编写 Jenkinsfile
使用常用的流水线方法 —— 常用的流水线方法,httpRequest,readJson,readYaml 等
Pipeline 定义 - agent/options | 准备阶段
agent {
node {
label "master" // 指定运行节点的标签或名称
customWorkspace "${workspace}" // 指定运行工作目录(可选)
}
}
options {
timestamps() // 插件:日志会有时间
skipDefaultCheckout() // 删除隐式 checkout scm 语句
disableConcurrentBuilds() // 禁止并行
timeout(time: 1, unit: 'HOURS') // 流水线超时设置 1h
}Pipeline 定义 - stages | 构建阶段
stages {
stage("GetCode") {
steps {
timeout(time:5, unit:"MINUTES") {
script {
println("获取代码")
}
}
}
stage("Build") {
steps {
timeout(time:20, unit:"MINUTES") {
script {
println("应用打包")
}
}
}
}
stage("CodeScan") {
steps {
timeout(time:30, unit:"MINUTES") {
script {
println("代码扫描")
}
}
}
}
}
}Pipeline 定义 - post | 构建后操作
post {
// 总是执行
always {
script {
println("always")
}
}
// 成功后执行
success {
script {
// currentBuild 局部变量
// description 构建描述
currentBuild.description = "\n 构建成功!✅"
}
}
// 失败后执行
failure {
script {
currentBuild.description = "\n 构建失败!❌"
}
}
// 取消后执行
aborted {
script {
currentBuild.description = "\n 构建取消!❕"
}
}
}Demo
部署 war
$ weget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.66/bin/apache-tomcat-8.5.66.tar.gz
$ tar -zxvf apache-tomcat-8.5.66.tar.gz
$ cd apache-tomcat-8.5.66/bin
$ ./startup.sh
$ tail -222f ../logs/catalina.out # 查看日志,未报错即可
# 开启防火墙
$ firewall-cmd --zone=public --add-port=8080/tcp --permanent
$ firewall-cmd --reload部署 jar
#!/bin/bash
DIR="/data/app"
projectName="maven-test"
server_ips="192.168.1.8"
for server_ip in ${server_ips[@]}; do
echo "$server_ip"
echo "backup"
ssh -Tq -oStrictHostKeyChecking=no admin@${server_ip} <<EOF
mkdir -p $DIR/backup/${projectName}
if [ -f "$DIR/${project}/${projectName}.jar" ]; then
mv -v $DIR/${project}/${projectName}.jar $DIR/backup/${project}/${projectName}.jar
fi
EOF
echo "download"
scp -q -oStrictHostKeyChecking=no ${WORKSPACE}/target/*.jar admin@${server_ip}:/tmp/${projectName}.jar
echo "deploy"
ssh -q -oStrictHostKeyChecking=no admin@${server_ip} <<EOF
mv -v /tmp/${projectName}.jar $DIR/${projectName}/${projectName}.jar
cd ${DIR}/${projectName}
sh stop.sh
sh start.sh
EOF
done
echo "success"#!/bin/bash
set -e # 错误退出
set -o pipefail
APP_ID=maven-test
APP_DIR="/data/app"
nohup java -Dspring.profiles.active=dev -jar ${APP_DIR}/${APP_ID}/${APP_ID}.jar > release_out.log &
start_ok=false
if [[ $? = 0 ]]; then
sleep 3
tail -n 10 release_out.log
sleep 5
tail -n 50 release_out.log
fi
aaa=${grep "Started" release_out.log | awk '{print $1}'}
if [[ -n "${aaa}" ]]; then
echo "Application started ok"
exit 0
else
echo "Application started error"
exit 1
fi#!/bin/bash
APP_ID=maven-test
ps aux | grep ${APP_ID} | grep -v 'grep' | awk '{print "kill -9 "$2}' | shWebHook
自动触发 Jenkins 构建
步骤:
- 针对不同代码仓库平台,安装对应插件。如:gitee (一般 github 默认安装了)
- 内网穿透:frp
# 钉钉内网穿透
$ git clone --depth=1 https://github.com/open-dingtalk/pierced.git
$ chmod -R 777 pierced
# 运行如下命令
# mydomain 你的二级域名前缀
# 8777 本地监听端口
$ ./pierced/linux/ding -config=./ding.cfg -subdomain=mydomain 8777离线、灰度、生产回滚代码
按分支/标签发布
| 依赖插件 | 说明 |
|---|---|
| Parameter | |
| Git Parameter |
| 参数 | 说明 | 值 |
|---|---|---|
| x/Git Parameter | 选择可以发布的分支/标签/其他。参数构建时,会主动拉取仓库相关参数供选择。 | 一般必须默认值 |
| x/Branches to build | ${branch} |
todo 主从 Jenkins 节点
本地环境:开发/测试 离线、灰度、生产环境:云服务器
通知
https://oapi.dingtalk.com/rebot/send?access_token=6cecd6cecd6cecd6cecd6cecd6cecd6cecd6cecd6cecd6cecd6cecd6cecd#!/bin/bash
#-*- coding:utf-8 -*-
tt="BUILD_DATE=$(date +%F-%T)"
message='发布完成\n项目名称: ${PROJECT_NAME}\n项目版本号: ${version}\n操作类型: $type\n触发时间: $tt\n触发人员: $BUILD_USER'
https://oapi.dingtalk.com/rebot/send?access_token=6cecd6cecd6cecd6cecd6cecd6cecd6cecd6cecd6cecd6cecd6cecd6cecd \
-H 'Content-Type: application/json' \
-d "
{
\"msgtype\": \"text\",
\"text\": {
\"content\": \"$message\"
}
}
"提示
想要获取到构建项目信息,需要在 Jenkins 的构建项目中开启: 构建环境/Set jenkins user build variables
发布完成
项目名称: tf-teacher-front
项目分支&TAG: t04_20210104_02
检出分支或TAG:
环境: t04
完成时间: 2021-01-04 15:53:22
触发人员: test-lichanjuan
完成状态: 成功蒲公英/fir.im
SonarQube
Your teammate for Code Quality and Code Security.
SonarQube empowers all developers to write cleaner and safer code.
安装
环境准备:
安装 Postgresql (SonarQube 7.9 以上版本不再支持 mysql)
$ 安装 docker
$ 配置 docker 国内镜像源
$ docker pull postgres
$ docker run --name mypostgres -d -p 5432:5432 -e POSTGRES_PASSWORD=123456 postgres
$ docker exec -it mypostgres psql -U postgres -d postgres
# 创建数据库
postgres=# create database sonar;
# 设置 sonar 用户名和密码 sonar postgres
postgres=# create user sonar;
postgres=# alter user sonar with password 'postgres';
# 授予 sonar 权限
postgres=# alter role sonar createdb;
postgres=# alter role sonar superuser;
postgres=# alter role sonar createrole;
# 更改 sonar 数据库拥有者(否则 sonarqube 连接失败)
postgres=# alter database sonar owner to sonar;
# 查看数据库
postgres=# \l
# 查看用户
postgres=# \du
# 重启数据库
$ docker exec -it mypostgres systemctl start postgresql-11安装 SonarQube
# 下载 Community 版本
$ su -
$ mkdir -p /opt/sonar
$ cd /opt/sonar
$ wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-8.9.0.43852.zip
# 解压 sonar 并设置权限
$ yum install unzip
$ unzip sonarqube-8.9.0.43852.zip
$ mv sonarqube-8.9.0.43852 sonarqube
$ useradd sonar
$ chown -R sonar. /opt/sonar
# 更改 sonar 配置
$ su sonar
$ vim /opt/sonar/sonarqube/conf/sonar.properties
sonar.jdbc.username=sonar
sonar.jdbc.password=postgres
sonar.jdbc.url=jdbc:postgresql://47.92.230.42:5432/sonar
# sonar 默认监听 9000 端口配置 JDK11
$ tar -zxvf jdk-11_linux-x64_bin.tar.gz
$ cd jdk-11/bin
$ pwd
/opt/sonar/jdk-11/bin
# 修改 sonarqube/conf/wrapper.conf 中的 java 设置
# wrapper.java.command=java
wrapper.java.command=/opt/sonar-jdk-11/bin/java
# 修改环境变量
vim /etc/profile
export ES_JAVA_HOME=/opt/sonar/jdk-11
source /etc/profile启动 sonar
$ cd /opt/sonar/sonarqube
$ su sonar ./bin/linux-x86064/sonar.sh start
$ su sonar ./bin/linux-x86064/sonar.sh status
$ su sonar ./bin/linux-x86064/sonar.sh stop
$ tail -f logs/sonar.logs
# 开放防火墙
$ firewall-cmd --zone=public --add-port=9000/tcp --permanent
$ firewall-cmd --reloadtodo Jenkins 集成 Sonar