当前位置: 首页 > news >正文

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: Define and run multi-container applications with Docker

# 安装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来部署GitLab,docker-compose.yml文件位置如下:

version: '3.6'
services:gitlab:image: gitlab/gitlab-ce:latestcontainer_name: gitlabrestart: alwaysenvironment:GITLAB_OMNIBUS_CONFIG: |external_url 'http://10.10.10.11:80'gitlab_rails['gitlab_shell_ssh_prot'] = 22ports:- '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. 修改语言

修改语言:点击头像选择Preferences->Localization->Language选项中选择Chinese->Save changes

2.4. 关闭注册功能

关闭注册功能:点击Menu->Admin->Settings->找到Sign-up restrictions点击Expand->取消勾选Sign-up enabled->Save changes

3. Harbor部署

3.1. harbor部署

官网:Harbor

下载地址:GitHub - goharbor/harbor: An open source trusted cloud native registry project that stores, signs, and scans 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-ltscontainer_name: jenkinsrestart: alwaysprivileged: trueuser: rootenvironment:TZ: 'Asia/Shanghai'ports:- 8080:8080- 50000:50000volumes:- ./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 – Welcome to 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容器并赋予权限,重启jinkins容器

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部署

官网:Download | SonarQube | Sonar

version: "3.6"
services:sonarqube:image: sonarqube:lts-communitydepends_on:- dbports:- "9000:9000"environment:SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonarSONAR_JDBC_USERNAME: sonarSONAR_JDBC_PASSWORD: sonarvolumes:- sonarqube_data:/opt/sonarqube/data- sonarqube_extensions:/opt/sonarqube/extensions- sonarqube_logs:/opt/sonarqube/logsnetworks:- sonarqube_netdb:image: postgres:12ports:- "5432:5432"environment:POSTGRES_USER: sonarPOSTGRES_PASSWORD: sonarvolumes:- postgresql:/var/lib/postgresql- postgresql_data:/var/lib/postgresql/datanetworks:- 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整合

点击Manage Jenkins->System->SonarQube servers->Add SonarQube server加入SonarQube信息

点击Manage Jenkins->Tools->SonarQube Scanner installations->Add SonarQube Scanner

6. 创建自由风格的任务

流程:拉取代码-->maven打包-->SonarQube代码检测-->制作镜像推送到Harbor-->部署

点击New Item->选择Freestyle project

6.1. 拉取代码

添加tag标签:勾选This project is parameterized->点击Add Parameter->勾选->Git Parameter

配置Git:在Source Code Management位置->点击Git->输入Git的URL和账号密码

根据tag拉取代码:在Build Steps下->点击Add build step->勾选Execute shell并拉到顶部位置->输入git checkout $tag

测试:

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

6.2. Maven打包

配置构建参数:在Build Steps下->点击Add build step->勾选Invoke top-level Maven targets->输入打包命令clean package -DskipTests

再次测试:

可以看到已经打包成功

6.3. SonarQube代码检测

打包后使用SonarQube扫码代码:找到Build Steps点击Add Build Steps->Execute SonarQube Scanner

sonar.projectname=${JOB_NAME}
sonar.projectKey=${JOB_NAME}
sonar.source=./
sonar.java.binaries=./target/

再次Build,能够看到输出日志结果是SUCCESS,登录SonarQube能看到检测结果

6.4. 制作镜像推送到Harbor

