springcloud微服务k8s部署-03-云服务器CICD

1、CICD流程总览

在这里插入图片描述

部署流程

1、通过jenkins拉取开发人员提交到gitee上最新的代码
2、通过maven进行打包
3、调用sonarqube进行代码质量检查
4、通过dockerfile制作镜像
5、提交制作的镜像到镜像仓库
6、通过k8s拉取最新的镜像,重启pod

2、项目准备

这次我准备了一个微服务项目,是依照Ruiyi-Cloud进行了一些修改,所得到的微服务项目。项目地址为:https://gitee.com/qi-guohui/qgh-cloud,大家请fork到自己的代码仓库中。

3、流水线方式的任务

1、通过jenkins拉取开发人员提交到gitee上最新的代码
1、新建流水线方式

在这里插入图片描述

2、配置git地址

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、在代码长库中添加流水线文件Jenkinsfile

在这里插入图片描述
jenkinsfile文件内容为:

pipeline {
    // 指定任务在哪个集群节点中执行
    agent any

    // 声明全局变量,方便后面使用
    environment {
    }

    stages {
        stage('拉取git仓库代码') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

在这里插入图片描述
在这里插入图片描述
把生成的脚本放到jenkinsfile中,修改后的jenkinsfile内容如下:

pipeline {
    // 指定任务在哪个集群节点中执行
    agent any
    stages {
        stage('拉取git仓库代码') {
            steps {
           checkout scmGit(branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: 'b3716fb8-9358-4326-8b18-4bc7b7e6ec1c', url: 'https://gitee.com/qi-guohui/qgh-cloud.git']])
            }
        }
    }
}
4、配置项目变量

1、配置tag
在这里插入图片描述
在这里插入图片描述
2、配置选项参数
在这里插入图片描述
配置完成后,构建页面如下图所示:
在这里插入图片描述

2、通过maven进行打包
1、配置jenkinsfile
pipeline {
    // 指定任务在哪个集群节点中执行
    agent any

     tools {
        // 指定要使用的 Maven 版本,需要配置maven
        maven 'maven_home' 
    }

    stages {

        stage('拉取git仓库代码') {
            steps {
           checkout scmGit(branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: 'b3716fb8-9358-4326-8b18-4bc7b7e6ec1c', url: 'https://gitee.com/qi-guohui/qgh-cloud.git']])
            }
        }

        stage('项目打包') {
            steps {
                script {
                    // 打包
                    doPackage()
                }
            }
        }
       
    }

}

def doPackage() {

    if (env.program_name == 'yueyang-ui') {
       
        // 前端,需要设置权限,不然jenkins容器没有目录的权限,会导致下载前端依赖失败
       // sh 'chmod -R 777 /var/jenkins_home/workspace/yueyang-ui && cd yueyang-ui && npm cache clean --force && npm install --registry=https://registry.npmmirror.com --unsafe-perm && npm run build:prod'
       sh '''
        chmod -R 777 /var/jenkins_home/workspace/yueyang-ui
        cd yueyang-ui
        rm -rf node_modules/
        npm cache clean --force
        npm install --registry=https://registry.npmmirror.com --unsafe-perm
        npm run build:prod
       '''
    } else {
        // 后端 sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
        sh 'mvn clean package -DskipTests'
    }

}

这里在tools组件中指定了maven,运行是按指定的maven打包,这里需要特殊注意一下,maven配置的值必须是全局工具配置的变量的名称,如果没配置,必须要配置,按如下图配置
在这里插入图片描述

3、调用sonarqube进行代码质量检查
1、启动sonarqube服务

修改docker-compose.yml文件,添加sonarqube

services:
  jenkins:
    image: jenkins/jenkins:qgh
    container_name: jenkins
    ports:
      - 8080:8080
      - 50000:50000
    volumes:
      - ./data1/:/var/jenkins_home/
      - /etc/localtime:/etc/localtime
    networks:
      - my_cloud_network 

  db:
    image: postgres
    container_name: db
    ports:
      - 5432:5432
    networks:
      - my_cloud_network
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar

  sonarqube:
    image: sonarqube:8.9.6-community
    container_name: sonarqube
    depends_on:
      - db
    ports:
      - "9000:9000"
    networks:
      - my_cloud_network
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
      SONAR_JDBC_USERNAME: sonar
      SONAR_JDBC_PASSWORD: sonar


networks:
  my_cloud_network:
    external: true

