Jenkins流水线实践
Jenkins流水线实践
Jenkins Pipeline简介
Pipeline是Jenkins的核心功能,允许定义代码化的构建、测试和部署流程。
安装Jenkins
# Docker方式
docker run -d --name jenkins \
-p 8080:8080 -p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts
Pipeline语法
声明式Pipeline
pipeline {
agent any
environment {
APP_NAME = 'myapp'
DOCKER_REGISTRY = 'registry.example.com'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh 'npm install'
sh 'npm run build'
}
}
stage('Test') {
steps {
sh 'npm test'
}
post {
always {
junit 'test-results/**/*.xml'
}
}
}
stage('Docker Build') {
steps {
script {
docker.build("${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}")
}
}
}
stage('Push Image') {
steps {
script {
docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-credentials') {
docker.image("${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}").push()
}
}
}
}
stage('Deploy') {
steps {
sh "kubectl set image deployment/${APP_NAME} ${APP_NAME}=${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}"
}
}
}
post {
always {
cleanWs()
}
success {
echo 'Build succeeded!'
}
failure {
echo 'Build failed!'
}
}
}
脚本式Pipeline
node {
stage('Checkout') {
checkout scm
}
stage('Build') {
sh 'npm install'
sh 'npm run build'
}
stage('Test') {
sh 'npm test'
}
stage('Deploy') {
if (env.BRANCH_NAME == 'main') {
sh 'kubectl apply -f k8s/'
}
}
}
常用步骤
文件操作
// 读取文件
def config = readYaml file: 'config.yml'
// 写入文件
writeFile file: 'output.txt', text: 'Hello'
// 归档制品
archiveArtifacts artifacts: 'dist/**', fingerprint: true
// 存储测试结果
junit 'test-results/**/*.xml'
Docker操作
// 构建镜像
docker.build('myapp:latest')
// 运行容器
docker.image('myapp:latest').inside('-p 8080:8080') {
sh 'npm test'
}
// 推送镜像
docker.withRegistry('https://registry.example.com', 'credentials-id') {
docker.image('myapp:latest').push()
}
通知
// 邮件通知
emailext body: 'Build completed', subject: "Build ${currentBuild.currentResult}", to: 'team@example.com'
// Slack通知
slackSend channel: '#devops', message: "Build ${currentBuild.currentResult}: ${env.JOB_NAME}"
实践:完整CI/CD Pipeline
// Jenkinsfile
pipeline {
agent any
tools {
nodejs 'node-18'
}
environment {
APP_NAME = 'webapp'
REGISTRY = 'registry.example.com'
KUBECONFIG = credentials('kubeconfig')
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install Dependencies') {
steps {
sh 'npm ci'
}
}
stage('Lint') {
steps {
sh 'npm run lint'
}
}
stage('Unit Test') {
steps {
sh 'npm test -- --coverage'
}
post {
always {
junit 'coverage/junit.xml'
publishHTML([
reportDir: 'coverage/lcov-report',
reportFiles: 'index.html',
reportName: 'Coverage Report'
])
}
}
}
stage('Build') {
steps {
sh 'npm run build'
}
}
stage('Docker Build & Push') {
when {
branch 'main'
}
steps {
script {
docker.withRegistry("https://${REGISTRY}", 'docker-creds') {
def image = docker.build("${REGISTRY}/${APP_NAME}:${env.GIT_COMMIT.take(7)}")
image.push()
image.push('latest')
}
}
}
}
stage('Deploy to Staging') {
when {
branch 'main'
}
steps {
sh """
kubectl set image deployment/${APP_NAME} \
${APP_NAME}=${REGISTRY}/${APP_NAME}:${env.GIT_COMMIT.take(7)} \
--namespace=staging
"""
}
}
stage('Deploy to Production') {
when {
branch 'main'
}
input {
message 'Deploy to production?'
ok 'Deploy'
}
steps {
sh """
kubectl set image deployment/${APP_NAME} \
${APP_NAME}=${REGISTRY}/${APP_NAME}:${env.GIT_COMMIT.take(7)} \
--namespace=production
"""
}
}
}
post {
always {
cleanWs()
}
success {
slackSend color: 'good', message: "Build succeeded: ${env.JOB_NAME}"
}
failure {
slackSend color: 'danger', message: "Build failed: ${env.JOB_NAME}"
}
}
}
总结
Jenkins Pipeline是实现CI/CD的核心工具。通过Pipeline as Code,可以版本化管理构建流程,实现可重复、可审计的自动化构建。