制作镜像并推送到Harbor:找到Build Steps点击Add Build Steps->勾选Execute shell输入shell命令

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=$4ImageName=$Harbor_add/$Harbor_repo/$project:$versionContainerId=`docker ps -a | grep ${project} | awk '{print $1}'`if [ "$ContainerId" != "" ]; thendocker stop $ContainerId && docker rm $ContainerId
fitag=`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 $ImageNamedocker run -d -p 8084:8080 --name $project $ImageName

在Jenkins上添加部署机:

部署:在Post-build Actions下->点击Add post-build action->选择Send build artifacts over SSH

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中选择checkou:Check out from version control填入Git信息后点击Generate Pipeline Script

7.2. 生成Maven构建项目脚本

在Sample Step中选择sh:Shell Script填入Maven命令后点击Generate Pipeline Script

/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中选择sshPublisher:Send build artifacts over SSH填入部署命令后点击Generate Pipeline Script

deploy.sh $HarborAddress $Repo $JOB_NAME $tag 

7.7. Jenkinsfile文件

pipeline {agent anyenvironment{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}:$tagdocker 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下选择Pipeline script from SCM填入Git信息保存并启动任务

7.9. 部署成功后通知到企业微信机器人

安装Qy Wechat Notification插件,这个插件可以通过企业微信群机器人发送构建信息,然后来到Manage Jenkins-->System下找到企业微信通知配置,填入信息

并在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 anyenvironment{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}:$tagdocker 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下添加K8S机器,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: pipelinetestname: pipelinetest
spec:        replicas: 2      selector:matchLabels:app: pipelinetesttemplate:        metadata:        labels:app: pipelinetestspec:           containers:- name: pipelinetestimage: 192.168.32.146:1080/library/pipeline_test:v2.0.0imagePullPolicy: Alwaysports:- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:namespace: test   labels:app: pipelinetestname: 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.comhttp:paths:- path: /pathType: Prefixbackend:service:name: pipelinetestport:number: 8084

修改Jenkinsfile脚本,将pipeline_test.yaml传到K8Smaster节点,会传到/usr/local/pipeline下

pipeline {agent anyenvironment{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}:$tagdocker 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 -f /usr/local/pipeline/pipeline_test.yaml,加入到Jenkinsfile脚本中

完整Jenkinsfile

pipeline {agent anyenvironment{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}:$tagdocker 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 --> My Views --> [项目名称] --> Configure

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

回到gitlab在项目中点击Settings --> Webhooks在URL处粘贴上Build when a change is pushed to GitLab. 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文件中的代码拉取tag为*/master,docker镜像版本修改为latest,pipeline_test.yaml文件中的镜像版本改为latest

由于这个流程如果yaml文件没有变动就不会部署成功,需要在部署命令后增加ssh root@192.168.33.209 kubectl rollout restart deployment pipelinetest -n test

pipeline {agent anyenvironment{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}:latestdocker 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:'部署失败!'}}
}

相关文章:

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 sdownload.docker.commirrors.aliyun.com/docker-ce /…...

ComfyUI工作流网站

https://openart.ai/home https://comfyworkflows.com/ https://civitai.com/...

【机器学习】机器学习基础概念与初步探索

❀机器学习 &#x1f4d2;1. 引言&#x1f4d2;2. 机器学习概述&#x1f4d2;3. 机器学习基础概念&#x1f389;2.1 机器学习的分类&#x1f389;2.2 数据预处理&#x1f308;数据清洗与整合&#x1f308; 特征选择和特征工程&#x1f308;数据标准化与归一化 &#x1f4d2;4. …...

学英语材料:单口喜剧、讲故事、短剧喜剧以及广播剧和播客节目

学习英语节目 有名的单口喜剧、讲故事、短剧喜剧以及广播剧和播客节目&#xff1a; 单口喜剧&#xff08;Stand-up Comedy&#xff09; 描述&#xff1a;这是最接近相声的形式&#xff0c;表演者独自一人站在舞台上&#xff0c;用幽默的方式讲述个人经历、观察到的社会现象或…...

Docker Compose使用

Docker-Compose是什么 docker建议我们每一个容器中只运行一个服务,因为doker容器本身占用资源极少&#xff0c;所以最好是将每个服务单独分割开来&#xff0c;但是这样我们又面临了一个问题&#xff1a; 如果我需要同时部署好多个服务&#xff0c;难道要每个服务单独写Docker…...

如何优雅的卸载linux上的todesk

要优雅地卸载Linux上的ToDesk&#xff0c;您可以按照以下步骤操作&#xff1a; 打开终端。 输入以下命令来停止ToDesk服务&#xff08;如果它正在运行的话&#xff09;&#xff1a; sudo systemctl stop todesk 然后&#xff0c;使用包管理器卸载ToDesk。如果您使用的是apt&…...

【Vue】el-checkbox多选框实现单选效果,选中一个选项则自动取消其他勾选

&#x1f935; 作者&#xff1a;coderYYY &#x1f9d1; 个人简介&#xff1a;前端程序媛&#xff0c;目前主攻web前端&#xff0c;后端辅助&#xff0c;其他技术知识也会偶尔分享&#x1f340;欢迎和我一起交流&#xff01;&#x1f680;&#xff08;评论和私信一般会回&#…...

Linux中使用vi编辑器自动缩进4个字符

平常在Linux操作系统下书写shell脚本内容&#xff0c;或是把写好的shell内容直接复制到vi编辑器中&#xff0c;本来缩进好的字符&#xff0c;会自动变乱&#xff0c;这是因为Linux的vi编辑器默认是缩进8个字符造成&#xff0c;可以使用下面2个方法解决该问题的发生。 1、本用户…...

#笔记#笔记#其他

大鱼论文是一款非常靠谱、方便、值得推荐的论文写作工具。无论是在学术研究中还是在日常写作中&#xff0c;大鱼论文都能够帮助用户轻松完成论文的写作工作。 首先&#xff0c;大鱼论文提供了强大的查重降重功能&#xff0c;能够帮助用户快速定位论文中可能存在的抄袭问题&…...

gtask笔记

1、创建Task GTask *g_task_new (gpointer source_object, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer callback_data); source_object&#xff1a;GObject对象&#xff0c;拥有者 cancellable&#xff1a;可否取消 callback&#xff1a;task完成后…...

【Linux学习】深入探索进程等待与进程退出码和退出信号

文章目录 退出码return退出 进程的等待进程等待的方法 退出码 main函数的返回值&#xff1a;进程的退出码。 一般为0表示成功&#xff0c;非0表示失败。 每一个非0退出码都表示一个失败的原因&#xff1b; echo $&#xff1f;命令 作用&#xff1a;查看进程退出码。&#xf…...

Linux:线程

文章目录 前言1. 线程概念1.1 什么是线程1.2 线程比进程更加轻量化1.3 虚拟地址到物理地址的转化物理内存的管理页表 1.4 线程的优点1.5 线程的缺点1.6 线程异常1.7 线程用途 2. 进程 vs 线程3. 线程控制3.1 线程创建3.2 线程退出3.3 线程等待3.4 分离线程3.5 线程取消 4. 线程…...

卡到BUG了:删除重发白得积分(以前删除会扣减积分)

以前是&#xff1a;删除文章&#xff0c;积分减少&#xff0c;点赞积分减少&#xff0c;从回收站恢复文章&#xff0c;积分恢复&#xff0c;点赞数恢复但点赞积分不恢复。也就是删除重发总积分减少点赞的积分&#xff0c;有损失。 今天是&#xff1a;删除文章&#xff0c;积分不…...

轻松拿捏C语言——【字符函数】字符分类函数、字符转换函数

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; &#x1f339;如有问题&#xff0c;欢迎指正 感谢 目录&#x1f451; 一、字符分类函数&#x1f319; 二、字符转换函数…...

【Rust日报】ratatui版本更新

[new ver] ratatui v0.26.3 一个构建终端用户界面的库。新版本包括&#xff1a; 修复Unicode 截断 bug对颜色更好地序列化更快的渲染弃用assert_buffer_eq宏暴露错误类型常量函数和类型 官网: https://ratatui.rs/ 链接: https://ratatui.rs/highlights/v0263/ [new lib] ansi2…...

力扣每日一题 5/28

题目&#xff1a;2951-找出峰值 给你一个下标从 0 开始的数组 mountain 。你的任务是找出数组 mountain 中的所有 峰值。 以数组形式返回给定数组中 峰值 的下标&#xff0c;顺序不限 。 注意&#xff1a; 峰值 是指一个严格大于其相邻元素的元素。数组的第一个和最后一个元…...

async函数和await函数

一、async函数 async是一个加在函数前的修饰符&#xff0c;被async定义的函数会默认返回一个Promise对象resolve的值。 因此对async函数可以直接then&#xff0c;返回值就是then方法传入的函数。 // async基础语法 async function fun0(){console.log(1);return 1; } fun0()…...

Redis面试题深度解析

1、我看你做的项目中&#xff0c;都用到了redis&#xff0c;你在最近的项目中哪些场景使用了redis呢? 2、缓存穿透 布隆过滤器的误判现象 Redisson和Guava都对布隆过滤器进行了实现 3、缓存击穿 互斥锁&#xff0c;就是一个线程来修改&#xff0c;并占据了锁&#xff0c;另外其…...

Ubuntu 22.04 .NET8 程序 环境安装和运行

前言 我们需要将.NET8编写的console控制台程序&#xff0c;部署在Ubuntu服务器上运行。 安装.NET运行时 1.增加微软包安装源 wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages…...

MetaRTC-ffmpeg arm移植

touch cmake_arm.sh 添加 rm -rf build mkdir build cd build ARCHaarch64.cmake cmake -DCMAKE_BUILD_TYPERelease -DCMAKE_TOOLCHAIN_FILE../$ARCH .. maketouch cmake_arm.sh 添加 SET(CMAKE_SYSTEM_NAME Linux) SET(CMAKE_C_COMPILER /home/yqw/MetaRTC/BC/stbgcc-6.3-1…...

指针与函数参数传递详解 —— 值传递与地址传递的区别及应用

资料合集下载链接&#xff1a; ​​https://pan.quark.cn/s/472bbdfcd014​​ 在C语言中&#xff0c;函数参数的传递方式主要有两种&#xff1a;值传递和地址传递&#xff08;通过指针&#xff09;。理解两者的区别及应用对于正确操作数据和优化程序逻辑至关重要。本文将通过…...

Scrapy爬虫教程(新手)

1. Scrapy的核心组成 引擎&#xff08;engine&#xff09;&#xff1a;scrapy的核心&#xff0c;所有模块的衔接&#xff0c;数据流程梳理。 调度器&#xff08;scheduler&#xff09;&#xff1a;本质可以看成一个集合和队列&#xff0c;里面存放着一堆即将要发送的请求&#…...

elasticsearch基本操作笔记

1.通过kibana查看elasticsearch版本信息 a.左上角三道横->Management->Dev Tools b.GET / 执行 c.执行结果 { “name” : “xxxx”, “cluster_name” : “xxxxxxx”, “cluster_uuid” : “vl1UudAoQp-aHWAzyPoMyw”, “version” : { “number” : “7.15.1”, “build…...

CppCon 2015 学习:Intro to the C++ Object Model

这段代码展示了使用 make 工具来编译 C 程序的简单过程。 代码和步骤解析&#xff1a; C 代码&#xff08;intro.cpp&#xff09;&#xff1a;#include <iostream> int main() { std::cout<<"hello world\n"; } 这是一个简单的 C 程序&#xff0c;它包…...

SpringBoot2.3.1集成Knife4j接口文档

首先要查看项目中pom文件里面有没有swagger和knife4j的依赖&#xff0c;如果有的话删除&#xff0c;加入以下依赖 <!-- swagger --><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-spring-boot-starter</…...

H_Prj06_03 8088单板机串口读取8088ROM复位内存

1.8088CPU复位时&#xff0c;CSFFFFH,IP0000H,因此在ROM的逻辑地址FFFF&#xff1a;0000&#xff08;FFF0H&#xff09;处一般要防止一个长跳转指令LJMP&#xff08;机器码位EAH&#xff09; 2.写一个完整的8086汇编程序&#xff0c;通过查询方式检测串口接收符串‘r’&#x…...

智能对联网页小程序的仓颉之旅

#传统楹联遇上AI智能体&#xff1a;我的Cangjie Magic开发纪实 引言&#xff1a;一场跨越千年的数字对话 "云对雨&#xff0c;雪对风&#xff0c;晚照对晴空"。昨天晚上星空璀璨&#xff0c;当我用仓颉语言写下第一个智能对联网页小程序的Agent DSL代码时&#xff0…...

基于功能基团的3D分子生成扩散模型 - D3FG 评测

D3FG 是一个在口袋中基于功能团的3D分子生成扩散模型。与通常分子生成模型直接生成分子坐标和原子类型不同&#xff0c;D3FG 将分子分解为两类组成部分&#xff1a;官能团和连接体&#xff0c;然后使用扩散生成模型学习这些组成部分的类型和几何分布。 一、背景介绍 D3FG 来源…...

AI代码助手需求说明书架构

AI代码助手需求说明书架构 #mermaid-svg-6dtAzH7HjD5rehlu {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6dtAzH7HjD5rehlu .error-icon{fill:#552222;}#mermaid-svg-6dtAzH7HjD5rehlu .error-text{fill:#552222;s…...

最新Spring Security实战教程(十七)企业级安全方案设计 - 多因素认证(MFA)实现

&#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Micro麦可乐的博客 &#x1f425;《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程&#xff0c;入门到实战 &#x1f33a;《RabbitMQ》…...