基于Jenkins和Argocd实现CI/CD(二)

简介: 基于Jenkins和Argocd实现CI/CD

在Jenkins上配置共享库


(1)需要在Jenkins上添加凭证


640.png


(2)在Jenkins的系统配置里面配置共享库(系统管理-->系统配置)


640.png


然后点击应用并保存


然后我们可以用一个简单的Jenkinsfile测试一下共享库,看配置是否正确。


在Jenkins上创建一个项目,如下:


640.png


然后在最地下的pipeline处贴入以下代码:


def labels = "slave-${UUID.randomUUID().toString()}"
// 引用共享库
@Library("jenkins_shareLibrary")
// 应用共享库中的方法
def tools = new org.devops.tools()
pipeline {
    agent {
    kubernetes {
        label labels
      yaml """
apiVersion: v1
kind: Pod
metadata:
  labels:
    some-label: some-label-value
spec:
  volumes:
  - name: docker-sock
    hostPath:
      path: /var/run/docker.sock
      type: ''
  containers:
  - name: jnlp
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/inbound-agent:4.3-4
  - name: maven
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/maven:3.5.0-alpine
    command:
    - cat
    tty: true
  - name: docker
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/docker:19.03.11
    command:
    - cat
    tty: true
    volumeMounts:
    - name: docker-sock
      mountPath: /var/run/docker.sock
"""
    }
  }
    stages {
        stage('Checkout') {
            steps {
                script{
                    tools.PrintMes("拉代码","green")
                }
            }
        }
        stage('Build') {
            steps {
                container('maven') {
                    script{
                        tools.PrintMes("编译打包","green")
                    }
                }
            }
        }
        stage('Make Image') {
            steps {
                container('docker') {
                    script{
                        tools.PrintMes("构建镜像","green")
                    }
                }
            }
        }
    }
}


然后点击保存并运行,如果看到输出有颜色,就代表共享库配置成功,如下:


640.png


到此共享库配置完成。


编写Jenkinsfile


整个java的Jenkinsfile如下:


