🚀 一、CI/CD 基础理论

1. 持续集成(CI,Continuous Integration)

目标:频繁(每天多次)地集成代码,发现问题尽早修复
  • 每次提交代码自动触发构建流程
  • 自动执行单元测试、构建镜像等
  • 发现问题及时反馈给开发者

2. 持续交付(CD,Continuous Delivery)

目标:构建完成后自动部署到类生产环境,确保可发布
  • 镜像推送至 Harbor
  • 自动部署到 Kubernetes 测试环境
  • 手动审核部署到生产

3. 持续部署(Continuous Deployment)

目标:构建完成后自动部署到生产环境
  • 与持续交付相比,多了“自动化发布”这一步
  • 风险较大,需保障测试和回滚机制完善

image.png

🧱 二、平台组件角色与协作关系

组件角色描述
GitLab代码管理、Webhook 触发 CI 流水线
Jenkins流水线核心引擎,构建、测试、打包、部署的控制中心
Docker用于构建应用容器镜像
Harbor私有镜像仓库,用于保存构建好的镜像
Kubernetes应用运行环境,完成容器调度、伸缩、滚动更新等部署工作

🔄 三、典型工作流程(理论视角)

1. 开发者提交代码(Push)

  • GitLab 接收到 Push 请求
  • 触发 Webhook,通知 Jenkins 进行 CI 构建

2. Jenkins CI 流水线执行

  • 拉取代码
  • 单元测试(可选)
  • 生成 Docker 镜像
  • 推送镜像到 Harbor
  • 更新 K8s 部署(例如修改 Deployment 的镜像版本)

3. Kubernetes 执行部署

  • 拉取 Harbor 中的镜像
  • 滚动更新 Deployment
  • 实现无缝部署

🚀 CI/CD 流程描述

客户机开发者使用本地 IDE 进行持续编码,仅需手动执行一次代码提交(git push),之后的所有操作均自动完成,流程如下:

  1. 代码提交

    • 开发者将代码通过本地 IDE push 到 GitLab 仓库。
  2. 触发构建

    • GitLab 通过 WebHook 通知 Jenkins,自动触发对应的构建任务。
  3. 拉取源码

    • Jenkins 使用 Shell 脚本从 GitLab 仓库拉取最新的应用源代码和 Dockerfile 文件。
  4. 构建镜像

    • Jenkins 基于拉取的源码和 Dockerfile 构建 Docker 镜像。
  5. 推送镜像

    • 构建完成的镜像被推送至 Harbor 私有镜像仓库中。
  6. 部署到集群

    • Jenkins 通过 kubectl 命令行工具(或 kubelet 客户端)通知 Kubernetes 集群拉取 Harbor 中的镜像,并更新对应 Deployment。
    • 默认使用 滚动更新(Rolling Update)策略,无缝替换旧版本容器。

整个流程中,除了开发者手动提交代码,其余步骤均实现自动化,确保持续集成与持续部署高效闭环。

四、架构规划

Node IP部署服务备注
100.100.157.10(master01)Ingress-nginxk8s-统一入口
100.100.157.11(work01)SpringBoot、harbor后端项目
100.100.157.12(work02)vue前端项目
100.100.157.13(cicd)jenkins、gitlab、maven、jdk、nodejs、docker数据库/镜像仓库
这里基础组件部署就不过多赘述了,请参考其他文章。

五、gitlab项目demo准备

1.gitlab创建前后端项目,并创建master/devops分支(用于模拟正式环境/开发环境发布流程)

image.png

2.推送代码至gitlab(master/devops分支)

gitlab git url:

前端:http://100.100.157.13:9090/cicd-xhy/front-end-demo.git

后端:http://100.100.157.13:9090/cicd-xhy/back-end-demo.git

后端项目如下:

image.png

前端项目如下:

image.png

六、jenkins环境配置

1.jenkins基础全局配置

Dashdoard——manage-jenkins——System

  • Jenkins Location:Jenkins URL

Dashdoard——manage-jenkins——Tools

  • git、maven、node.js(可选,也可以在流水线中配置)

Dashdoard——manage-jenkins——credentials

  • 配置凭证

image.png

七、cicd java项目

1、准备

  • 将dockerfile上传至gitlab项目中,用于构建镜像

    image.png

2.新建ltem

  • 输入任务名称(自定义)
  • 选择pipeline
  • 流水线-定义-pipeline script
    流水线配置
