目 录CONTENT

文章目录

ArgoCD驱动的CI/CD半解耦实践:若依项目GitOps部署全解析

Administrator
2025-08-08 / 0 评论 / 1 点赞 / 86 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

ArgoCD驱动的CI/CD半解耦实践:若依项目GitOps部署全解析

在现代软件开发中,持续集成(CI)和持续部署(CD)是提高软件交付效率和质量的两个重要实践。
通常的做法是CI/CD耦合在一起,即在同一条流水线中,既做CI(持续集成)的构建和测试,也做CD(持续部署)。但在某些情况下,特别是已经存在镜像的情况下,将CI与CD解耦可能是更灵活的选择。
本文将详细介绍一种基于这种半解耦模式的CI/CD流水线,特别是如何通过CI流水线构建镜像并上传,然后触发Argo CD进行部署。

前置条件

  • Jenkins/GitLab CI/GitHub Actions等CI工具
  • ArgoCD
  • Docker
  • Kubernetes
  • gitlab/gitee/gogs等仓库托管服务
  • harbor/docker hub等镜像仓库服务
  • kustomize/helm等配置管理工具

概述

1. CI流水线概述

CI流水线是自动化构建和测试软件代码的过程。在本例中,CI流水线包括以下步骤:

  • 下载代码:从版本控制系统(如Git)中拉取最新的代码。
  • 编译构建:对代码进行编译和构建,生成可执行文件或构建产物。
  • 打包镜像:将构建产物打包成Docker镜像。
  • 上传镜像:将打包好的Docker镜像上传到镜像仓库(如Docker Hub、Harbor等)。

这些步骤通常是由CI工具(如Jenkins、GitLab CI、GitHub Actions等)自动化执行的。

2. 半自动化CD触发

在本例中,CD部分不是完全由CI流水线自动化控制的。
相反,当CI流水线完成镜像上传后,继续在此CI流水线,下载argocd-gitops仓库的代码,然后通过编码的方式(具体是通过yq工具),更新镜像的名称与tag,推送至argocd-gitops仓库,argocd监控此仓库的变化,进而触发部署。

3. Argo CD基于CI流水线结果的部署流程

Argo CD是一个声明式GitOps持续交付工具,它使用Git作为应用程序定义的唯一真实来源。在本例中,Argo CD将基于CI流水线生成的新镜像信息来更新Kubernetes集群中的应用程序。

  • 配置仓库:Argo CD使用一个Git仓库来存储应用程序的配置(如Kubernetes清单文件)。
  • 镜像更新:当CI流水线完成镜像上传后,它会更新配置仓库中的镜像tag信息(可能是通过直接修改文件、提交新的commit等方式)。
  • Argo CD同步:Argo CD会定期检查配置仓库中的变化,并尝试将这些变化同步到Kubernetes集群中。当检测到镜像tag更新时,Argo CD会自动触发部署操作,将新的镜像部署到集群中。
  • 手动确认(可选):在某些情况下,为了在生产环境中部署新镜像之前进行额外的验证或审批,可以在Argo CD中配置手动同步步骤。这样,即使CI流水线已经完成了镜像上传和配置更新,也需要手动确认后才能触发部署。

实操,以若依的ruoyi-gateway为例

CI的流水线编写

编写及配置jenkins shared library

本文使用到了jenkins的共享库,因为有必要介绍具体的编写及配置jenkins shared library过程,具体参考此链接:
编写及配置jenkins shared library
本文中用到的jenkins shared library代码,可以参考我的另外一个仓库:
howlaisi-shared-library
此仓库封装了下载代码、构建镜像、上传镜像、更新argocd-gitops仓库的代码。

编写Jenkinsfile

以一个后端的Java项目:若依的ruoyi-gateway为例,其Jenkinsfile长这样:

@Library('howlaisi_shared_library@master') _ // 引用共享库