def labels = "slave-${UUID.randomUUID().toString()}"
// 引用共享库
@Library("jenkins_shareLibrary")
// 应用共享库中的方法
def tools = new org.devops.tools()
def sonarapi = new org.devops.sonarAPI()
def sendEmail = new org.devops.sendEmail()
def build = new org.devops.build()
def sonar = new org.devops.sonarqube()
// 前端传来的变量
def gitBranch = env.branch
def gitUrl = env.git_url
def buildShell = env.build_shell
def image = env.image
def dockerRegistryUrl = env.dockerRegistryUrl
def devops_cd_git = env.devops_cd_git
pipeline {
    agent {
    kubernetes {
        label labels
      yaml """
apiVersion: v1
kind: Pod
metadata:
  labels:
    some-label: some-label-value
spec:
  volumes:
  - name: docker-sock
    hostPath:
      path: /var/run/docker.sock
      type: ''
  - name: maven-cache
    persistentVolumeClaim:
      claimName: maven-cache-pvc
  containers:
  - name: jnlp
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/inbound-agent:4.3-4
  - name: maven
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/maven:3.5.0-alpine
    command:
    - cat
    tty: true
    volumeMounts:
    - name: maven-cache
      mountPath: /root/.m2
  - name: docker
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/docker:19.03.11
    command:
    - cat
    tty: true
    volumeMounts:
    - name: docker-sock
      mountPath: /var/run/docker.sock
  - name: sonar-scanner
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/sonar-scanner:latest
    command:
    - cat
    tty: true
  - name: kustomize
    image: registry.cn-hangzhou.aliyuncs.com/rookieops/kustomize:v3.8.1
    command:
    - cat
    tty: true
"""
    }
  }
    environment{
        auth = 'joker'
    }
    options {
        timestamps()    // 日志会有时间
        skipDefaultCheckout()   // 删除隐式checkout scm语句
        disableConcurrentBuilds()   //禁止并行
        timeout(time:1,unit:'HOURS') //设置流水线超时时间
    }
    stages {
        // 拉取代码
        stage('GetCode') {
            steps {
                checkout([$class: 'GitSCM', branches: [[name: "${gitBranch}"]],
                    doGenerateSubmoduleConfigurations: false,
                    extensions: [],
                    submoduleCfg: [],
                    userRemoteConfigs: [[credentialsId: '83d2e934-75c9-48fe-9703-b48e2feff4d8', url: "${gitUrl}"]]])
                }
            }
        // 单元测试和编译打包
        stage('Build&Test') {
            steps {
                container('maven') {
                    script{
                        tools.PrintMes("编译打包","blue")
                        build.DockerBuild("${buildShell}")
                    }
                }
            }
        }
        // 代码扫描
        stage('CodeScanner') {
            steps {
                container('sonar-scanner') {
                    script {
                        tools.PrintMes("代码扫描","green")
                        tools.PrintMes("搜索项目","green")
                        result = sonarapi.SearchProject("${JOB_NAME}")
                        println(result)
                        if (result == "false"){
                            println("${JOB_NAME}---项目不存在,准备创建项目---> ${JOB_NAME}!")
                            sonarapi.CreateProject("${JOB_NAME}")
                        } else {
                            println("${JOB_NAME}---项目已存在!")
                        }
                        tools.PrintMes("代码扫描","green")
                        sonar.SonarScan("${JOB_NAME}","${JOB_NAME}","src")
                        sleep 10
                        tools.PrintMes("获取扫描结果","green")
                        result = sonarapi.GetProjectStatus("${JOB_NAME}")
                        println(result)
                        if (result.toString() == "ERROR"){
                            toemail.Email("代码质量阈错误!请及时修复!",userEmail)
                            error " 代码质量阈错误!请及时修复!"
                        } else {
                            println(result)
                        }
                    }
                }
            }
        }
        // 构建镜像
        stage('BuildImage') {
            steps {
                withCredentials([[$class: 'UsernamePasswordMultiBinding',
                credentialsId: 'dockerhub',
                usernameVariable: 'DOCKER_HUB_USER',
                passwordVariable: 'DOCKER_HUB_PASSWORD']]) {
                    container('docker') {
                        script{
                            tools.PrintMes("构建镜像","green")
                            imageTag = tools.createVersion()
                            sh """
                            docker login ${dockerRegistryUrl} -u ${DOCKER_HUB_USER} -p ${DOCKER_HUB_PASSWORD}
                            docker build -t ${image}:${imageTag} .
                            docker push ${image}:${imageTag}
                            docker rmi ${image}:${imageTag}
                            """
                        }
                    }
                }
            }
        }
        // 部署
        stage('Deploy') {
            steps {
                 withCredentials([[$class: 'UsernamePasswordMultiBinding',
                credentialsId: 'ci-devops',
                usernameVariable: 'DEVOPS_USER',
                passwordVariable: 'DEVOPS_PASSWORD']]){
                    container('kustomize') {
                        script{
                            APP_DIR="${JOB_NAME}".split("_")[0]
                            sh """
                            git remote set-url origin http://${DEVOPS_USER}:${DEVOPS_PASSWORD}@${devops_cd_git}
                            git config --global user.name "Administrator"
                            git config --global user.email "coolops@163.com"
                            git clone http://${DEVOPS_USER}:${DEVOPS_PASSWORD}@${devops_cd_git} /opt/devops-cd
                            cd /opt/devops-cd
                            git pull
                            cd /opt/devops-cd/${APP_DIR}
                            kustomize edit set image ${image}:${imageTag}
                            git commit -am 'image update'
                            git push origin master
                            """
                        }
                    }
                }
            }
        }
        // 接口测试
        stage('InterfaceTest') {
            steps{
                sh 'echo "接口测试"'
            }
        }
    }
    // 构建后的操作
    post {
        success {
            script{
                println("success:只有构建成功才会执行")
                currentBuild.description += "\n构建成功!"
                // deploy.AnsibleDeploy("${deployHosts}","-m ping")
                sendEmail.SendEmail("构建成功",toEmailUser)
                // dingmes.SendDingTalk("构建成功 ✅")
            }
        }
        failure {
            script{
                println("failure:只有构建失败才会执行")
                currentBuild.description += "\n构建失败!"
                sendEmail.SendEmail("构建失败",toEmailUser)
                // dingmes.SendDingTalk("构建失败 ❌")
            }
        }
        aborted {
            script{
                println("aborted:只有取消构建才会执行")
                currentBuild.description += "\n构建取消!"
                sendEmail.SendEmail("取消构建",toEmailUser)
                // dingmes.SendDingTalk("构建失败 ❌","暂停或中断")
            }
        }
    }
}


需要在Jenkins上创建两个凭证,一个id叫dockerhub,一个叫ci-devops,还有一个叫sonar-admin-user。


dockerhub是登录镜像仓库的用户名和密码。


ci-devops是管理YAML仓库的用户名和密码。


sonar-admin-user是管理sonarqube的用户名和密码。


然后将这个Jenkinsfile保存到shareLibrary的根目录下,命名为java.Jenkinsfile。


