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: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. 修改语言

修改语言:点击头像选择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-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 – 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-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整合

点击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=$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下->点击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 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下选择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 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下添加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: 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 -f /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 --> 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 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:'部署失败!'
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/666678.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【SpringBoot】JWT+Token之Token自动续期

目录 回顾一下JWT基于JWT的认证流程安全性性能一次性 Token过期影响解决智障思路分析 token定时检查续期思路分析大致代码问题 双token【重点】思路分析补充微信网页授权方案 实现1.依赖2.配置3.拦截器及配置4.其他类5.token映射类6.jwt工具类7.controller类8.测试 总结双token…

HackTheBox-Machines--Bashed

Bashed 测试过程 1 信息收集 NMAP 80 端口 目录扫描 http://10.129.155.171/dev/phpbash.min.php http://10.129.155.171/dev/phpbash.php 半交互式 shell 转向 交互式shell python -c import socket,subprocess,os;ssocket.socket(socket.AF_INET,socket.SOCK_STREAM);s.co…

模型 FABE(特性 优势 好处 证据)法则

说明&#xff1a;系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。特性、优势、好处、证据&#xff0c;一气呵成。 1 FABE法则的应用 1.1 FABE法则营销商用跑步机 一家高端健身器材公司的销售代表正在向一家新开的健身房推销他们的商用跑步机。以下…

腾讯元宝眼中的我,竟是一个变现20w的AI博主!

文章首发于公众号&#xff1a;X小鹿AI副业 大家好&#xff0c;我是程序员X小鹿&#xff0c;前互联网大厂程序员&#xff0c;自由职业2年&#xff0c;也一名 AIGC 爱好者&#xff0c;持续分享更多前沿的「AI 工具」和「AI副业玩法」&#xff0c;欢迎一起交流~ 昨天&#xff08;5…

工厂模式详情

一.介绍工厂模式的用途与特点 工厂方法模式是一种创建型设计模式&#xff0c; 其在父类中提供一个创建对象的方法&#xff0c; 允许子类决定实例化对象的类型。定义工厂方法模式(Fatory Method Pattern)是指定义一个创建对象的接口&#xff0c;但让实现这个接口的类来决定实例…

FasterRCNN入门案例水稻图像目标检测新手友好入门案例

目录 依赖环境 代码概述 引用库 读取数据指定目录 数据集划分 数据集加载Dataset类 特征增强处理 预训练模型定义 评估指标定义 实例化训练集和测试集 设置硬件调取一个batch 可视化 ​编辑 激活选定硬件&#xff0c;初始化损失函数参数 模型训练 模型测试和验…

61. UE5 RPG 实现敌人近战攻击技能和转向攻击

在前面&#xff0c;我们实现了敌人的AI系统&#xff0c;敌人可以根据自身的职业进行匹配对应的攻击方式。比如近战战士会靠近目标后进行攻击然后躲避目标的攻击接着进行攻击。我们实现了敌人的AI行为&#xff0c;但是现在还没有实现需要释放的技能&#xff0c;接下来&#xff0…

让ChatGPT成为自己的旅游顾问

不积跬步&#xff0c;无以至千里&#xff1b;不积小流&#xff0c;无以成江海。 大家好&#xff0c;我是闲鹤&#xff0c;公众号 xxh_zone&#xff0c;十多年开发、架构经验&#xff0c;先后在华为、迅雷服役过&#xff0c;也在高校从事教学3年&#xff1b;目前已创业了7年多&a…

桃金娘T2T基因组-文献精读17

Gap-free genome assembly and comparative analysis reveal the evolution and anthocyanin accumulation mechanism of Rhodomyrtus tomentosa 无缺口基因组组装及比较分析揭示了桃金娘的进化和花青素积累机制 摘要 桃金娘&#xff08;Rhodomyrtus tomentosa&#xff09;是…

安装Kubernetes v3 ----以docker的方式部署

以docker的方式部署 docker run -d \ --restartunless-stopped \ --namekuboard \ -p 80:80/tcp \ -p 10081:10081/tcp \ -e KUBOARD_ENDPOINT"http://192.168.136.55:80" \ -e KUBOARD_AGENT_SERVER_TCP_PORT"10081" \ -v /root/kuboard-data:/data \ e…

Flutter中如何让Android的手势导航栏完全透明?

Flutter 开发中 安卓机器都有 像ios 的手势操作栏&#xff0c; 也就是屏幕底下的 那条线。 但这条线默认是有颜色的 &#xff08;像下面这样&#xff09; 一、全屏幕方式 void main() {// 全屏沉浸式SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []…

iOS ------ 多线程 GCD

一&#xff0c;GCD简介 GCD是Apple开发的一个多线程的较新的解决方案。它主要用于优化应用程序以支持多核处理器以及其他对称处理系统。它是一个在线程池模式的基础上执行的并发任务。 为什么要使用GCD&#xff1f; GCD&#xff01;可用于多核的并行运算GCD会自动利用更多的…

【学习Day3】计算机基础

✍&#x1f3fb;记录学习过程中的输出&#xff0c;坚持每天学习一点点~ ❤️希望能给大家提供帮助~欢迎点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;指点&#x1f64f; 1.5.4 Cache替换算法 Cache的页面淘汰算法 常用替换算法有&#xff1a; • 随机替换算法RA…

方差分析的七种类型

方差分析&#xff08;ANOVA&#xff09;是一种用于检验两个以上样本均数差别的显著性统计方法。根据不同的研究设计和数据类型&#xff0c;方差分析可以分为以下7种类型。 一、单因素方差分析 ①单因素方差分析说明 单因素方差分析用于研究一个定类数据&#xff08;自变量&am…

开发一个SDK(starter)

1.创建项目 将pom.xml中build删除掉

用容器构建wordpress项目

用容器构建wordpress项目 #准备两个镜像 #数据库和centos docker pull mysql:5.7 docker pull centos:7 #创建一个wordpress文件夹&#xff0c;在wordpress文件里面写一个Dockerfile文件 vim DockerfileFROM centos:7 #基于centos环境RUN yum -y install epel-release ;\ #安装…

http协议及httpd安装组成

文章目录 一、http协议http协议通信过程http相关技术网站访问量HTTP工作机制HTTP协议版本HTTP请求访问的完整过程HTTP报文头部响应报文 二、httpd安装组成apache介绍和特点工作模式&#xff08; MPM multi-processing module &#xff09;Http相关文件Http编译安装httpd常见配置…

文件系统小册(FusePosixK8s csi)【1 Fuse】

文件系统小册&#xff08;Fuse&Posix&K8s csi&#xff09;【1 Fuse&#xff1a;用户空间的文件系统】 Fuse(filesystem in userspace),是一个用户空间的文件系统。通过fuse内核模块的支持&#xff0c;开发者只需要根据fuse提供的接口实现具体的文件操作就可以实现一个文…

Unity中的MVC框架

基本概念 MVC全名是Model View Controller 是模型(model)-视图(view)-控制器(controller)的缩写 是一种软件设计规范&#xff0c;用一种业务逻辑、数据、界面显示 分离的方法组织代码 将业务逻辑聚集到一个部件里面&#xff0c;在改进和个性化定制界面及用户交互的同时&#x…

tinycudann安装

在安装完torch等 直接运行下面的指令会出现错误 pip install githttps://github.com/NVlabs/tiny-cuda-nn/#subdirectorybindings/torch大部分错误是下面的 大概看了一下都是因为虚拟环境里面的include文件下缺少文件&#xff0c;将之前的一些.h文件全部复制过来在执行上面的…