properties([
    parameters([
        string(name: 'BRANCH', defaultValue: 'master', description: '请输入要构建的 Git 分支')
    ])
])

node {
    def harborUser = 'hxy'
    def harborPasswd = 'Hxy1224...'
    def harborAddress = '100.100.157.10:5000'
    def harborRepo = 'k8s'
    def JAVA_HOME = '/usr/java/jdk1.8.0_131'
    def dingTalkWebhook = 'https://oapi.dingtalk.com/robot/send?access_token=25508193433dbe82f8761fb5e63396a0c43188d398040a7d4a484184eeeb7ceb'
    def imageTag = ""
    def buildSuccess = false

    catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
        stage('拉取Git代码') {
            checkout scmGit(
                branches: [[name: "*/${params.BRANCH}"]],
                extensions: [],
                userRemoteConfigs: [[
                    credentialsId: 'gitlab',
                    url: 'http://100.100.157.13:9090/cicd-xhy/back-end-demo.git'
                ]]
            )
        }

        stage('构建代码') {
            env.JAVA_HOME = JAVA_HOME
            env.PATH = "${JAVA_HOME}/bin:${env.PATH}"
            sh '''
              export JAVA_HOME=/usr/java/jdk1.8.0_131
              export PATH=$JAVA_HOME/bin:$PATH
              /root/hxy/packages/jenkins/mvm/apache-maven-3.9.9/bin/mvn clean package -DskipTests
            '''
        }

        stage('制作镜像并推送 Harbor') {
            def timestamp = new Date().format("yyyy-MM-dd-HH-mm", TimeZone.getTimeZone("Asia/Shanghai"))
            imageTag = timestamp
            def imageFullPath = "${harborAddress}/${harborRepo}/${env.JOB_NAME}:${imageTag}"
            env.IMAGE_TAG = imageTag

            sh """
              mv target/*jar docker/
              docker build -t ${imageFullPath} docker/
              docker image prune -f
              docker login -u ${harborUser} -p ${harborPasswd} ${harborAddress}
              docker push ${imageFullPath}
            """
        }

        stage('更新K8s YAML并部署') {
            def newImage = "${harborAddress}/${harborRepo}/${env.JOB_NAME}:${imageTag}"
            sh """
              ssh root@100.100.157.10 "sudo sed -i 's|image: .*|image: ${newImage}|' /root/hxy/packages/k8s-demo/java/backend.yaml"
              ssh root@100.100.157.10 kubectl delete -f /root/hxy/packages/k8s-demo/java/backend.yaml || true
              ssh root@100.100.157.10 kubectl apply -f /root/hxy/packages/k8s-demo/java/backend.yaml
            """
        }

        buildSuccess = true
    }

    // ✅ 无论构建成功或失败都执行
    def emoji = buildSuccess ? "✅" : "❌"
    def msg = buildSuccess ? "构建成功" : "构建失败"
    sendDingTalkText(emoji, msg, imageTag, dingTalkWebhook, harborAddress, harborRepo)
}

// 发送钉钉通知函数
def sendDingTalkText(String statusEmoji, String resultDesc, String imageTag, String webhook, String harborAddress, String harborRepo) {
    def jobName = env.JOB_NAME
    def buildNumber = env.BUILD_NUMBER
    def tag = imageTag ?: "N/A"
    def buildTime = new Date().format("yyyy-MM-dd HH:mm", TimeZone.getTimeZone("Asia/Shanghai"))
    def imageFullPath = "${harborAddress}/${harborRepo}/${jobName}:${tag}"
    def buildUrl = env.BUILD_URL ?: "http://your-jenkins-url/job/${jobName}/${buildNumber}/"

    def rawText = """cicd-发版通知
构建状态:${statusEmoji} ${resultDesc}
应用名称:${jobName}
应用版本:${tag}
构建时间:${buildTime}
构建镜像:${imageFullPath}
构建链接:${buildUrl}
备注:请各研发运维同学观察版本上线验证 ✅"""

    def payload = """{
        "msgtype": "text",
        "text": {
            "content": "${rawText}"
        }
    }"""

    sh """
        curl '${webhook}' \
        -H 'Content-Type: application/json' \
        -d '${payload}'
    """
}
  • this project is parameterized(配置动态分支选择)

    image.png

  • 运行流水线

    image.png

正文到此结束
最后修改:2025 年 06 月 05 日
如果觉得我的文章对你有用,请随意赞赏