CI/CD:持续集成/持续部署
1. 安装docker、docker-compose
# 安装Docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
yum makecache fast
yum -y install docker-ce
systemctl enable docker --now

安装Docker Compose
该页面提供了[GitHub - docker/compose: 定义并运行多容器应用程序]的详细信息与下载链接。
# 安装Docker Compose
wget https://github.com/docker/compose/releases/download/v2.26.0/docker-compose-linux-x86_64
mv docker-compose-linux-x86_64
chmod +x /usr/local/bin/docker-compose

2. GitLab部署
2.1. gitlab部署
GitLab的配置方案有很多种,在当前项目中采用Docker技术进行部署,请参考以下Docker Compose文件的位置。

version: '3.6'
services:
gitlab:
image: gitlab/gitlab-ce:latest
container_name: gitlab
restart: always
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://10.10.10.11:80'
gitlab_rails['gitlab_shell_ssh_prot'] = 22
ports:
- '80:80'
- '443:443'
- '2224:22'
volumes:
- './config:/etc/gitlab'
- './logs:/var/log/gitlab'
- './data:/var/opt/gitlab'
启动gitlab
docker-compose -f /home/gitlab/docker-compose.yml up -d
# 查看日志输出完毕即可通过浏览器访问
docker logs -f gitlab
# 查看密码
docker exec -it gitlab bash
cat /etc/gitlab/initial_root_password


2.2. 修改密码
修改密码:点击头像选择Preferences->Password->Save changes

2.3. 修改语言
设置语言:在软件偏好设置中选择Chinese -> 保存更改
2.4. 关闭注册功能
禁用注册功能:单击菜单栏中的【菜单
3. Harbor部署
3.1. harbor部署
官网:Harbor
GitHub - goharbor/harbor: a reliable open-source project on the cloud platform designed to store, verify the authenticity of, and analyze potential threats in the content.
# 下载Harbor安装程序
wget https://github.com/goharbor/harbor/releases/download/v2.10.2/harbor-offline-installer-v2.10.2.tgz
tar -zxvf harbor-offline-installer-v2.10.2.tgz
mv harbor /usr/local
# 修改配置文件
cd /usr/local/harbor/
cp harbor.yml.tmpl harbor.yml
vim harbor.yml

# 开始安装
./prepare
./install.sh
# Harbor安装完成之后通过docker-compose来管理
docker-compose ps

4. Jenkins部署
4.1. jenkins部署
Jenkins的dokcer-compose文件如下:

version: "3.6"
services:
jenkins:
image: jenkins/jenkins:2.414.3-lts
container_name: jenkins
restart: always
privileged: true
user: root
environment:
TZ: 'Asia/Shanghai'
ports:
- 8080:8080
- 50000:50000
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
启动jenkins
docker-compose -f /home/jenkins/docker-compose.yml up -d
# 查看密码
docker logs -f jenkins


4.2. 修改国内插件下载地址:
# 修改插件下载地址
cd /home/jenkins/data/updates
sed -i 's/https:\/\/updates.jenkins.io\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json #适用于新版本。
sudo sed -i 's/https:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
docker-compose -f /home/jenkins/docker-compose.yml restart
4.3. 插件安装
插件安装:点击Manage Jenkins->Plugins->Available plugins
# 安装如下插件:
Git Parameter
Publish Over SSH
SonarQube Scanner
Pipeline
Pipeline Stage View
Chinese
4.4. 配置全局环境JDK和Maven
JDK获取途径:Java Archive Downloads - Java SE 8u211 and later
Maven获取位置:Maven – 欢迎访问 Apache Maven
将下载的安装包上传到服务器。
tar -zxvf jdk-8u381-linux-x64.tar.gz -C
tar -zxvf apache-maven-3.9.6-bin.tar.gz
mv jdk1.8.0_381/ /home/jenkins/data/jdk
mv apache-maven-3.9.6 /home/jenkins/data/maven
# 配置maven私服地址
cd /usr/local/maven
vim conf/settings.xml
# 在mirrors节点下面添加子节点
--------------------------------------
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

# 配置jdk8编译插件
<profile>
<id>jdk8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
<activeProfiles>
<activeProfile>jdk8</activeProfile>
<activeProfile>anotherAlwaysActiveProfile</activeProfile>
</activeProfiles>

在配置完成后访问jenkinsWEB界面并依次点击Manage Jenkins->Tools->JDK installations和Maven installations,在这两个位置分别添加JDK安装目录和Maven安装目录。


