精通 Jenkins:从 Pipeline 新手到 DevOps 英雄 🎭

发布: (2025年12月3日 GMT+8 09:43)
6 min read
原文: Dev.to

Source: Dev.to

引言

欢迎来到 正式 CI/CD 流水线 之前的世界——一个黑暗的地方,开发者像数字牛仔一样手动部署代码,祈祷他们的改动不会在用户面前炸开。

登场的是 Jenkins——你全新的数字管家,兼具天才与混沌的特质。最初叫 Hudson(直到 Oracle 的律师闹翻了局),Jenkins 自 2011 年起就开始自动化开发者的生活。趣闻:Jenkins 的吉祥物实际上就是一位名叫 “Jenkins” 的管家。

今天,我们将把你从流水线新手培养成 CI/CD 骑士,配备自动化测试盔甲和部署超能力。

1. Jenkins 101:认识你的新数字管家 🤖

好的、坏的以及蓝球

Jenkins 对彩色小球有一种古怪的执念:

  • 绿色 表示成功。
  • 蓝色 也表示成功(情况有点复杂)。
  • 红色 表示 “该更新你的简历了”。

Jenkins 社区曾就蓝色与绿色指示灯展开激烈争论。

Jenkins 生存套件

pipeline {
    agent any

    stages {
        stage('Hello World') {
            steps {
                echo 'Welcome to Jenkins, brave soul!'
                script {
                    def courage = "maximum"
                    echo "Setting courage level to: ${courage}"
                }
            }
        }
    }
}

鲜为人知的事实:Jenkins 拥有超过 1,800 个插件——比瑞士军刀工厂的种类还要多!想要集成 Slack?有插件。需要部署到火星?可能也有插件(好吧,也许还没有火星…但以后会有)。

安装:召唤仪式

# Docker 方式(适合智者)
docker run -p 8080:8080 -p 50000:50000 jenkins/jenkins:lts

# 传统方式(适合勇者)
sudo apt update
sudo apt install openjdk-11-jdk
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb https://pkg.jenkins.io/debian binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt update && sudo apt install jenkins

专业提示:Jenkins 会用一个隐藏在深层文件中的 管理员密码 向你问好。 🗝️

2. 流水线架构:为代码的生产之路铺设高速公路 🛣️

阶段:装配线工人

把流水线阶段想象成装配线工人,每个人都有自己的性格:

  • Build Bob —— 编译你的代码并抱怨缺少依赖。
  • Test Terry —— 以咖啡因充沛的 QA 工程师的热情运行测试。
  • Deploy Diana —— 将你的代码送往生产(成功率各不相同)。

示例流水线

pipeline {
    agent any

    environment {
        DOCKER_IMAGE = "myapp:${env.BUILD_NUMBER}"
        DEPLOY_ENV = "staging"
    }

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/yourcompany/awesome-app.git'
            }
        }

        stage('Build & Test') {
            parallel {
                stage('Build') {
                    steps {
                        sh 'mvn clean compile'
                        echo "Build completed! Bob is happy! 😊"
                    }
                }
                stage('Unit Tests') {
                    steps {
                        sh 'mvn test'
                        publishTestResults testResultsPattern: 'target/test-reports/*.xml'
                    }
                    post {
                        always {
                            echo "Terry finished testing (with varying degrees of success)"
                        }
                    }
                }
                stage('Security Scan') {
                    steps {
                        sh 'mvn dependency-check:check'
                        echo "Security scan complete - no known vulnerabilities found! 🔒"
                    }
                }
            }
        }
    }
}

令人惊叹的事实并行执行 能将构建时间缩短 60 % 以上——这就像同时拥有多条装配线。

Jenkinsfile:你的流水线 DNA

Jenkinsfile 是流水线的基因代码。把它存放在代码库中,并把它当作 Pipeline‑as‑Code(代码即流水线),它是 Infrastructure‑as‑Code(基础设施即代码)的更酷表亲。

3. 从零到英雄:真实世界的流水线实现 🦸‍♂️

完整流水线:现代杰作