部署服务docker-compose up -d
在这里插入图片描述
启动报错
在这里插入图片描述
修改配置: vi /etc/sysctl.conf
在这里插入图片描述
#使文件生效: sysctl -p
#重启服务 : docker-compose up -d

2、获取sonarqube 的token

访问http://ip:9000/ 默认用户名密码是admin/admin
本人密码最后改成sonarqube
在这里插入图片描述
在这里插入图片描述

3、修改sonarqube插件配置

#进入jenkins容器,修改sonarqube-sconar
docker exec -it jenkins /bin/bash

vim /var/jenkins_home/sonar-scanner/conf/sonar-scanner.properties

sonar.host.url=http://sonarqube:9000
sonar.sourceEncoding=UTF-8
4、配置jenkinsfile
pipeline {
    // 指定任务在哪个集群节点中执行
    agent any

     // 声明全局变量,方便后面使用
    environment {
        sonarqubeToken='6daf20a303e0fd298f077f3e60c962579dc2d2a7'
    }

     tools {
        // 指定要使用的 Maven 版本,需要配置maven
        maven 'maven_home' 
    }

    stages {

        stage('拉取git仓库代码') {
            steps {
           checkout scmGit(branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: 'b3716fb8-9358-4326-8b18-4bc7b7e6ec1c', url: 'https://gitee.com/qi-guohui/qgh-cloud.git']])
            }
        }

        stage('项目打包') {
            steps {
                script {
                    // 打包
                    doPackage()
                }
            }
        }

        stage('通过Sonarqube做代码质量检测') {
            
            steps {
              script {
                 doSonarqube()
              }
            }
        }
       
    }

}

def doPackage() {

    if (env.program_name == 'yueyang-ui') {
       
        // 前端,需要设置权限,不然jenkins容器没有目录的权限,会导致下载前端依赖失败
       // sh 'chmod -R 777 /var/jenkins_home/workspace/yueyang-ui && cd yueyang-ui && npm cache clean --force && npm install --registry=https://registry.npmmirror.com --unsafe-perm && npm run build:prod'
       sh '''
        chmod -R 777 /var/jenkins_home/workspace/yueyang-ui
        cd yueyang-ui
        rm -rf node_modules/
        npm cache clean --force
        npm install --registry=https://registry.npmmirror.com --unsafe-perm
        npm run build:prod
       '''
    } else {
        // 后端 sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
        sh 'mvn clean package -DskipTests'
    }

}

def doSonarqube() {

    def scriptContent = '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./' + env.program_name + ' -Dsonar.projectname=' + env.JOB_NAME + ' -Dsonar.login=' + env.sonarqubeToken + ' -Dsonar.projectKey=' + env.JOB_NAME + ' -Dsonar.java.binaries=./' + env.program_name + '/target'

    // 定义程序所在目录
    env.program_dir_path = env.program_name

    if (env.program_name == 'yueyang-gateway' || env.program_name == 'yueyang-auth') {
        
        echo 'scriptContent: ' + scriptContent

        echo 'env.program_dir_path: ' + env.program_dir_path

        if(sh(script: scriptContent, returnStatus: true) != 0) {
            error '代码检查失败!'
        } else {
            echo '代码检查成功!'
        }
    } else if (env.program_name == 'yueyang-ui') {
        echo 'env.program_dir_path: ' + env.program_dir_path
        // 页面不检查
        echo '页面检查成功!'
    } else if (env.program_name == 'yueyang-file' 
            || env.program_name == 'yueyang-gen'
            || env.program_name == 'yueyang-job' 
            || env.program_name == 'yueyang-system'
    ) {
        // 子模块
        scriptContent = '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./yueyang-modules/' + env.program_name + ' -Dsonar.projectname=' + env.JOB_NAME + ' -Dsonar.login=' + env.sonarqubeToken + ' -Dsonar.projectKey=' + env.JOB_NAME + '    -Dsonar.java.binaries=./yueyang-modules/' + env.program_name + '/target'
       
        echo 'scriptContent: ' + scriptContent

        env.program_dir_path= 'yueyang-modules/' + env.program_name

        echo 'env.program_dir_path: ' + env.program_dir_path
        
        if(sh(script: scriptContent, returnStatus: true) != 0) {
            error '代码检查失败!'
        } else {
            echo '代码检查成功!'
        }

    } else {
        // 代码检查失败
        error '代码检查失败, 项目名称不存在!'
    }
}

注意:sonarqubeToken要换成自己生成的token

4、通过dockerfile制作镜像
1、容器内docker的安装

