Jenkins教程
Jenkins是一个开源的自动化服务器,用于实现软件开发过程中的持续集成和持续交付。它提供了一种灵活的方式来构建、测试和部署软件项目,以及监控项目的整个开发过程。
Jenkins可以通过插件扩展其功能,支持各种编程语言和工具。它可以与版本控制系统(如Git、Subversion)、构建工具(如Apache Maven、Gradle)、测试框架(如JUnit、Selenium)以及部署工具(如Docker、Kubernetes)等集成。
Jenkins的核心概念是作业(Job)。作业定义了构建过程的一系列步骤,包括代码的获取、编译、测试和部署等。通过配置作业,您可以指定何时触发构建、如何获取代码、构建步骤的顺序以及构建产物的处理方式。
Jenkins还提供了一个可视化的用户界面,使用户可以方便地管理和监控作业、查看构建历史和日志,并设置触发条件和通知机制。它还支持分布式构建,可以在多台计算机上同时执行构建任务,以加快构建速度和提高效率。
通过使用Jenkins,团队可以实现持续集成和持续交付的最佳实践,将软件的开发、测试和交付过程自动化,减少手动操作和人为错误,提高软件质量和交付速度。它广泛应用于各种软件开发项目和持续集成环境中。
CI、CD
安装Jenkins
Windows安装
Jenkins中文网:http://www.jenkins.org.cn/
进群下载.msi文件进行安装
Docker安装
编写docker-compose.yml
version: "3.1" services: jenkins: image: jenkins/jenkins:2.401.1-lts container_name: jenkins ports: - 8080:8080
volumes:
- ./data/:/var/jenkins_home/
2. 启动docker-compose
docker-compose up -d

这里看到启动失败了,查看容器日志发现是权限问题,无法进行write

对data文件夹赋予777权限并启动再次容器
chmod -R 777 data
docker start jenkins
3. 浏览器访问8080端口进入首页,密码可在容器日志中或者文件中查看

4. 安装插件,随便点击一个并等待插件安装完成
> 这里插件大概率会安装失败,不要紧,等下我们进去安装我们需要的插件,不用在这个地方纠结很久

5. 创建用户,这里随便输,记住账号密码即可

6. 实例配置使用默认值,点击保存并完成

## 安装插件
Jenkins的大部分功能都来自于它的插件,插件越多,功能越强大
进入插件页面

我们需要安装`Git Parameter`和`Publish Over SSH`2个插件

安装完并重启

`Git Parameter`插件用于在连接Git仓库时添加额外的参数
`Publish Over SSH`插件用于连接远程服务器
## Jenkins配置Maven、JDK、SSH
进入全局配置页面

### Maven
填写Name和Home路径
路径在填写错误时会有提示

### JDK

### SSH

滑到最底部找到 `Publish over SSH`并配置需要连接的服务器信息

使用密码进行验证

## CI
CI(持续集成)是指在团队开发过程中,频繁地将代码集成到共享代码仓库中,并自动执行构建、测试和代码质量检查等过程。其目标是确保团队成员的代码能够及时合并,并尽早发现和解决集成问题。CI的关键是自动化构建和测试,以便尽早发现代码中的错误和问题。通过持续集成,团队可以更快地交付软件,减少集成问题的风险,并提高团队的协作效率。
> 本次案例使用项目为RuoYi前后端分离多模块项目:https://gitee.com/y_project/RuoYi-Vue
>
> 采用Docker容器的方式进行部署
1. 创建一个自定义风格的项目

2. 配置项目源码信息

测试代码是否拉取成功

查看控制台日志

拉取代码成功

拉取成功之后会在Jenkins的工作空间中看到项目文件夹
使用docker部署时在挂载的data/workspace文件夹中查看。
使用windows安装版本在图中的目录中查看

3. 添加项目构建步骤:调用顶层Maven目标


再次进行构建并查看控制台日志

项目构建成功之后会在对应的工作空间的项目中生成target目录
4. 在项目根目录新建docker文件夹并编写Dockerfile和docker-compose文件
`/docker/Dockerfile`
FROM daocloud.io/library/java:8u40-jdk
COPY ruoyi-admin.jar /usr/local/
WORKDIR /usr/local
CMD java -jar ruoyi-admin.jar
`/docker/docker-compose.yml`
version: "3.1"
services:
bms-project:
build:
context: ./
dockerfile: Dockerfile
image: bms:v2.2
container_name: bms
ports:
- "4001:4001"
**编写完代码记得提交到自己Git仓库**
5. 添加构建后操作:通过SSH发送构建工件


