CentOS 下基于 Jenkins 的蓝绿部署落地方案
一 架构与前置条件
架构要点:准备两套完全一致的生产环境,分别为Blue/Green;通过一个负载均衡器(Nginx/HAProxy/硬件LB)统一入口;上线时先部署非活跃色,完成健康检查后一次性切换流量,异常则立即切回,实现快速回滚与用户无感。蓝绿部署的优势是切换/回滚快、验证充分;代价是需要约两倍资源并在切换窗口内存在资源闲置。
基础环境(CentOS 7/8 建议):
二 方案一 非容器化实现 Nginx 手动切换
目录与版本管理约定(两台目标机分别属于 Blue/Green):
Nginx 负载均衡配置要点(示例):
upstream backend {
server 10.0.0.11:8080 max_fails=2 fail_timeout=30s;
server 10.0.0.12:8081 max_fails=2 fail_timeout=30s;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
health_check interval=10 uri=/health fails=2 passes=2;
}
}
Jenkins 关键步骤与脚本(Freestyle 或 Pipeline 均可):
#!/usr/bin/env bash
set -e
COLOR=$1; BUILD_ID=$2
APP_DIR=/opt/app
VERSION_DIR=$APP_DIR/$COLOR
CURRENT_LINK=$APP_DIR/current
# 1) 停止目标色实例(避免文件占用)
if systemctl is-active --quiet tomcat; then
systemctl stop tomcat || true
fi
# 2) 部署新版本
rm -rf $VERSION_DIR/*
cp -r $WORKSPACE/target/*.war $VERSION_DIR/app.war
# 如有需要可执行数据库迁移(务必可回滚)
# 3) 启动目标色实例
systemctl start tomcat
sleep 10
# 4) 健康检查(示例)
for i in {1..30}; do
if curl -sf http://localhost:8080/health; then
echo "Health check OK"; break
fi
sleep 5
done
# 5) 原子切换 current 链接(避免并发写)
ln -sfn $VERSION_DIR $CURRENT_LINK
nginx -s reload。三 方案二 容器化实现 Kubernetes 一键切换
# Deployment: myapp-green
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-green
labels: {app: myapp, version: green}
spec:
replicas: 3
selector: {matchLabels: {app: myapp, version: green}}
template:
metadata: {labels: {app: myapp, version: green}}
spec:
containers:
- name: app
image: harbor.example.com/ns/myapp:${GIT_COMMIT}
ports: [{containerPort: 8080}]
readinessProbe:
httpGet: {path: /health, port: 8080}
initialDelaySeconds: 10
periodSeconds: 5
livenessProbe:
httpGet: {path: /health, port: 8080}
initialDelaySeconds: 20
periodSeconds: 10
# Service: myapp(统一入口)
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector: {app: myapp, version: blue} # 初始指向 blue
ports: [{protocol: TCP, port: 80, targetPort: 8080}]
pipeline {
agent any
environment {
IMAGE = "harbor.example.com/ns/myapp:${env.GIT_COMMIT}"
K8S_NS = "prod"
}
stages {
stage('Build & Push') {
steps {
sh 'docker build -t $IMAGE .'
sh 'docker push $IMAGE'
}
}
stage('Deploy Green') {
steps {
script {
sh """
kubectl -n $K8S_NS apply -f k8s/deploy-green.yaml
kubectl -n $K8S_NS rollout status deploy/myapp-green --timeout=300s
"""
}
}
}
stage('Switch Traffic') {
steps {
script {
// 原子切换:将 Service selector 指向 green
sh """
kubectl -n $K8S_NS patch svc myapp \
-p '{"spec":{"selector":{"app":"myapp","version":"green"}}}'
"""
// 可选:观察一段时间后再清理 blue
// sh "kubectl -n $K8S_NS delete deploy myapp-blue"
}
}
}
}
post {
failure {
script {
// 回滚:切回 blue
sh """
kubectl -n $K8S_NS patch svc myapp \
-p '{"spec":{"selector":{"app":"myapp","version":"blue"}}}'
"""
}
}
}
}
四 健康检查 回滚与风险控制