容器内安装docker有如下两种方式,
1、让jenkins中拥有docker(和主机拥有同一个docker)
2、可以在jenkins内部装一个docker
我们采用第一种方式

#修改宿主机的配置

cd /var/run
# 修改权限
chown root:root docker.sock
chmod o+rw docker.sock

修改docker-compose.yml
在这里插入图片描述

 - /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 up -d 或者 docker-compose restart jenkins

2、创建阿里云镜像仓库

1、在阿里云中搜索 容器镜像服务,创建个人镜像仓库,步骤如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2、docker登陆镜像仓库
sudo docker login --username=aliyun9269580612 crpi-y28tc52b6by7jt80.cn-hangzhou.personal.cr.aliyuncs.com
3、修改镜像仓库地址
#vim /etc/docker/daemon.json
在这里插入图片描述
#sudo systemctl restart docker

3、添加构建镜像脚本
   // 声明全局变量,方便后面使用
 environment {
    sonarqubeToken='6daf20a303e0fd298f077f3e60c962579dc2d2a7'
harbor_addr='crpi-y28tc52b6by7jt80.cn-hangzhou.personal.cr.aliyuncs.com/qgh-cloud-learning'
    }
........
     tools {
        // 指定要使用的 JDK 版本,需要配置jdk
        jdk 'java_home' // 替换为你的自定义JDK名称或者路径
        // 指定要使用的 Maven 版本,需要配置maven
        maven 'maven_home' 
        // 替换为你配置的 Maven 版本,需要安装nodejs插件
        nodejs 'node_home'
    } 
........
 stage('通过Docker制作自定义镜像') {
            steps {
                script {
                    if (env.program_name == 'yueyang-ui') {
                        sh '''
                        rm -rf ./docker/yueyang-ui/dist
                        mv ./yueyang-ui/dist ./docker/yueyang-ui/
                        cd ./docker/${program_dir_path}
                        docker build -t ${harbor_addr}/${JOB_NAME}:${tag} .
                        '''
                    } else {
                        sh '''
                            rm -rf ./docker/${program_dir_path}/java/
                            mkdir -p ./docker/${program_dir_path}/java/
                            mv ./${program_dir_path}/target/*.jar ./docker/${program_dir_path}/java/
                            cd ./docker/${program_dir_path}
                            docker build -t ${harbor_addr}/${JOB_NAME}:${tag} .
                        '''
                    }
                }
                
            }
        }
5、提交制作的镜像到镜像仓库

添加构建脚本

  stage('上传镜像到镜像仓库') {
            steps {
                sh '''docker image prune
                docker push ${harbor_addr}/${JOB_NAME}:${tag}'''
            }
        }

最后附上完整的jenkinsfile文件内容

pipeline {
    // 指定任务在哪个集群节点中执行
    agent any

     // 声明全局变量,方便后面使用
    environment {
        sonarqubeToken='6daf20a303e0fd298f077f3e60c962579dc2d2a7'
        harbor_addr='crpi-y28tc52b6by7jt80.cn-hangzhou.personal.cr.aliyuncs.com/qgh-cloud-learning'
    }

     tools {
        
        jdk 'java_home' 
      
        maven 'maven_home' 
       
        nodejs 'node_home'
    }

    stages {

        stage('拉取git仓库代码') {
            steps {
           checkout scmGit(branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: 'b3716fb8-9358-4326-8b18-4bc7b7e6ec1c', url: 'https://gitee.com/qi-guohui/qgh-cloud.git']])
            }
        }

        stage('项目打包') {
            steps {
                script {
                    // 打包
                    doPackage()
                }
            }
        }

        stage('通过Sonarqube做代码质量检测') {
            
            steps {
              script {
                 doSonarqube()
              }
            }
        }

        stage('通过Docker制作自定义镜像') {
            steps {
                script {
                    if (env.program_name == 'yueyang-ui') {
                        sh '''
                        rm -rf ./docker/yueyang-ui/dist
                        mv ./yueyang-ui/dist ./docker/yueyang-ui/
                        cd ./docker/${program_dir_path}
                        docker build -t ${harbor_addr}/${JOB_NAME}:${tag} .
                        '''
                    } else {
                        sh '''
                            rm -rf ./docker/${program_dir_path}/java/
                            mkdir -p ./docker/${program_dir_path}/java/
                            mv ./${program_dir_path}/target/*.jar ./docker/${program_dir_path}/java/
                            cd ./docker/${program_dir_path}
                            docker build -t ${harbor_addr}/${JOB_NAME}:${tag} .
                        '''
                    }
                }
                
            }
        }

        stage('上传镜像到镜像仓库') {
            steps {
                sh '''docker image prune -f
                docker push ${harbor_addr}/${JOB_NAME}:${tag}'''
            }
        }
       
    }

}