6. 保存并执行任务
- 超时

<img src="https://qny.chengxuyi.top//typora_img/image-20230626094112712.png" alt="image-20230626094112712" />
修改超时时间保存后再次执行

在目标服务器中使用`docker ps`查看已经部署成功
> **至此,CI操作就已经完成了**
## CD
CD(持续交付/持续部署)是CI的延伸,指的是在通过持续集成构建、测试和验证代码后,自动将代码交付给生产环境或可用于生产部署的环境。持续交付的目标是使软件的交付过程自动化、可靠且可重复,以减少人工干预和减少交付的时间间隔。持续交付的流程通常包括自动化构建、自动化测试、自动化部署和自动化验证等步骤。持续部署则更进一步,指的是将经过验证的代码自动部署到生产环境中,以实现全自动的软件交付。
1. 在Gitee中配置标签

2. 在任务配置中选择参数化,并选择之前安装的`Git Parameter`


3. 新增一行构建之前的命令,切换到指定的tag分支。$tag取上面Git Parameter名称的值

> windows环境中的Jenkins无法调用shell脚本问题
在系统配置里面中配置shell为Git的sh.exe执行文件路径

4. 在配置完参数后,构建按钮变成了Build with Parameters

5. 选择对应的tag并开始构建

控制台查看执行了切换分支的命令

## SonarQube
SonarQube(前身为Sonar)是一个开源的代码质量管理平台。它提供了一个集中的平台,用于对源代码进行静态代码分析、测量代码质量、跟踪技术债务、管理代码复杂性以及监控代码规范和安全性等方面的指标。SonarQube支持多种编程语言,包括Java、C/C++、C#、Python、JavaScript等,并提供了丰富的插件生态系统,以扩展和定制功能。SonarQube还提供了直观的仪表板和报告,用于可视化和监控代码质量的变化趋势。
### Docker形式安装SonarQube
编写docker-compose.yml
version: '3.1'
services:
db:
image: postgres
container_name: db
ports:
- 5432:5432
networks:
- sonarnet
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
sonarqube:
image: sonarqube:9.9-community
container_name: sonarqube
depends_on:
- db
ports:
- 9000:9000
networks:
- sonarnet
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
networks:
sonarnet:
driver: bridge
启动命令:docker-compose up -d
**Windows启动失败查看SonarQube容器日志**
bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
**启动失败解决办法:https://blog.csdn.net/qq_38680405/article/details/126700722**
> 浏览器打开端口为9000
### Maven与SonarQube集成
#### 修改Maven配置文件:settings.xml
在profiles标签中新增SonarQube配置信息并激活配置
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.login>admin</sonar.login>
<sonar.password>123456</sonar.password>
<sonar.host.url>http://localhost:9000</sonar.host.url>
</properties>
</profile>
<activeProfile>sonar</activeProfile>
#### 在项目根目录运行:mvn sonar:sonar

在SonarQube提供的可视化界面查看检查结果

## SonarScanner
SonarScanner是SonarQube的命令行工具,用于将源代码发送到SonarQube服务器进行分析。它是一个独立的客户端工具,可以与SonarQube进行集成,以便在分析阶段捕获和处理代码。SonarScanner通过读取配置文件(如`sonar-project.properties`)或通过命令行参数传递配置信息,确定需要分析的项目和相关设置。它会扫描项目的源代码,执行静态代码分析,并将结果提交到SonarQube服务器进行处理和展示。
SonarScanner支持多种构建工具和编程语言,包括Maven、Gradle、Ant、MSBuild等。它可以轻松地集成到持续集成(CI)和持续交付(CD)流程中,使开发团队能够在每次代码提交或构建时自动进行代码质量分析。
下载地址:https://docs.sonarqube.org/latest/analyzing-source-code/scanners/sonarscanner/
下载自己对应的操作系统文件

### 命令行方式检查代码
#### 打开SonarScanner配置文件:sonar-scanner.properties