4.5. Jenkins容器内部使用docker
配置宿主机器将var/run/docker.sock文件绑定到jenkins容器,并授予其执行权限后进行重新启动
chown root:root /var/run/docker.sock
chmod o+rw /var/run/docker.sock
docker-compose -f /home/jenkins/docker-compose.yml up -d

5. SonarQube部署
官方网站:下载 | 子弹头代码库 | 子系统
version: "3.6"
services:
sonarqube:
image: sonarqube:lts-community
depends_on:
- db
ports:
- "9000:9000"
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
networks:
- sonarqube_net
db:
image: postgres:12
ports:
- "5432:5432"
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
volumes:
- postgresql:/var/lib/postgresql
- postgresql_data:/var/lib/postgresql/data
networks:
- sonarqube_net
networks:
sonarqube_net:
driver: bridge
volumes:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
postgresql:
postgresql_data:
5.1. 插件安装:
Administration->Marketplace搜索框输入Chinese->点击install
5.2. sonar-scaner安装
获取该资源的完整路径为:https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.1.2450-linux.zip]
unzip sonar-scanner-cli-4.6.1.2450-linux.zip
mv sonar-scanner-4.6.1.2450-linux/ /home/jenkins/data/sonar-scanner
vim /home/jenkins/data/sonar-scanner/conf/sonar-scanner.properties