pipeline {
    agent any

    environment {
        DOCKER_REGISTRY = "your-registry.com"
        APP_NAME = "awesome-app"
        STAGING_SERVER = "staging.awesome-app.com"
        PRODUCTION_SERVER = "awesome-app.com"
    }

    stages {
        stage('Preparation') {
            steps {
                cleanWs()
                git branch: "${BRANCH_NAME}", url: 'https://github.com/yourcompany/awesome-app.git'
                script {
                    env.BUILD_VERSION = "${env.BUILD_NUMBER}-${env.GIT_COMMIT.take(7)}"
                }
            }
        }

        stage('Build & Quality Gates') {
            parallel {
                stage('Application Build') {
                    steps {
                        sh 'mvn clean package -DskipTests'
                        archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
                    }
                }
                stage('Code Quality') {
                    steps {
                        sh 'mvn sonar:sonar'
                        echo "SonarQube analysis complete - code quality checked! ✨"
                    }
                }
                stage('Dependency Audit') {
                    steps {
                        sh 'mvn dependency-check:check'
                        publishHTML([
                            allowMissing: false,
                            alwaysLinkToLastBuild: true,
                            keepAll: true,
                            reportDir: 'target',
                            reportFiles: 'dependency-check-report.html',
                            reportName: 'Dependency Check Report'
                        ])
                    }
                }
            }
        }

        stage('Testing Symphony') {
            parallel {
                stage('Unit Tests') {
                    steps {
                        sh 'mvn test'
                        publishTestResults testResultsPattern: 'target/test-reports/*.xml'
                    }
                }
                stage('Integration Tests') {
                    steps {
                        sh 'mvn integration-test'
                        echo "Integration tests passed - components are playing nice! 🤝"
                    }
                }
                stage('API Tests') {
                    steps {
                        sh 'npm install && npm run api-tests'
                        publishTestResults testResultsPattern: 'api-test-results.xml'
                    }
                }
            }
        }

        stage('Containerization') {
            steps {
                script {
                    def image = docker.build("${env.DOCKER_REGISTRY}/${env.APP_NAME}:${env.BUILD_VERSION}")
                    docker.withRegistry("https://${env.DOCKER_REGISTRY}", 'docker-registry-credentials') {
                        image.push()
                        image.push('latest')
                    }
                    echo "Docker image ${image.id} pushed to ${env.DOCKER_REGISTRY}"
                }
            }
        }

        stage('Deploy to Staging') {
            steps {
                sh """
                ssh user@${STAGING_SERVER} '
                    docker pull ${env.DOCKER_REGISTRY}/${env.APP_NAME}:${env.BUILD_VERSION}
                    docker run -d --rm -p 8080:8080 ${env.DOCKER_REGISTRY}/${env.APP_NAME}:${env.BUILD_VERSION}
                '
                """
                echo "Deployed ${APP_NAME} to staging."
            }
        }

        stage('Approval') {
            steps {
                input message: 'Promote to production?', ok: 'Deploy'
            }
        }

        stage('Deploy to Production') {
            steps {
                sh """
                ssh user@${PRODUCTION_SERVER} '
                    docker pull ${env.DOCKER_REGISTRY}/${env.APP_NAME}:${env.BUILD_VERSION}
                    docker run -d --rm -p 80:8080 ${env.DOCKER_REGISTRY}/${env.APP_NAME}:${env.BUILD_VERSION}
                '
                """
                echo "Deployed ${APP_NAME} to production."
            }
        }
    }

    post {
        always {
            cleanWs()
            echo 'Workspace cleaned.'
        }
        success {
            mail to: 'team@example.com',
                 subject: "✅ Successful build ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                 body: "Great job! The pipeline completed successfully."
        }
        failure {
            mail to: 'team@example.com',
                 subject: "❌ Failed build ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                 body: "Something went wrong. Check the Jenkins console for details."
        }
    }
}

此流水线演示了:

  • 并行阶段 用于更快的反馈。
  • 使用 SonarQube 的 代码质量 检查。
  • 依赖审计 与 HTML 报告。
  • 使用 Docker 的 容器化,包括将镜像推送到私有仓库。
  • 预发布部署、手动批准以及 生产部署
  • 构建后操作 用于清理和通知。
Back to Blog

相关文章

阅读更多 »

Jenkins 在 AWS + Docker

Jenkins 在 AWS + Docker 的封面图片 https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-upload...