def doPackage() {

    if (env.program_name == 'yueyang-ui') {
       
        // 前端,需要设置权限,不然jenkins容器没有目录的权限,会导致下载前端依赖失败
       // sh 'chmod -R 777 /var/jenkins_home/workspace/yueyang-ui && cd yueyang-ui && npm cache clean --force && npm install --registry=https://registry.npmmirror.com --unsafe-perm && npm run build:prod'
       sh '''
        chmod -R 777 /var/jenkins_home/workspace/yueyang-ui
        cd yueyang-ui
        rm -rf node_modules/
        npm cache clean --force
        npm install --registry=https://registry.npmmirror.com --unsafe-perm
        npm run build:prod
       '''
    } else {
        // 后端 sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
        sh 'mvn clean package -DskipTests'
    }

}

def doSonarqube() {

    def scriptContent = '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./' + env.program_name + ' -Dsonar.projectname=' + env.JOB_NAME + ' -Dsonar.login=' + env.sonarqubeToken + ' -Dsonar.projectKey=' + env.JOB_NAME + ' -Dsonar.java.binaries=./' + env.program_name + '/target'

    // 定义程序所在目录
    env.program_dir_path = env.program_name

    if (env.program_name == 'yueyang-gateway' || env.program_name == 'yueyang-auth') {
        
        echo 'scriptContent: ' + scriptContent

        echo 'env.program_dir_path: ' + env.program_dir_path

        if(sh(script: scriptContent, returnStatus: true) != 0) {
            error '代码检查失败!'
        } else {
            echo '代码检查成功!'
        }
    } else if (env.program_name == 'yueyang-ui') {
        echo 'env.program_dir_path: ' + env.program_dir_path
        // 页面不检查
        echo '页面检查成功!'
    } else if (env.program_name == 'yueyang-file' 
            || env.program_name == 'yueyang-gen'
            || env.program_name == 'yueyang-job' 
            || env.program_name == 'yueyang-system'
    ) {
        // 子模块
        scriptContent = '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./yueyang-modules/' + env.program_name + ' -Dsonar.projectname=' + env.JOB_NAME + ' -Dsonar.login=' + env.sonarqubeToken + ' -Dsonar.projectKey=' + env.JOB_NAME + '    -Dsonar.java.binaries=./yueyang-modules/' + env.program_name + '/target'
       
        echo 'scriptContent: ' + scriptContent

        env.program_dir_path= 'yueyang-modules/' + env.program_name

        echo 'env.program_dir_path: ' + env.program_dir_path
        
        if(sh(script: scriptContent, returnStatus: true) != 0) {
            error '代码检查失败!'
        } else {
            echo '代码检查成功!'
        }

    } else {
        // 代码检查失败
        error '代码检查失败, 项目名称不存在!'
    }

    
}

《Docker和Kubernetes微服务实战》是一本非常实用的书籍。本书主要介绍了使用Docker和Kubernetes构建和部署微服务架构的实践方法和技巧。 首先,本书详细介绍了Docker和Kubernetes的基础知识和原理,包括容器技术的原理、镜像管理和容器编排等方面的内容。读者可以通过本书全面了解Docker和Kubernetes的核心概念和基本操作。 其次,本书从实践角度出发,详细介绍了使用Docker和Kubernetes构建和部署微服务的过程。作者通过丰富的实战案例,演示了如何将传统的单体应用拆分成微服务,并使用Docker容器化和Kubernetes部署这些微服务。读者可以学习到如何使用Dockerfile创建镜像、使用Docker Compose组织多个容器、使用Kubernetes进行服务编排和管理等相关技术。 此外,本书还特别强调了DevOps的实践,包括持续集成、持续交付和自动化测试等方面的内容。作者提供了一系列的实践指导,帮助读者构建完善的开发、测试和部署流程,提高开发效率和运维质量。 总的来说,本书是一本内容丰富、实用性强的Docker和Kubernetes微服务实战指南。对于想要学习和实践微服务架构的开发人员和运维人员来说,本书是一本不可多得的参考书籍。无论是初学者还是有一定经验的人员,都可以从本书中获取到宝贵的经验和知识,帮助他们在实际项目中更好地应用Docker和Kubernetes
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值