1. 安装Docker环境
#!/bin/bash
# Docker安装脚本
set -e
echo"=== 开始安装Docker ==="
# 卸载旧版本
sudo yum remove -y docker docker-client docker-client-latest \
docker-common docker-latest docker-latest-logrotate \
docker-logrotate docker-engine
# 安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加Docker仓库
sudo yum-config-manager --add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
# 配置Docker镜像加速和日志
sudomkdir -p /etc/docker
sudotee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://registry.docker-cn.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2",
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
# 启动Docker
sudo systemctl daemon-reload
sudo systemctl enable docker
sudo systemctl start docker
# 验证安装
docker --version
docker info
echo"=== Docker安装完成 ==="
2.部署GitLab代码仓库
#!/bin/bash
# GitLab安装脚本
set -e
GITLAB_HOME="/data/gitlab"
GITLAB_HOSTNAME="reg.cx.test.com"
echo"=== 开始安装GitLab ==="
# 创建数据目录
sudomkdir -p ${GITLAB_HOME}/{config,logs,data}
# 运行GitLab容器
docker run -d \
--hostname ${GITLAB_HOSTNAME} \
--name gitlab \
--restart always \
--publish 443:443 \
--publish 80:80 \
--publish 22:22 \
--volume ${GITLAB_HOME}/config:/etc/gitlab \
--volume ${GITLAB_HOME}/logs:/var/log/gitlab \
--volume ${GITLAB_HOME}/data:/var/opt/gitlab \
--shm-size 256m \
gitlab/gitlab-ce:latest
echo"=== GitLab正在启动,需要3-5分钟 ==="
echo"等待GitLab启动..."
# 等待GitLab启动
for i in {1..30}; do
if docker logs gitlab 2>&1 | grep -q "gitlab Reconfigured"; then
echo"GitLab启动成功!"
break
fi
echo"等待中... ($i/30)"
sleep 10
done
# 获取初始密码
echo""
echo"=== GitLab初始管理员密码 ==="
docker exec gitlab cat /etc/gitlab/initial_root_password | grep Password:
echo""
echo"访问地址: http://${GITLAB_HOSTNAME}"
echo"管理员账号: root"
echo"请保存上面的初始密码,24小时后将自动删除"
3.部署Harbor镜像仓库
#!/bin/bash
# Harbor安装脚本
set -e
HARBOR_VERSION="v2.11.0"
HARBOR_DOMAIN="harbor.company.com"# 修改为你的域名
HARBOR_ADMIN_PASSWORD="Harbor123456"# 修改管理员密码
echo"=== 开始安装Harbor ==="
# 安装docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
sudochmod +x /usr/local/bin/docker-compose
# 下载Harbor
cd /opt
wget https://github.com/goharbor/harbor/releases/download/${HARBOR_VERSION}/harbor-offline-installer-${HARBOR_VERSION}.tgz
tar xzvf harbor-offline-installer-${HARBOR_VERSION}.tgz
cd harbor
# 配置Harbor
cp harbor.yml.tmpl harbor.yml
sed -i "s/hostname: reg.mydomain.com/hostname: ${HARBOR_DOMAIN}/g" harbor.yml
sed -i "s/harbor_admin_password: Harbor12345/harbor_admin_password: ${HARBOR_ADMIN_PASSWORD}/g" harbor.yml
# 禁用HTTPS(测试环境,生产建议启用)
sed -i '/^https:/,+8 s/^/#/' harbor.yml
# 安装Harbor
sudo ./install.sh
echo"=== Harbor安装完成 ==="
echo"访问地址: http://${HARBOR_DOMAIN}"
echo"管理员账号: admin"
echo"管理员密码: ${HARBOR_ADMIN_PASSWORD}"
4.部署Jenkins CI/CD引擎
#!/bin/bash
# Jenkins安装脚本
set -e
JENKINS_HOME="/data/jenkins"
echo"=== 开始安装Jenkins ==="
# 创建数据目录
sudomkdir -p ${JENKINS_HOME}
sudochown -R 1000:1000 ${JENKINS_HOME}
# 运行Jenkins容器
docker run -d \
--name jenkins \
--restart always \
--user root \
-p 8080:8080 \
-p 50000:50000 \
-v ${JENKINS_HOME}:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
jenkins/jenkins:lts
echo"=== 等待Jenkins启动(约2分钟) ==="
sleep 120
# 获取初始密码
echo""
echo"=== Jenkins初始管理员密码 ==="
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
echo""
echo"访问地址: http://YOUR_IP:8080"
echo"请使用上面的密码登录并完成初始化配置"
5.Jenkins Pipeline参考
// Jenkinsfile - 企业级流水线脚本
pipeline {
agent any
environment {
// 项目配置
PROJECT_NAME = 'demo-app'
GIT_REPO = 'http://gitlab.company.com/dev/demo-app.git'
GIT_CREDENTIALS = 'gitlab-credentials'
// Harbor镜像仓库
HARBOR_URL = 'harbor.company.com'
HARBOR_PROJECT = 'production'
HARBOR_CREDENTIALS = 'harbor-credentials'
IMAGE_NAME = "${HARBOR_URL}/${HARBOR_PROJECT}/${PROJECT_NAME}"
// Kubernetes配置
K8S_NAMESPACE_TEST = 'test'
K8S_NAMESPACE_PROD = 'production'
K8S_CREDENTIALS = 'k8s-credentials'
// SonarQube
SONAR_URL = 'http://sonarqube.company.com'
// 构建信息
BUILD_TAG = "${env.BUILD_NUMBER}-${env.GIT_COMMIT?.take(8)}"
}
stages {
stage('代码检出') {
steps {
script {
echo "=== 从GitLab检出代码 ==="
git branch:'master',
credentialsId:"${GIT_CREDENTIALS}",
url:"${GIT_REPO}"
// 获取Git提交信息
env.GIT_COMMIT_MSG = sh(
script:'git log -1 --pretty=%B',
returnStdout:true
).trim()
env.GIT_AUTHOR = sh(
script:'git log -1 --pretty=%an',
returnStdout:true
).trim()
}
}
}
stage('代码扫描') {
steps {
script {
echo "=== 执行SonarQube代码扫描 ==="
withSonarQubeEnv('SonarQube') {
sh """
sonar-scanner \
-Dsonar.projectKey=${PROJECT_NAME} \
-Dsonar.sources=. \
-Dsonar.host.url=${SONAR_URL} \
-Dsonar.login=${SONAR_TOKEN}
"""
}
}
}
}
stage('质量门禁') {
steps {
script {
echo "=== 等待SonarQube质量门禁结果 ==="
timeout(time:5, unit:'MINUTES') {
def qg = waitForQualityGate()
if (qg.status != 'OK') {
error "代码质量不达标: ${qg.status}"
}
}
}
}
}
stage('单元测试') {
steps {
script {
echo "=== 执行单元测试 ==="
sh """
# 以Java项目为例
mvn clean test
# 或Node.js项目
# npm test
# 或Python项目
# pytest --cov=./ --cov-report=xml
"""
}
}
post {
always {
// 发布测试报告
junit '**/target/surefire-reports/*.xml'
}
}
}
stage('编译构建') {
steps {
script {
echo "=== 编译项目代码 ==="
sh """
# Java项目
mvn clean package -DskipTests
# 或Node.js项目
# npm run build
# 或Go项目
# go build -o app main.go
"""
}
}
}
stage('构建镜像') {
steps {
script {
echo "=== 构建Docker镜像 ==="
// 创建Dockerfile(如果项目中没有)
sh """
cat > Dockerfile <<'EOF'
FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
EOF
"""
// 构建镜像
docker.build("${IMAGE_NAME}:${BUILD_TAG}")
docker.build("${IMAGE_NAME}:latest")
}
}
}
stage('推送镜像') {
steps {
script {
echo "=== 推送镜像到Harbor ==="
docker.withRegistry("http://${HARBOR_URL}", "${HARBOR_CREDENTIALS}") {
docker.image("${IMAGE_NAME}:${BUILD_TAG}").push()
docker.image("${IMAGE_NAME}:latest").push()
}
}
}
}
stage('部署到测试环境') {
steps {
script {
echo "=== 部署到Kubernetes测试环境 ==="
withKubeConfig([credentialsId:"${K8S_CREDENTIALS}"]) {
sh """
kubectl set image deployment/${PROJECT_NAME} \
${PROJECT_NAME}=${IMAGE_NAME}:${BUILD_TAG} \
-n ${K8S_NAMESPACE_TEST}
# 等待部署完成
kubectl rollout status deployment/${PROJECT_NAME} \
-n ${K8S_NAMESPACE_TEST} \
--timeout=5m
"""
}
}
}
}
stage('自动化测试') {
steps {
script {
echo "=== 执行接口自动化测试 ==="
sh """
# 等待服务就绪
sleep 30
# 执行自动化测试
# newman run tests/api-tests.json
# 或使用pytest
# pytest tests/integration/
echo "自动化测试通过"
"""
}
}
}
stage('人工审批') {
when {
branch 'master'
}
steps {
script {
echo "=== 等待人工审批发布到生产环境 ==="
def userInput = input(
id:'userInput',
message:'是否发布到生产环境?',
parameters: [
booleanParam(
defaultValue:false,
description:'确认发布',
name:'DEPLOY_TO_PROD'
)
]
)
if (!userInput) {
error "用户取消了生产环境发布"
}
}
}
}
stage('部署到生产环境') {
when {
branch 'master'
}
steps {
script {
echo "=== 部署到Kubernetes生产环境 ==="
withKubeConfig([credentialsId:"${K8S_CREDENTIALS}"]) {
sh """
# 记录发布信息
kubectl annotate deployment/${PROJECT_NAME} \
kubernetes.io/change-cause="Build ${BUILD_TAG} by ${GIT_AUTHOR}: ${GIT_COMMIT_MSG}" \
-n ${K8S_NAMESPACE_PROD}
# 更新镜像
kubectl set image deployment/${PROJECT_NAME} \
${PROJECT_NAME}=${IMAGE_NAME}:${BUILD_TAG} \
-n ${K8S_NAMESPACE_PROD}
# 等待部署完成
kubectl rollout status deployment/${PROJECT_NAME} \
-n ${K8S_NAMESPACE_PROD} \
--timeout=10m
"""
}
}
}
}
stage('健康检查') {
when {
branch 'master'
}
steps {
script {
echo "=== 生产环境健康检查 ==="
sh """
# 获取服务地址
SERVICE_URL=\$(kubectl get svc ${PROJECT_NAME} \
-n ${K8S_NAMESPACE_PROD} \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')
# 健康检查
for i in {1..10}; do
HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" http://\${SERVICE_URL}/health)
if [ "\${HTTP_CODE}" == "200" ]; then
echo "健康检查通过"
exit 0
fi
echo "等待服务就绪... (\$i/10)"
sleep 10
done
echo "健康检查失败,准备回滚"
exit 1
"""
}
}
}
}
post {
success {
script {
echo "=== 流水线执行成功 ==="
// 发送通知(钉钉/企业微信/邮件)
sh """
curl -X POST 'https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "markdown",
"markdown": {
"title": "发布成功",
"text": "### ${PROJECT_NAME} 发布成功\\n\\n- 构建编号: ${BUILD_NUMBER}\\n- 镜像版本: ${BUILD_TAG}\\n- 提交人: ${GIT_AUTHOR}\\n- 提交信息: ${GIT_COMMIT_MSG}"
}
}'
"""
}
}
failure {
script {
echo "=== 流水线执行失败 ==="
// 自动回滚
withKubeConfig([credentialsId:"${K8S_CREDENTIALS}"]) {
sh """
if [ "${env.BRANCH_NAME}" == "master" ]; then
echo "执行自动回滚"
kubectl rollout undo deployment/${PROJECT_NAME} \
-n ${K8S_NAMESPACE_PROD}
fi
"""
}
// 发送告警通知
sh """
curl -X POST 'https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "text",
"text": {
"content": "【告警】${PROJECT_NAME} 发布失败! 构建编号: ${BUILD_NUMBER}, 请及时处理!"
},
"at": {
"isAtAll": true
}
}'
"""
}
}
always {
// 清理构建缓存
cleanWs()
}
}
}