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
![image-20230621174121654](https://qny.chengxuyi.top//typora_img/image-20230621174121654.png)
这里看到启动失败了,查看容器日志发现是权限问题,无法进行write
![image-20230621174345882](https://qny.chengxuyi.top//typora_img/image-20230621174345882.png)
对data文件夹赋予777权限并启动再次容器
chmod -R 777 data
docker start jenkins
3. 浏览器访问8080端口进入首页,密码可在容器日志中或者文件中查看
![image-20230621175229386](https://qny.chengxuyi.top//typora_img/image-20230621175229386.png)
4. 安装插件,随便点击一个并等待插件安装完成
> 这里插件大概率会安装失败,不要紧,等下我们进去安装我们需要的插件,不用在这个地方纠结很久
![image-20230621175504592](https://qny.chengxuyi.top//typora_img/image-20230621175504592.png)
5. 创建用户,这里随便输,记住账号密码即可
![image-20230621175903669](https://qny.chengxuyi.top//typora_img/image-20230621175903669.png)
6. 实例配置使用默认值,点击保存并完成
![image-20230621175954040](https://qny.chengxuyi.top//typora_img/image-20230621175954040.png)
## 安装插件
Jenkins的大部分功能都来自于它的插件,插件越多,功能越强大
进入插件页面
![image-20230621180351804](https://qny.chengxuyi.top//typora_img/image-20230621180351804.png)
我们需要安装`Git Parameter`和`Publish Over SSH`2个插件
![image-20230621180523507](https://qny.chengxuyi.top//typora_img/image-20230621180523507.png)
安装完并重启
![image-20230621180544156](https://qny.chengxuyi.top//typora_img/image-20230621180544156.png)
`Git Parameter`插件用于在连接Git仓库时添加额外的参数
`Publish Over SSH`插件用于连接远程服务器
## Jenkins配置Maven、JDK、SSH
进入全局配置页面
![image-20230625201915125](https://qny.chengxuyi.top//typora_img/image-20230625201915125.png)
### Maven
填写Name和Home路径
路径在填写错误时会有提示
![image-20230625202056876](https://qny.chengxuyi.top//typora_img/image-20230625202056876.png)
### JDK
![image-20230625202237465](https://qny.chengxuyi.top//typora_img/image-20230625202237465.png)
### SSH
![image-20230625202325738](https://qny.chengxuyi.top//typora_img/image-20230625202325738.png)
滑到最底部找到 `Publish over SSH`并配置需要连接的服务器信息
![image-20230625202855508](https://qny.chengxuyi.top//typora_img/image-20230625202855508.png)
使用密码进行验证
![image-20230625202912132](https://qny.chengxuyi.top//typora_img/image-20230625202912132.png)
## CI
CI(持续集成)是指在团队开发过程中,频繁地将代码集成到共享代码仓库中,并自动执行构建、测试和代码质量检查等过程。其目标是确保团队成员的代码能够及时合并,并尽早发现和解决集成问题。CI的关键是自动化构建和测试,以便尽早发现代码中的错误和问题。通过持续集成,团队可以更快地交付软件,减少集成问题的风险,并提高团队的协作效率。
> 本次案例使用项目为RuoYi前后端分离多模块项目:https://gitee.com/y_project/RuoYi-Vue
>
> 采用Docker容器的方式进行部署
1. 创建一个自定义风格的项目
![image-20230625201202830](https://qny.chengxuyi.top//typora_img/image-20230625201202830.png)
2. 配置项目源码信息
![image-20230625201700751](https://qny.chengxuyi.top//typora_img/image-20230625201700751.png)
测试代码是否拉取成功
![image-20230625203259138](https://qny.chengxuyi.top//typora_img/image-20230625203259138.png)
查看控制台日志
![image-20230625203325532](https://qny.chengxuyi.top//typora_img/image-20230625203325532.png)
拉取代码成功
![image-20230625203346572](https://qny.chengxuyi.top//typora_img/image-20230625203346572.png)
拉取成功之后会在Jenkins的工作空间中看到项目文件夹
使用docker部署时在挂载的data/workspace文件夹中查看。
使用windows安装版本在图中的目录中查看
![image-20230625203550793](https://qny.chengxuyi.top//typora_img/image-20230625203550793.png)
3. 添加项目构建步骤:调用顶层Maven目标
![image-20230625203714474](https://qny.chengxuyi.top//typora_img/image-20230625203714474.png)
![image-20230625203927742](https://qny.chengxuyi.top//typora_img/image-20230625203927742.png)
再次进行构建并查看控制台日志
![image-20230625204030927](https://qny.chengxuyi.top//typora_img/image-20230625204030927.png)
项目构建成功之后会在对应的工作空间的项目中生成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发送构建工件
![image-20230625205524397](https://qny.chengxuyi.top//typora_img/image-20230625205524397.png)
![image-20230626093529864](https://qny.chengxuyi.top//typora_img/image-20230626093529864.png)
6. 保存并执行任务
- 超时
![image-20230626094020061](https://qny.chengxuyi.top//typora_img/image-20230626094020061.png)
<img src="https://qny.chengxuyi.top//typora_img/image-20230626094112712.png" alt="image-20230626094112712" />![image-20230626094227457](https://qny.chengxuyi.top//typora_img/image-20230626094227457.png)
修改超时时间保存后再次执行
![image-20230626094424578](https://qny.chengxuyi.top//typora_img/image-20230626094424578.png)
在目标服务器中使用`docker ps`查看已经部署成功
> **至此,CI操作就已经完成了**
## CD
CD(持续交付/持续部署)是CI的延伸,指的是在通过持续集成构建、测试和验证代码后,自动将代码交付给生产环境或可用于生产部署的环境。持续交付的目标是使软件的交付过程自动化、可靠且可重复,以减少人工干预和减少交付的时间间隔。持续交付的流程通常包括自动化构建、自动化测试、自动化部署和自动化验证等步骤。持续部署则更进一步,指的是将经过验证的代码自动部署到生产环境中,以实现全自动的软件交付。
1. 在Gitee中配置标签
![image-20230626095308436](https://qny.chengxuyi.top//typora_img/image-20230626095308436.png)
2. 在任务配置中选择参数化,并选择之前安装的`Git Parameter`
![image-20230626095442344](https://qny.chengxuyi.top//typora_img/image-20230626095442344.png)
![image-20230628164540903](https://qny.chengxuyi.top//typora_img/image-20230628164540903.png)
3. 新增一行构建之前的命令,切换到指定的tag分支。$tag取上面Git Parameter名称的值
![image-20230628170215381](https://qny.chengxuyi.top//typora_img/image-20230628170215381.png)
> windows环境中的Jenkins无法调用shell脚本问题
在系统配置里面中配置shell为Git的sh.exe执行文件路径
![image-20230628170343041](https://qny.chengxuyi.top//typora_img/image-20230628170343041.png)
4. 在配置完参数后,构建按钮变成了Build with Parameters
![image-20230626095851626](https://qny.chengxuyi.top//typora_img/image-20230626095851626-16877447685341.png)
5. 选择对应的tag并开始构建
![image-20230626095956108](https://qny.chengxuyi.top//typora_img/image-20230626095956108.png)
控制台查看执行了切换分支的命令
![image-20230628170551950](https://qny.chengxuyi.top//typora_img/image-20230628170551950.png)
## 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
![image-20230625193319595](https://qny.chengxuyi.top//typora_img/image-20230625193319595.png)
在SonarQube提供的可视化界面查看检查结果
![image-20230625193442430](https://qny.chengxuyi.top//typora_img/image-20230625193442430.png)
## 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/
下载自己对应的操作系统文件
![image-20230625165342274](https://qny.chengxuyi.top//typora_img/image-20230625165342274.png)
### 命令行方式检查代码
#### 打开SonarScanner配置文件:sonar-scanner.properties
![image-20230625165522702](https://qny.chengxuyi.top//typora_img/image-20230625165522702.png)
更改后的文件内容为
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插件
![image-20230701093415322](https://qny.chengxuyi.top//typora_img/image-20230701093415322.png)
2. 生成密钥:打开SonarQube服务端
![image-20230701094153984](https://qny.chengxuyi.top//typora_img/image-20230701094153984.png)
复制令牌
![image-20230701094229335](https://qny.chengxuyi.top//typora_img/image-20230701094229335.png)
3. 配置SonarQube服务端
类型选择Secret text,输入复制的令牌
![image-20230701094304636](https://qny.chengxuyi.top//typora_img/image-20230701094304636.png)
![image-20230701093949642](https://qny.chengxuyi.top//typora_img/image-20230701093949642.png)
4. 构建项目时添加SonarQubeScanner步骤
![image-20230701094621711](https://qny.chengxuyi.top//typora_img/image-20230701094621711.png)
![image-20230701094814580](https://qny.chengxuyi.top//typora_img/image-20230701094814580.png)
5. 重新构建
> 在构建成功之后执行了SonarScanner命令进行检查
![image-20230701095008286](https://qny.chengxuyi.top//typora_img/image-20230701095008286.png)
SonarQube服务端也新增了一个检查
![image-20230701095126527](https://qny.chengxuyi.top//typora_img/image-20230701095126527.png)
## 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):选择离线或者在线版本
![image-20230704194905334](https://qny.chengxuyi.top//typora_img/image-20230704194905334.png)
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`内容
![image-20230704195702869](https://qny.chengxuyi.top//typora_img/image-20230704195702869.png)
4. 执行`install.sh`。harbor部署方式是使用docker容器部署,所有install之前需要先安装好Docker和Docker compose
5. 部署好查看Docker容器运行情况
![image-20230704195931227](https://qny.chengxuyi.top//typora_img/image-20230704195931227.png)
6. 浏览器访问89端口
![image-20230704200004857](https://qny.chengxuyi.top//typora_img/image-20230704200004857.png)
### Harbor基本操作
#### 新建项目
![image-20230714163418205](https://qny.chengxuyi.top//typora_img/image-20230714163418205.png)
![image-20230714163428904](https://qny.chengxuyi.top//typora_img/image-20230714163428904.png)
输入项目名称、访问级别、项目配合限制:-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
![image-20230714164321072](https://qny.chengxuyi.top//typora_img/image-20230714164321072.png)
2. 登录到Harbor
docker login 111.230.199.xxx:89 -u 用户名 -p 密码
![image-20230714164353104](https://qny.chengxuyi.top//typora_img/image-20230714164353104.png)
3. 推送
docker push 111.230.199.xxx:89/test/mysql:v1.0.0
![image-20230714164520134](https://qny.chengxuyi.top//typora_img/image-20230714164520134.png)
4. 推送完毕之后就可以在Harbor中看到
![image-20230714164605854](https://qny.chengxuyi.top//typora_img/image-20230714164605854.png)
### 将镜像拉取到本地
Harbor进入到要拉取镜像的页面中复制拉取命令
![image-20230714164642412](https://qny.chengxuyi.top//typora_img/image-20230714164642412.png)
复制后的命令
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目标进行打包
![image-20230716210054716](https://qny.chengxuyi.top//typora_img/image-20230716210054716.png)
package -Dmaven.test.skip=true
4. 在项目的Dockerfile路径执行构建镜像命令
![image-20230717150433979](https://qny.chengxuyi.top//typora_img/image-20230717150433979.png)
**问题:Jenkins无法直接执行的Docker命令(本案例Jenkins在WIndows环境中使用Docker进行部署)**
![image-20230716205949661](https://qny.chengxuyi.top//typora_img/image-20230716205949661.png)
**解决:让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
- 构建运行