更改后的文件内容为
Configure here general information about the environment, such as SonarQube server connection details for example
No information about specific project should appear here
----- Default SonarQube server
对应sonarQube的url地址
sonar.host.url=http://localhost:9000
----- Default source code encoding
sonar.sourceEncoding=UTF-8
#### 执行检查
切换到SonarScanner目录
cd E:environmentsonar-scanner-4.8.0.2856-windowsbin
执行
./sonar-scanner.bat -D sonar.java.binaries=.//target -D sonar.source=./ -D sonar.login=sqa_684223ae6877050107f0b3e3368e72fc06759874 -D sonar.projectKey=bms-project -D sonar.projectBaseDir=E:overload-workingbms-dianshang-project -D sonar.exclusions=RuoYi-Vue3/
注释
sonar.java.binaries 编译后的class文件位置
sonar.source 源码位置
sonar.login token
sonar.projectKey 项目的Key
sonar.projectBaseDir 项目的基本路径
sonar.exclusions 需要排除的文件夹或者文件
## Jenkins集成SonarQubeScanner
在构建项目时对代码进行检查
1. Jenkins安装SonarQubeScanner插件

2. 生成密钥:打开SonarQube服务端

复制令牌

3. 配置SonarQube服务端
类型选择Secret text,输入复制的令牌


4. 构建项目时添加SonarQubeScanner步骤


5. 重新构建
> 在构建成功之后执行了SonarScanner命令进行检查

SonarQube服务端也新增了一个检查

