平台迁移【全程班】DevOps运维自动化

11 阅读3分钟

abc065a69ed54cf9987d737fed8e840e.jpeg

在教育行业数字化转型的浪潮中,技术架构的稳定性与迭代速度直接决定了教学质量与用户体验。近期,我们启动了核心教学平台的迁移计划,将旧有的单体架构应用迁移至云原生的 Kubernetes 集群中。这不仅是一次基础设施的升级,更是一次 DevOps 自动化能力的全面演练。在本次“平台迁移 DevOps 全程班”的实战复盘会上,我们沉淀了一套完整的自动化流水线方案。

本文将剥离业务细节,重点分享如何通过 Jenkins Pipeline 实现从代码提交到生产环境部署的 “一键式自动化” ,并附上核心实战代码。

一、 迁移痛点与自动化思路

平台迁移面临的最大挑战在于“新旧并存”期间的流量切换与数据一致性。传统的人工部署方式已无法满足高频回滚与灰度发布的需求。因此,我们确立了基于 GitOps 的自动化思路:

  1. 版本溯源:所有环境配置 Git化管理,拒绝手动 SSH 修改。
  2. 镜像不可变:构建即发布,通过 Tag 管理版本。
  3. 零停机迁移:利用 Kubernetes 的滚动更新机制平滑过渡。

二、 核心实战:声明式 Jenkins Pipeline

我们选择了 Jenkins 作为 CI/CD 编排引擎。为了实现“全程班”所强调的可维护性,我们采用了声明式 Pipeline,并将构建逻辑与部署逻辑解耦。

以下是一份真实可用的 Jenkinsfile 核心片段,它演示了如何自动构建 Docker 镜像、推送到私有仓库,并触发 K8s 集群更新。

groovy

复制

pipeline {
    agent any
    
    // 环境变量定义:将敏感信息存储在 Jenkins Credentials 中
    environment {
        DOCKER_REPO = 'harbor.education.com/platform'
        GIT_CREDENTIALS_ID = 'gitlab-ssh-key'
        K8S_CONFIG_ID = 'kubeconfig-prod'
        APP_NAME = 'edu-portal-v2'
    }

    stages {
        stage('代码检出') {
            steps {
                checkout([
                    $class: 'GitSCM', 
                    branches: [[name: '*/main']],
                    userRemoteConfigs: [[credentialsId: env.GIT_CREDENTIALS_ID, url: 'git@gitlab.com:edu/platform.git']]
                ])
            }
        }

        stage('代码质量扫描') {
            steps {
                echo "正在进行 SonarQube 静态代码分析..."
                // 集成 SonarQube Scanner,严控代码质量门禁
                script {
                    def scannerHome = tool 'SonarQubeScanner';
                    withSonarQubeEnv('SonarServer') {
                        sh "${scannerHome}/bin/sonar-scanner -DprojectSettings=sonar-project.properties"
                    }
                }
            }
        }

        stage('构建 & 推送镜像') {
            steps {
                script {
                    // 技巧点:使用 Git Commit ID 和构建号作为镜像 Tag,确保版本可追溯
                    def gitCommitId = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
                    def imageTag = "${BUILD_NUMBER}-${gitCommitId}"
                    def imageName = "${env.DOCKER_REPO}/${env.APP_NAME}:${imageTag}"
                    
                    echo "正在构建镜像: ${imageName}"
                    
                    // Docker Build
                    sh "docker build -t ${imageName} ."
                    
                    // Docker Login & Push
                    withCredentials([usernamePassword(credentialsId: 'harbor-auth', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
                        sh "docker login -u ${DOCKER_USER} -p${DOCKER_PASS} ${env.DOCKER_REPO}"
                        sh "docker push ${imageName}"
                    }
                    
                    // 将关键信息写入环境变量供后续阶段使用
                    env.IMAGE_NAME = imageName
                }
            }
        }

        stage('部署到 K8s 集群') {
            steps {
                script {
                    echo "正在更新 K8s Deployment: ${env.APP_NAME}"
                    
                    // 技巧点:使用 kubectl set image 直接触发滚动更新,无需维护复杂的 YAML 模板文件
                    withCredentials([file(credentialsId: env.K8S_CONFIG_ID, variable: 'KUBECONFIG')]) {
                        sh """
                            export KUBECONFIG=${KUBECONFIG}
                            # 更新镜像
                            kubectl set image deployment/${env.APP_NAME}${env.APP_NAME}=${env.IMAGE_NAME} -n production
                            
                            # 等待滚动更新完成,确保 Pod Ready
                            kubectl rollout status deployment/${env.APP_NAME} -n production --timeout=300s
                        """
                    }
                }
            }
        }
    }

    post {
        success {
            echo "部署成功!镜像: ${env.IMAGE_NAME}"
            // 可集成钉钉/飞书机器人发送通知
        }
        failure {
            echo "部署失败,请检查日志!"
            // 自动回滚逻辑可以在此添加
        }
    }
}

三、 迁移实战心得:稳字当头

在本次全程班的实战演练中,我们总结了三条宝贵的迁移经验:

  1. 蓝绿部署的必要性:在教育平台高峰期(如选课、考试期间),稳定性压倒一切。我们在 K8s 中配置了两个 Service,通过 Ingress 切换流量,确保新版本出现 Bug 时能毫秒级回滚。
  2. 配置文件分离:坚决反对将 application-prod.yml 打包进 Docker 镜像。实战中,我们使用 K8s 的 ConfigMap 和 Secret 挂载配置,实现了“镜像一次构建,多环境通用”。
  3. 自动化测试左移:在 Pipeline 的早期阶段集成接口自动化测试。一旦测试未通过,直接阻断流水线,避免将有缺陷的镜像推向生产环境。

结语

教育技术的深耕,离不开底层架构的坚实支撑。通过本次 DevOps 全程班的自动化实战分享,我们证明了:平台迁移不是一场“大爆炸”式的重构,而是一次通过高度自动化流水线驱动、可拆解、可回滚的精密工程。  掌握这套代码与方法论,将赋予每一位技术团队驾驭复杂变革的底气。