报错:
ERROR: [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch.
bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
# 修改虚拟内存大小
vim /etc/sysctl.conf
# 在文件末尾添加
vm.max_map_count=262144
# 保存并退出后,执行
sysctl -p
默认的账号和密码都是admin
5.3. SonarQube与Jenkins整合
单击位于Jenkins管理器中的"System"模块,在其下找到并选择"SonarQubes"服务器列表中的新增选项卡;然后依次完成以下操作:单击该位置以打开编辑器窗口;在编辑器中输入所需配置参数;最后保存设置并完成配置
说明

Launch Jenkins Management -> Navigate to Tools -> Proceed to Manage SonarQube Scanners -> Deploy SonarQube Scanners

6. 创建自由风格的任务
流程:获取代码-->使用Maven进行打包-->通过SonarQube执行代码质量检测-->构建镜像并上传至Harbor平台-->部署到生产环境
点击New Item->选择Freestyle project

6.1. 拉取代码
为项目添加参数化设置:选择项目参数化设置→单击"添加参数"按钮→选择→GitParameter

设置 Git 配置:在源代码管理位置 -> 单击 Git 选项 -> 输入 Git 的完整 URL 地址及账号密码。

通过指定tag获取代码:在Build Steps窗口中->单击Add build step按钮->勾选'Execute shell'选项并置于顶端位置->输入$tag处的git checkout命令

测试:


在jenkins目录下可以看到拉取的代码:

6.2. Maven打包
在Build Steps中选择Add Build Step, 然后勾选启动Top级Maven目标, 接着输入打包命令'clean package -DskipTests'。

再次测试:

可以看到已经打包成功

6.3. SonarQube代码检测
在打包完成后利用SonarQube进行代码扫描:在Build Steps中选择→启动SonarQube扫描程序。

sonar.projectname=${JOB_NAME}
sonar.projectKey=${JOB_NAME}
sonar.source=./
sonar.java.binaries=./target/
再一次构建系统后,可以看到日志信息显示为SUCCESS状态;进入SonarQube平台后可查看检测报告。

6.4. 制作镜像推送到Harbor
为镜像生成文件并在Harbor存储库中部署:在BuildSteps中添加执行脚本选项

cp target/*.jar docker/
docker build -t ${JOB_NAME}:$tag docker/
docker login -uadmin -p 123456Aa 192.168.32.146:1080
docker tag ${JOB_NAME}:$tag 192.168.32.146:1080/library/${JOB_NAME}:$tag
docker push 192.168.32.146:1080/library/${JOB_NAME}:$tag
若docker login -uadmin -p 123456Aa 192.168.32.146:1080报如下错误
# WARNING! Using --password via the CLI is insecure. Use --password-stdin.
# Error response from daemon: Get "https://192.168.32.146:1080/v2/": http: server gave HTTP response to HTTPS client
在/etc/docker/daemon.json文件中加入一行
"insecure-registries": ["192.168.32.146:1080"], # Harbor地址
再次Build,等待日志输出SUCCESS后查看部署机器和Harbor仓库:


6.5. 部署
在部署的机器上编写发布脚本:
Harbor_add=$1
Harbor_repo=$2
project=$3
version=$4
ImageName=$Harbor_add/$Harbor_repo/$project:$version
ContainerId=`docker ps -a | grep ${project} | awk '{print $1}'`
if [ "$ContainerId" != "" ]; then
docker stop $ContainerId && docker rm $ContainerId
fi
tag=`docker images | grep ${project} | awk '{print $2}'`
if [[ "$tag" =~ "$version" ]]; then
docker rmi -f $ImageName
fi
docker login -uadmin -p Harbor12345 $Harbor_add
docker pull $ImageName
docker run -d -p 8084:8080 --name $project $ImageName
在Jenkins上添加部署机:

部署步骤:位于Post-build Actions选项卡中->单击‘添加后构建动作’按钮->选择通过SSH传输构建 artifact

deploy.sh 192.168.32.146:1080 library ${JOB_NAME} $tag
docker image prune -f
最后测试:


7. Pipeline任务

创建Jenkinsfile文件,并在代码中增加一个Jenkinsfile文件,按照先前的流程依次生成流水线脚本。
7.1. 生成拉取代码脚本
单击任务pipeline_test链接并进入Configure菜单→进入Pipeline Syntax子菜单→在Sample Step选项卡中选择Check Out→填入Git信息后点击Generate Pipeline Script

7.2. 生成Maven构建项目脚本
在Sample步骤中选择配置Maven命令中的ShellScript字段并将其输入到Maven命令窗口中后点击生成管道脚本以完成配置。
/var/jenkins_home/maven/bin/mvn clean package -DskipTests

7.3. 生成SonarQube检测代码质量脚本
同上:
/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.source=./ -Dsonar.java.binaries=./target/ -Dsonar.login=da3b131bd550db98f33e5d8359d2e03be1ea1a8f

7.4. 生成制作镜像脚本
cp target/*.jar docker/
docker build -t ${JOB_NAME}:$tag docker/

7.5. 推送镜像到Harbor
docker login -uadmin -p 123456Aa 192.168.32.146:1080
docker tag ${JOB_NAME}:$tag 192.168.32.146:1080/library/${JOB_NAME}:$tag
docker push 192.168.32.146:1080/library/${JOB_NAME}:$tag

7.6. 生成部署脚本
在Sample Step中选择'SSH Publisher':通过SSH发送构建 artifact填入部署命令后点击生成管道脚本
deploy.sh $HarborAddress $Repo $JOB_NAME $tag

7.7. Jenkinsfile文件

pipeline {
agent any
environment{
Harbor_user = 'admin'
Harbor_passwd = '123456Aa'
HarborAddress = '192.168.32.146:1080'
Repo = 'library'
}
stages {
stage('拉取git仓库代码') {
steps {
checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[credentialsId: 'cb59a2fa-6308-4d49-9a16-3b049aecd2c1', url: 'http://192.168.32.146:1180/root/freestyle_test.git']])
}
}
stage('Maven构建项目') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
stage('SonarQube检测代码质量') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.source=./ -Dsonar.java.binaries=./target/ -Dsonar.login=da3b131bd550db98f33e5d8359d2e03be1ea1a8f'
}
}
stage('制作镜像') {
steps {
sh '''cp target/*.jar docker/
docker build -t ${JOB_NAME}:$tag docker/'''
}
}
stage('推送镜像到Harbor') {
steps {
sh '''docker login -u${Harbor_user} -p ${Harbor_passwd} ${HarborAddress}
docker tag ${JOB_NAME}:$tag ${HarborAddress}/${Repo}/${JOB_NAME}:$tag
docker push ${HarborAddress}/${Repo}/${JOB_NAME}:$tag'''
}
}
stage('部署') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test_host', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh $HarborAddress $Repo $JOB_NAME $tag ", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
部署脚本因调用了Jenkinsfile变量以及全局变量而存在配置问题,在原有配置中这些变量均被标记为单引号,请将这些涉及的变量处的单引号替换为双引号以确保配置正确
7.8. 准备执行任务
在Pipeline配置中设置将Git信息填入SCM系统完成保存操作后启动任务流程


7.9. 部署成功后通知到企业微信机器人
安装名为Qy Wechat Notification的插件;这个插件能够利用企业微信群机器人发送构建信息;进入Jenkins的管理界面→系统模块→找到企业微信通知配置设置;输入相关的信息。
并在Jenkinsfile中加入如下内容
post{
success{
qyWechatNotification failNotify: true, mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=自己的机器人KEY', moreInfo:'部署成功!'
}
failure{
qyWechatNotification failNotify: true, mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=自己的机器人KEY', moreInfo:'部署失败!'
}
}
# mentionedId: '需要通知UserID', mentionedMobile: '需要通知的通知手机号码', 可以为空
效果

最终完整Jenkinsfile
pipeline {
agent any
environment{
Harbor_user = 'admin'
Harbor_passwd = '123456Aa'
HarborAddress = '192.168.32.146:1080'
Repo = 'library'
}
stages {
stage('拉取git仓库代码') {
steps {
checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[credentialsId: 'cb59a2fa-6308-4d49-9a16-3b049aecd2c1', url: 'http://192.168.32.146:1180/root/freestyle_test.git']])
}
}
stage('Maven构建项目') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
stage('SonarQube检测代码质量') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.source=./ -Dsonar.java.binaries=./target/ -Dsonar.login=da3b131bd550db98f33e5d8359d2e03be1ea1a8f'
}
}
stage('制作镜像') {
steps {
sh '''cp target/*.jar docker/
docker build -t ${JOB_NAME}:$tag docker/'''
}
}
stage('推送镜像到Harbor') {
steps {
sh '''docker login -u${Harbor_user} -p ${Harbor_passwd} ${HarborAddress}
docker tag ${JOB_NAME}:$tag ${HarborAddress}/${Repo}/${JOB_NAME}:$tag
docker push ${HarborAddress}/${Repo}/${JOB_NAME}:$tag'''
}
}
stage('部署') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'test_host', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "deploy.sh $HarborAddress $Repo $JOB_NAME $tag ", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
post{
success{
qyWechatNotification failNotify: true, mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=自己的机器人KEY', moreInfo:'部署成功!'
}
failure{
qyWechatNotification failNotify: true, mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=自己的机器人KEY', moreInfo:'部署失败!'
}
}
}
8. 部署到K8S
在Jenkins环境中配置Kubernetes机器,在Post-build Actions模块中执行Add post-build action操作,在此界面中选择Send build artifacts over SSH选项,并将工作目录设置为/usr/local/pipeline

在Gitlab仓库中新增pipeline_test.yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
labels:
app: pipelinetest
name: pipelinetest
spec:
replicas: 2
selector:
matchLabels:
app: pipelinetest
template:
metadata:
labels:
app: pipelinetest
spec:
containers:
- name: pipelinetest
image: 192.168.32.146:1080/library/pipeline_test:v2.0.0
imagePullPolicy: Always
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
namespace: test
labels:
app: pipelinetest
name: pipelinetest
spec:
selector:
app: pipelinetest
ports:
- port: 8084
protocol: TCP
targetPort: 8080
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: pipelinetest
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: pipeline.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: pipelinetest
port:
number: 8084
优化Jenkinsfile脚本,并将其配置文件pipeline_test.yaml传输至K8Smaster节点,则该文件会被传输至/usr/local/pipeline目录下。

pipeline {
agent any
environment{
Harbor_user = 'admin'
Harbor_passwd = '123456Aa'
HarborAddress = '192.168.32.146:1080'
Repo = 'library'
}
stages {
stage('拉取git仓库代码') {
steps {
checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[credentialsId: 'cb59a2fa-6308-4d49-9a16-3b049aecd2c1', url: 'http://192.168.32.146:1180/root/freestyle_test.git']])
}
}
stage('Maven构建项目') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
stage('SonarQube检测代码质量') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.source=./ -Dsonar.java.binaries=./target/ -Dsonar.login=da3b131bd550db98f33e5d8359d2e03be1ea1a8f'
}
}
stage('制作镜像') {
steps {
sh '''cp target/*.jar docker/
docker build -t ${JOB_NAME}:$tag docker/'''
}
}
stage('推送镜像到Harbor') {
steps {
sh '''docker login -u${Harbor_user} -p ${Harbor_passwd} ${HarborAddress}
docker tag ${JOB_NAME}:$tag ${HarborAddress}/${Repo}/${JOB_NAME}:$tag
docker push ${HarborAddress}/${Repo}/${JOB_NAME}:$tag'''
}
}
stage('将yaml文件传到K8Smaster') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline_test.yaml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
post{
success{
qyWechatNotification failNotify: true, mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=自己的机器人key', moreInfo:'部署成功!'
}
failure{
qyWechatNotification failNotify: true, mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=自己的机器人key', moreInfo:'部署失败!'
}
}
}
在Gitlab新打一个标签,重新构建检查pipeline_test.yaml文件是否成功


Jenkins免密登录K8Smaster
# 进入Jenkins容器内
docker exec -it jenkins bash
# SSH免密登录
ssh-keygen
ssh-copy-id root@192.168.33.209
执行以下部署命令:使用SSH连接到root@192.168.33.209,并利用kubectl apply指令将文件/usr/local/pipeline/pipeline_test.yaml配置文件整合到Jenkinsfile脚本中。

完整Jenkinsfile
pipeline {
agent any
environment{
Harbor_user = 'admin'
Harbor_passwd = '123456Aa'
HarborAddress = '192.168.32.146:1080'
Repo = 'library'
}
stages {
stage('拉取git仓库代码') {
steps {
checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[credentialsId: 'cb59a2fa-6308-4d49-9a16-3b049aecd2c1', url: 'http://192.168.32.146:1180/root/freestyle_test.git']])
}
}
stage('Maven构建项目') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
stage('SonarQube检测代码质量') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.source=./ -Dsonar.java.binaries=./target/ -Dsonar.login=da3b131bd550db98f33e5d8359d2e03be1ea1a8f'
}
}
stage('制作镜像') {
steps {
sh '''cp target/*.jar docker/
docker build -t ${JOB_NAME}:$tag docker/'''
}
}
stage('推送镜像到Harbor') {
steps {
sh '''docker login -u${Harbor_user} -p ${Harbor_passwd} ${HarborAddress}
docker tag ${JOB_NAME}:$tag ${HarborAddress}/${Repo}/${JOB_NAME}:$tag
docker push ${HarborAddress}/${Repo}/${JOB_NAME}:$tag'''
}
}
stage('将yaml文件传到K8Smaster') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline_test.yaml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('部署') {
steps {
sh 'ssh root@192.168.33.209 kubectl apply -f /usr/local/pipeline/pipeline_test.yaml'
}
}
}
post{
success{
qyWechatNotification failNotify: true, mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=自己的机器人key', moreInfo:'部署成功!'
}
failure{
qyWechatNotification failNotify: true, mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=自己的机器人key', moreInfo:'部署失败!'
}
}
}


完成!
9. 自动化CI
当GitLab检测到源代码发生变更时,会自动启动Jenkins进行构建操作.为了实现这一功能,需要先安装对应的GitLab插件.随后,请依次执行以下操作:首先打开Jenkins界面;然后在导航栏中选择[项目名称]选项卡;最后点击"Configure"按钮以完成配置.

在Jenkins全局配置中去掉gitlab认证

进入GitLab项目设置,在→Webhooks选项中配置该Webhook以触发构建每当提交到GitLab时,并将此URL设为对应的GitLab webhook URL

# 若gitlab和jenkins在同一主机上会报错:Url is blocked: Requests to the local network are not allowed
# 进入gitlab点击Menu --> Admin --> Settings --> Network -->Outbound requests勾选上Allow requests to the local network from web hooks and services

最后不再根据tag标签进行代码提取,并设置Jenkinsfile文件中pull request tag获取方式为*/master。同时更新Docker镜像版本至latest,并将pipeline_test.yaml文件中的镜像版本更新为latest。
因为这个流程只有当yaml文件发生更改时才会启动,在部署完成后应执行以下操作:首先运行kkubectl rollout restart deployment pipelinetest并指定namespace为test;然后添加ssh root@192.168.33.209以确保远程重启能够生效。
pipeline {
agent any
environment{
Harbor_user = 'admin'
Harbor_passwd = '123456Aa'
HarborAddress = '192.168.32.146:1080'
Repo = 'library'
}
stages {
stage('拉取git仓库代码') {
steps {
checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'cb59a2fa-6308-4d49-9a16-3b049aecd2c1', url: 'http://192.168.32.146:1180/root/freestyle_test.git']])
}
}
stage('Maven构建项目') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
stage('SonarQube检测代码质量') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.source=./ -Dsonar.java.binaries=./target/ -Dsonar.login=da3b131bd550db98f33e5d8359d2e03be1ea1a8f'
}
}
stage('制作镜像') {
steps {
sh '''cp target/*.jar docker/
docker build -t ${JOB_NAME}:latest docker/'''
}
}
stage('推送镜像到Harbor') {
steps {
sh '''docker login -u${Harbor_user} -p ${Harbor_passwd} ${HarborAddress}
docker tag ${JOB_NAME}:latest ${HarborAddress}/${Repo}/${JOB_NAME}:latest
docker push ${HarborAddress}/${Repo}/${JOB_NAME}:latest'''
}
}
stage('将yaml文件传到K8Smaster') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline_test.yaml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('部署') {
steps {
sh 'ssh root@192.168.33.209 kubectl apply -f /usr/local/pipeline/pipeline_test.yaml'
sh 'ssh root@192.168.33.209 kubectl rollout restart deployment pipelinetest -n test'
}
}
}
post{
success{
qyWechatNotification failNotify: true, mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=自己的机器人key', moreInfo:'部署成功!'
}
failure{
qyWechatNotification failNotify: true, mentionedId: '', mentionedMobile: '', webhookUrl: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=自己的机器人key', moreInfo:'部署失败!'
}
}
}
