jenkins+argocd

45 阅读1分钟

安装jenkins

构建jenkins基础镜像

FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/jenkins/jenkins:lts-jdk17
USER root

USER root

# 设置环境变量,定义APT镜像源(使用清华大学源)
ENV DEBIAN_FRONTEND=noninteractive \
    APT_SOURCE="deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware\n\
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware\n\
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware\n\
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware"

# 备份原源文件,并写入新的镜像源
RUN echo "${APT_SOURCE}" > /etc/apt/sources.list

# 安装 docker.io (Docker Engine CLI) 和依赖
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        docker.io \
        ca-certificates \
        && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# 将jenkins用户添加到docker组,使其无需sudo即可使用docker命令
RUN usermod -aG docker jenkins

# 切换回原来的jenkins用户,保证容器以非root权限运行
USER jenkins

# 验证安装
RUN docker --version

使用docker-compose 启动jenkins

version: '3'
services:
  jenkins:
    image: 10.9.2.45:5000/jenkins:1.0.4
    container_name: jenkins
    restart: unless-stopped
    ports:
      - "9091:8080"
      - "50000:50000"
    user: root
    volumes:
      - jenkins_data:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
#      - /snap/bin/docker:/usr/bin/docker
    environment:
#      - JAVA_OPTS=-Djenkins.install.runSetupWizard=false  # 跳过初始设置(可选)
      - DOCKER_HOST=unix:///var/run/docker.sock

volumes:
  jenkins_data:

jenkins 设置

  1. 安装插件
  2. gitlab仓库设置 Credentials 添加仓库凭证
  3. k8s 配置 Credentials 添加集群配置

pipeline 脚本

pipeline {
  agent any
  
  environment {
        
        // GitOps (Argo CD) 仓库配置
        // 使用 SSH 地址以配合 sshagent
        ARGO_REPO_URL   = '仓库地址'
        // 你要更新的 GitOps 仓库分支
        ARGO_REPO_BRANCH = 'gitops' // 或者 'dev', 'master' 等
        // Kustomize 环境路径 (根据你的描述)
        ARGO_ENV_PATH    = 'overlays/dev'
    }
    
  parameters {
      gitParameter name: 'branch',
      type: 'PT_BRANCH',
      branchFilter: 'origin/(.*)',
      defaultValue: 'zmz-0827',
      selectedValue: 'DEFAULT',
      sortMode: 'ASCENDING_SMART',
      description: '选择需要构建的分支'
  }


  stages {
      stage('服务信息')    {
          steps {
              sh 'echo 分支:$branch'
              sh 'echo 构建服务类型:${JOB_NAME}-$type'
          }
      }


      stage('拉取代码') {
          steps {
              checkout([$class: 'GitSCM',
              branches: [[name: "${params.branch}"]],
              doGenerateSubmoduleConfigurations: false,
              extensions: [],
              submoduleCfg: [],
              userRemoteConfigs: [[credentialsId: 'gitlab-secret', url: 'http://git.landspace.com/chenxi/integrated_services.git']]])
          }
      }
 
      stage('获取commit_id') {
    steps {
        echo '获取commit_id'
        git branch: "${params.branch}",  // 指定分支
              credentialsId: 'gitlab-secret',
              url: '仓库地址'
        script {
            env.commit_id = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
        }
    }
}
 
      stage('goctl版本检测') {
          steps{
              sh '/usr/local/bin/goctl -v'
          }
      }

      stage('Dockerfile Build') {
          steps{
                 script{
                      env.image = sh(returnStdout: true, script: 'echo ${servicename}:${commit_id} | tr "[:upper:]" "[:lower:]"').trim()
                 }
                 sh 'echo 镜像名称:${image}  && ls -l '
                 
                   sh '''
      docker build -f docker/prod/${servicename}.Dockerfile -t ${image} .
    '''
          }
      }

      stage('上传到镜像仓库') {
    steps {
        script {
            // 将 servicename 转为小写
            def lowerServiceName = params.servicename.toLowerCase()
            
            // 使用转换后的名称
            sh "docker tag ${image} ${DOCKER_REGISTRY}/${lowerServiceName}/${image}"
            sh "docker push ${DOCKER_REGISTRY}/${lowerServiceName}/${image}"
        }
    }
}

stage('Kubernetes 部署') {
  steps {
    script {
      def fullImageName = "${DOCKER_REGISTRY}/${params.servicename.toLowerCase()}/${image}"
      def deploymentFile = "docker/prod/${params.servicename}.deploy.yaml"
      
      withKubeConfig([credentialsId: 'k8s_config', serverUrl: 'https://10.9.2.45:6443']) {
        sh """
          # 备份文件

          # 替换镜像
          sed -i 's|image:.*|image: ${fullImageName}|g' ${deploymentFile}
          
          # 应用部署
          kubectl apply -f ${deploymentFile}
          
          # 检查状态
          kubectl rollout status deployment/${params.servicename.toLowerCase()} -n zq-3-test --timeout=300s
          
         
        """
      }
    }
  }
}
      
      
   
   
      
       stage('更新GitOps配置') {
        steps {
            // 同样使用 withCredentials 块
            withCredentials([usernamePassword(
                credentialsId: 'gitlab-secret',
                usernameVariable: 'GIT_USERNAME',
                passwordVariable: 'GIT_PASSWORD'
            )]) {
                script {
                    // 构造带有认证信息的 GitOps 仓库 URL
                    def argoRepoUrlWithCreds = "https://${GIT_USERNAME}:${GIT_PASSWORD}@demo.git"
                    
                    echo "开始更新 GitOps 仓库"
                    
                      sh 'rm -rf gitops-repo'

                      
                    // 1. 克隆 GitOps 仓库
                    sh """
                        # 克隆时在 URL 中嵌入凭证
                        git clone --branch ${env.ARGO_REPO_BRANCH} ${argoRepoUrlWithCreds} gitops-repo
                        cd gitops-repo
                        
                        git config user.name "Jenkins CI Bot"
                        git config user.email "jenkins-bot@your-company.com"
                    """

                    // 2. 修改 kustomization.yaml (这部分逻辑不变)
                    def kustomizeFilePath = "${env.ARGO_ENV_PATH}/kustomization.yaml"
                    def newImageName = "${env.DOCKER_REGISTRY}/${params.servicename.toLowerCase()}"
                   def fullImageName = "${DOCKER_REGISTRY}/${params.servicename.toLowerCase()}/${image}"

                    sh """
                        cd gitops-repo
                        echo ${env.ARGO_ENV_PATH}
                   cd ${env.ARGO_ENV_PATH}

                                    kustomize edit set image ${params.servicename.toLowerCase()}=${fullImageName}

                    """

                    // 3. 提交并推送变更
                    sh """
                        cd gitops-repo
                        git add ${kustomizeFilePath}
                        git commit -m "ci: Update ${params.servicename} to version ${env.commit_id}"
                        # 推送时不再需要额外认证,因为 clone 时已经包含了凭证信息
                        git push origin ${env.ARGO_REPO_BRANCH}
                    """
                }
            }
        }
    }
    
    //   stage('Clean') {
    //       steps{
    //           sh 'docker rmi -f ${image}'
    //           sh 'docker rmi -f ${docker_repo}/${image}'
    //           cleanWs notFailBuild: true
    //       }
    //   }

    }
}

argocd 安装

kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

暴露服务:

kubectl port-forward svc/argocd-server -n argocd 8080:443

argo 创建项目

screenshot-20250910-095912.png

screenshot-20250910-100012.png

jenkins流水线执行完之后,将image更新完 提交到运维仓库 ,argo自动sync变更 发布服务