## Harbor
Harbor是一个开源的企业级容器镜像仓库,用于存储、分发和管理Docker镜像。它提供了一个安全可靠的集中式存储库,使团队能够方便地共享和管理容器镜像。
下面是Harbor的一些主要特性:
1. **安全性和权限管理**:Harbor支持用户身份验证和授权机制,可以通过集成LDAP、Active Directory等进行用户认证。它还提供细粒度的访问控制,使管理员能够精确地管理用户对镜像的访问权限。
2. **镜像复制和同步**:Harbor支持镜像的复制和同步功能,可以在多个Harbor实例之间同步镜像。这有助于实现分布式部署和高可用性需求。
3. **漏洞扫描和安全审计**:Harbor集成了漏洞扫描工具,可以对上传到仓库中的镜像进行安全扫描,识别潜在的漏洞和安全风险。此外,Harbor还提供审计日志功能,记录了对仓库的操作和访问,方便进行安全审计。
4. **复制策略和镜像签名**:Harbor支持灵活的复制策略,可以定义哪些镜像需要复制到其他Harbor实例。此外,Harbor还支持镜像签名,以确保镜像的完整性和来源可信。
5. **项目和命名空间**:Harbor支持将镜像进行组织和管理,使用项目和命名空间来划分不同的逻辑单元。这有助于团队对镜像进行分类、管理和权限控制。
6. **可视化界面和API支持**:Harbor提供了易于使用的Web界面,使用户可以通过图形化界面进行镜像的上传、浏览和管理。此外,Harbor还暴露了一组RESTful API,方便与其他工具和系统进行集成。
总而言之,Harbor是一个功能丰富、安全可靠的容器镜像仓库,适用于企业级的容器镜像管理和分发需求。它提供了许多有用的特性,使团队能够轻松地构建、共享和管理容器镜像。
### 安装Harbor
[GitHub传送门](https://github.com/goharbor/harbor/releases):选择离线或者在线版本

1. 将[harbor-offline-installer-v2.8.2.tgz](https://github.com/goharbor/harbor/releases/download/v2.8.2/harbor-offline-installer-v2.8.2.tgz)上传到服务器或虚拟机中并解压
2. 将`harbor.yml.tmpl`拷贝一份并重命名为`harbor.yml`。harbor启动时只会识别`harbor.yml`配置文件
3. 修改`harbor.yml`内容

4. 执行`install.sh`。harbor部署方式是使用docker容器部署,所有install之前需要先安装好Docker和Docker compose
5. 部署好查看Docker容器运行情况

6. 浏览器访问89端口

### Harbor基本操作
#### 新建项目


输入项目名称、访问级别、项目配合限制:-1为不限制
### 将镜像推送到Harbor
需要推送的目标服务器设置`daemon.json`
`/etc/docker/daemon.json`
{
"registry-mirrors": [
"https://registry.hub.docker.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com"
],
"insecure-registries":["111.230.199.xxx:89"]
}
**重启docker**
`systemctl restart docker`
1. 先给要推送的镜像打一个tag
# 格式: docker tag 镜像ID HarborIP:端口/项目名/镜像名:版本号
docker tag 91b53e2624b4 111.230.199.xxx:89/test/mysql:v1.0.0

2. 登录到Harbor
docker login 111.230.199.xxx:89 -u 用户名 -p 密码

3. 推送
docker push 111.230.199.xxx:89/test/mysql:v1.0.0

4. 推送完毕之后就可以在Harbor中看到

### 将镜像拉取到本地
Harbor进入到要拉取镜像的页面中复制拉取命令

复制后的命令
docker pull 111.230.199.xxx:89/test/mysql@sha256:29ea1f451c3aad88df5a24288f76442286dc7fa6874d96a022e93a8a7efda880
需要将后面的hash码替换成需要拉取的版本号
docker pull 111.230.199.xxx:89/test/mysql:v1.0.0
## Jenkins集成部署
当我们需要在多台服务器中同时部署项目时,如果按之前的方式从目标服务器中进行构建Docker镜像,就会造成在每一台服务器中都需要进行构建镜像的操作,为了避免这种情况。
我们可以在Jenkins中先将Docker镜像构建好,并推送到Harbor中,这样我们在目标服务器只需执行命令,将镜像从Harbor中拉取下来,并运行即可。这样就省去了重复构建的操作。
### Jenkin制作自定义镜像并推送到Harbor
1. 创建一个自定义风格的任务
2. 设置Git源码地址
3. 调用顶层Maven目标进行打包

package -Dmaven.test.skip=true
4. 在项目的Dockerfile路径执行构建镜像命令

**问题:Jenkins无法直接执行的Docker命令(本案例Jenkins在WIndows环境中使用Docker进行部署)**

**解决:让Jenkins可以执行宿主机的Docker命令**
1. 修改Docker核心的sock文件所属组
路径:`/var/run/docker.sock`
chown root:root docker.sock
```
更改docker.sock的权限,使其对其他用户可读可写
chmod o+rw docker.sock
更改
docker-compose.yml
挂载信息,修改后:version: "3.1" services: jenkins: image: jenkins/jenkins:2.401.1-lts container_name: jenkins restart: always ports: - 8080:8080
volumes:
- ./data/:/var/jenkins_home/
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- /etc/docker/daemon.json:/etc/docker/daemon.json
environment:
- TZ=Asia/Shanghai
```
- 进入Jenkins容器内部使用docker命令进行测试
成功
- 再次进行构建发现已经执行了Docker构建命令的操作
文件不存在
在构建之前需要将jar包移动到docker文件夹中
mv ruoyi-admin/target/*.jar docker/ docker build -t ${JOB_NAME}:$tag docker/
- 构建成功,查看宿主机镜像
登录到Harbor,将镜像打一个tag并推送到Harbor
mv ruoyi-admin/target/*.jar docker/ docker build -t ${JOB_NAME}:$tag docker/ docker login -u admin -p Harbor1xxxx 111.230.199.xxx:89 docker tag ${JOB_NAME}:$tag 111.230.199.xxx:89/test/${JOB_NAME}:$tag docker push 111.230.199.xxx:89/test/${JOB_NAME}:$tag docker image prune -f
- 查看宿主机镜像和Harbor是否推送成功
到此推送流程就已经结束了
目标服务器准备脚本文件
脚本文件需要放置/usr/bin
路径下,确保在服务器的哪个地方都可以运行此脚本文件
harbor_addr=$1
harbor_repo=$2
project=$3
version=$4
container_port=$5
host_port=$6
imageName=$harbor_addr/$harbor_repo/$project:$version
echo $imageName
containerId=`docker ps -a | grep ${project} | awk '{print $1}'`
echo $containerId
if [ "$containerId" != "" ] ; then
docker stop $containerId
docker rm $containerId
fi
tag=`docker images | grep ${project} | awk '{print $2}'`
echo $tag
if [[ "$tag" =~ "$version" ]] ; then
docker rmi $imageName
fi
docker pull $imageName
docker run -d -p $host_port:$container_port --name $project $imageName
echo "SUCCESS"
完成基于Harbor的最终部署
- 添加2个字符串参数(容器内部端口、宿主机端口)
Send build artifacts over SSH
如果需要同时在多台服务器上部署,只需添加多个Send build artifacts over SSH即可。
前提是每台服务器都安装好了Docker
执行脚本文件
deploy.sh 111.230.199.xxx:89 test ${JOB_NAME} $tag $container_port $host_port
- 构建运行