pipeline {
    triggers {
        cron("0 * * * *")     // 每小时执行一次 
    }
    agent {
        node {
            label 'maven'     // 使用标签为maven的节点执行构建任务
        }
    }
    parameters {
        string(
                name: 'BRANCH_NAME',
                defaultValue: 'master',
                description: '这里的值是默认值'  // 这里的参数是默认值,在Jenkins流水线配置界面可以修改
        )
    }
    environment {
        // 镜像仓库地址,这里是私有harbor的地址
        REGISTRY = 'k8s-harbor:30002'
        // 镜像仓库的命名空间,这里是私有harbor的项目名
        DOCKERHUB_NAMESPACE = 'sms-prod-project'
        // 代码仓库地址,这里是若依的ruoyi-cloud项目
        APP_REPO = 'https://gitee.com/howlaisi/RuoYi-Cloud.git'
        // argocd-gitops仓库地址,这里是若依的argocd-gitops项目
        ARGOCD_REPO = "https://gitee.com/howlaisi/argocd-gitops.git"
        // kustomize文件路径,argocd-gitops仓库中:ruoyi项目的kustomization.yaml文件的绝对路径
        KUSTOMIZE_FILE = "howlaisi/sms/overlays/sms-prod-project/kustomization.yaml"  

    }

    stages {
        stage('动态变量设置') {
            steps {
                script {
                    env.JAR_PATH = "ruoyi-gateway"  
                    env.APP_NAME = "ruoyi-gateway"
                }
            }
        }
        stage("下载代码,配置yq,下载argocd-gitops代码,配置用户名及密码") {
            steps {
                container('maven') {
                    script {
                        // 下载代码,这里是若依的ruoyi-cloud项目
                        gt.checkout(APP_REPO, BRANCH_NAME, "gitlab-id")
                        // 配置yq工具,用于更新argocd-gitops仓库中的镜像tag信息,具体代码可以到我的仓库查看。
                        yqTools.configYq()   
                        dir("argocd-gitops") {
                            // 下载argocd-gitops仓库代码,用于后续更新镜像tag信息
                            gt.clone(ARGOCD_REPO, "master", "gitlab-id")
                            // 配置gitlab的用户名及密码,用于推送argocd-gitops仓库的代码
                            gitopsTools.configGitlab("master") 
                        }
                    }
                }
            }
        }

        stage('项目编译') {
            agent none
            steps {
                container('maven') {
                    sh 'pwd && ls -al'
                    // 编译项目,这里是若依的ruoyi-gateway模块
                    sh 'mvn clean package -e -DskipTests -Dcheckstyle.skip=true -Dmaven.test.skip=true -U'
                }
            }
        }
        stage('构建镜像') {
            agent none
            steps {
                container('maven') {
                    sh 'ls $JAR_PATH/target'
                    // 构建镜像,这里是若依的ruoyi-gateway模块,这里用的是Dockerfile文件进行构建。 
                    sh "cd $JAR_PATH && docker build --build-arg SPRING_PROFILES_ACTIVE=prod -t $APP_NAME:latest -f ./Dockerfile ."
                }
            }
        }
        stage('推送镜像') {
            agent none
            steps {
                container('maven') {
                    withCredentials([usernamePassword(credentialsId: 'harbor-id', usernameVariable: 'DOCKER_USER_VAR', passwordVariable: 'DOCKER_PWD_VAR',)]) {
                        // 登录harbor镜像仓库,这里是私有harbor的地址
                        sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin'
                        // 给镜像打tag,这里是私有harbor的地址、项目名和分支名等信息
                        sh "docker tag $APP_NAME:latest $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BRANCH_NAME-$BUILD_NUMBER-$COMMIT_ID"
                        script {
                            // 推送镜像到harbor
                            yqTools.pushImage("$REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$BRANCH_NAME-$BUILD_NUMBER-$COMMIT_ID") 
                        }
                    }
                }
            }
        }
        stage('更新argocd-gitops镜像') {
            steps {
                script {
                    container('maven') {
                        dir("argocd-gitops") {
                            // 更新argocd-gitops仓库中的镜像tag信息,具体代码可以到我的仓库查看。
                            gitopsTools.updateGitopsRepo()
                        }
                    }
                }
            }
        }
    }

    post {
        always {
            script {
                println("always")
            }
        }
        success {
            script {
                println("success")
            }
        }
        failure {
            script {
                println("failure")
            }
        }
        aborted {
            script {
                println("aborted")
            }
        }
    }
}

CD的YAML配置文件编写

编写kustomize配置

在argocd-gitops仓库中,根据kustomize的语法,编写base/overlays。

  • base
    base
  • overlays
    overlays
    了解更多kustomize的用法,可以参考张师傅的kustomize分享以及argocd-gitops仓库:
  • kustomize分享
  • argocd-gitops

在argocd的界面上创建Application

  • 可以在界面上通过编写YAML文件的方式,创建Application。
    yaml1
    yaml2
    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: sms-prod
    spec:
      destination:
        name: ''
        namespace: ''
        server: 'https://kubernetes.default.svc'
      source:
        path: howlaisi/sms/overlays/sms-prod-project
        repoURL: 'https://gitee.com/howlaisi/argocd-gitops.git'
        targetRevision: HEAD
      project: default
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
    
  • 通过填写表单的方式,创建Application。
    biaodan
    以上两种方式均可创建Application,原理其实是一样的,都是通过编写YAML文件的方式来创建Application。

4. 结论

通过将CI流水线与半自动化的CD触发机制相结合,并使用Argo CD作为声明式GitOps持续交付工具,我们可以实现高效且可靠的软件交付流程。这种半解耦的CI/CD模式允许团队在保持自动化构建和测试的同时,对部署过程进行更精细的控制和验证。

1
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区