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/...

【机器学习】机器学习基础概念与初步探索
❀机器学习 📒1. 引言📒2. 机器学习概述📒3. 机器学习基础概念🎉2.1 机器学习的分类🎉2.2 数据预处理🌈数据清洗与整合🌈 特征选择和特征工程🌈数据标准化与归一化 📒4. …...
学英语材料:单口喜剧、讲故事、短剧喜剧以及广播剧和播客节目
学习英语节目 有名的单口喜剧、讲故事、短剧喜剧以及广播剧和播客节目: 单口喜剧(Stand-up Comedy) 描述:这是最接近相声的形式,表演者独自一人站在舞台上,用幽默的方式讲述个人经历、观察到的社会现象或…...

Docker Compose使用
Docker-Compose是什么 docker建议我们每一个容器中只运行一个服务,因为doker容器本身占用资源极少,所以最好是将每个服务单独分割开来,但是这样我们又面临了一个问题: 如果我需要同时部署好多个服务,难道要每个服务单独写Docker…...
如何优雅的卸载linux上的todesk
要优雅地卸载Linux上的ToDesk,您可以按照以下步骤操作: 打开终端。 输入以下命令来停止ToDesk服务(如果它正在运行的话): sudo systemctl stop todesk 然后,使用包管理器卸载ToDesk。如果您使用的是apt&…...
【Vue】el-checkbox多选框实现单选效果,选中一个选项则自动取消其他勾选
🤵 作者:coderYYY 🧑 个人简介:前端程序媛,目前主攻web前端,后端辅助,其他技术知识也会偶尔分享🍀欢迎和我一起交流!🚀(评论和私信一般会回&#…...
Linux中使用vi编辑器自动缩进4个字符
平常在Linux操作系统下书写shell脚本内容,或是把写好的shell内容直接复制到vi编辑器中,本来缩进好的字符,会自动变乱,这是因为Linux的vi编辑器默认是缩进8个字符造成,可以使用下面2个方法解决该问题的发生。 1、本用户…...
#笔记#笔记#其他
大鱼论文是一款非常靠谱、方便、值得推荐的论文写作工具。无论是在学术研究中还是在日常写作中,大鱼论文都能够帮助用户轻松完成论文的写作工作。 首先,大鱼论文提供了强大的查重降重功能,能够帮助用户快速定位论文中可能存在的抄袭问题&…...
gtask笔记
1、创建Task GTask *g_task_new (gpointer source_object, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer callback_data); source_object:GObject对象,拥有者 cancellable:可否取消 callback:task完成后…...

【Linux学习】深入探索进程等待与进程退出码和退出信号
文章目录 退出码return退出 进程的等待进程等待的方法 退出码 main函数的返回值:进程的退出码。 一般为0表示成功,非0表示失败。 每一个非0退出码都表示一个失败的原因; echo $?命令 作用:查看进程退出码。…...

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了:删除重发白得积分(以前删除会扣减积分)
以前是:删除文章,积分减少,点赞积分减少,从回收站恢复文章,积分恢复,点赞数恢复但点赞积分不恢复。也就是删除重发总积分减少点赞的积分,有损失。 今天是:删除文章,积分不…...

轻松拿捏C语言——【字符函数】字符分类函数、字符转换函数
🥰欢迎关注 轻松拿捏C语言系列,来和 小哇 一起进步!✊ 🌈感谢大家的阅读、点赞、收藏和关注💕 🌹如有问题,欢迎指正 感谢 目录👑 一、字符分类函数🌙 二、字符转换函数…...

【Rust日报】ratatui版本更新
[new ver] ratatui v0.26.3 一个构建终端用户界面的库。新版本包括: 修复Unicode 截断 bug对颜色更好地序列化更快的渲染弃用assert_buffer_eq宏暴露错误类型常量函数和类型 官网: https://ratatui.rs/ 链接: https://ratatui.rs/highlights/v0263/ [new lib] ansi2…...
力扣每日一题 5/28
题目:2951-找出峰值 给你一个下标从 0 开始的数组 mountain 。你的任务是找出数组 mountain 中的所有 峰值。 以数组形式返回给定数组中 峰值 的下标,顺序不限 。 注意: 峰值 是指一个严格大于其相邻元素的元素。数组的第一个和最后一个元…...
async函数和await函数
一、async函数 async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。 因此对async函数可以直接then,返回值就是then方法传入的函数。 // async基础语法 async function fun0(){console.log(1);return 1; } fun0()…...

Redis面试题深度解析
1、我看你做的项目中,都用到了redis,你在最近的项目中哪些场景使用了redis呢? 2、缓存穿透 布隆过滤器的误判现象 Redisson和Guava都对布隆过滤器进行了实现 3、缓存击穿 互斥锁,就是一个线程来修改,并占据了锁,另外其…...
Ubuntu 22.04 .NET8 程序 环境安装和运行
前言 我们需要将.NET8编写的console控制台程序,部署在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…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...