640.png


在Jenkins上配置项目


在Jenkins上新建一个项目,如下:


640.png


然后添加以下参数化构建。


640.png

640.png

640.png

640.png

640.png

640.png

640.png


然后在流水线处配置Pipeline from SCM


640.png


640.png


此处需要注意脚本名。


然后点击应用保存,并运行。


640.png


也可以在sonarqube上看到代码扫描的结果。


640.png


在Argocd上配置CD流程


在argocd上添加代码仓库,如下:


640.png

640.png


然后创建应用,如下:


640.png

640.png


点击创建后,如下:


640.png


点进去可以看到更多的详细信息。


640.png


argocd有一个小bug,它ingress的健康检查必须要loadBalance有值,不然就不通过,但是并不影响使用。


然后可以正常访问应用了。


640.png


node项目的Jenkinsfile大同小异,由于我没有测试用例,所以并没有测试


集成Gitlab,通过Webhook触发Jenkins


在Jenkins中选择项目,在项目中配置gitlab触发,如下:


640.png


生成token,如下


640.png


在gitlab上配置集成。进入项目-->项目设置-->集成


640.png


配置Jenkins上生成的回调URL和TOKEN


640.png


到此配置完成,然后点击下方test,可以观察是否触发流水线。


640.png


也可以通过修改仓库代码进行测试。


写在最后


本片文章是纯操作步骤,大家在测试的时候可能会对Jenkinsfile做细微的调整,不过整体没什么问题。


相关文章
|
3月前
|
运维 监控 jenkins
运维自动化实战:利用Jenkins构建高效CI/CD流程
【10月更文挑战第18天】运维自动化实战:利用Jenkins构建高效CI/CD流程
|
3月前
|
jenkins Shell 持续交付
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(二)
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(二)
109 0
|
3月前
|
运维 监控 jenkins
运维自动化实践:利用Jenkins实现高效CI/CD流程
【10月更文挑战第18天】运维自动化实践:利用Jenkins实现高效CI/CD流程
|
3月前
|
jenkins Shell 持续交付
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(一)
Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 持续集成 CI/CD 超级详细 超多图(一)
303 0
|
5月前
|
jenkins Shell 持续交付
自动化部署:使用Jenkins和Docker实现CI/CD
【8月更文挑战第31天】 本文旨在引导读者了解如何通过Jenkins和Docker来实现持续集成和持续部署(CI/CD),从而优化开发流程,提升工作效率。文章将详细介绍配置Jenkins服务器、创建Docker镜像以及设置自动化构建和部署的步骤。通过实际操作案例,我们将展示如何将代码变更快速部署到测试或生产环境,确保软件质量与发布速度的双重保障。
|
2月前
|
jenkins Devops Java
DevOps实践:Jenkins在持续集成与持续部署中的价值
【10月更文挑战第27天】在快速发展的软件开发领域,DevOps实践日益重要。Jenkins作为一款流行的开源自动化服务器,在持续集成(CI)和持续部署(CD)中扮演关键角色。本文通过案例分析,探讨Jenkins在Java项目中的应用,展示其自动化构建、测试和部署的能力,提高开发效率和软件质量。
97 2
|
4天前
|
Java jenkins 持续交付
Jenkins集成Maven
通过以上步骤,可以在Jenkins中成功集成Maven,实现自动化构建和部署。通过定时构建、SCM轮询等方式,可以确保代码库中的最新变更能够及时构建和测试,提高开发效率和代码质量。这种集成方式在实际项目中具有广泛的应用前景,能够显著提升团队的协作效率。
30 8
|
5月前
|
jenkins 持续交付 开发者
自动化部署:使用Jenkins和Docker实现持续集成与交付
【8月更文挑战第31天】本文旨在为读者揭示如何通过Jenkins和Docker实现自动化部署,从而加速软件开发流程。我们将从基础概念讲起,逐步深入到实际操作,确保即使是初学者也能跟上步伐。文章将提供详细的步骤说明和代码示例,帮助读者理解并应用这些工具来优化他们的工作流程。
|
1月前
|
监控 jenkins Linux
从 Jenkins 持续集成出发:探究如何监控员工电脑屏幕
Jenkins 在企业信息化管理中用于自动化构建、测试和部署,提高开发效率。本文讨论了其重要性,并从技术角度探讨了屏幕监控的可能性,但明确反对非法监控,强调应合法合规地管理企业和尊重员工隐私。
82 12
|
2月前
|
运维 jenkins Java
Jenkins在持续集成与持续部署中的价值
Jenkins在持续集成与持续部署中的价值