基于docker安装jenkins+gitlab+harbor

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()
        }
    }
}
相关推荐
百万彩票中奖候选人2 小时前
迁移 Docker 存储目录
java·docker·eureka
0wioiw03 小时前
Docker(基础指令)
运维·docker·容器
vortex53 小时前
Docker 逃逸常见利用方式
运维·docker·容器
0wioiw03 小时前
Docker(Portainer)
运维·docker·容器
HIT_Weston3 小时前
53、【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(五)
网络协议·http·gitlab
༺๑Tobias๑༻3 小时前
国内可用的DOCKER 镜像源
运维·docker·容器
遇见火星3 小时前
主流CI/CD工具对比分析!
ci/cd·gitlab·jenkins·云效
HIT_Weston4 小时前
52、【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(四)
ubuntu·http·gitlab
成为你的宁宁4 小时前
【Jenkins 参数化构建实战指南:基于机器环境与插件配置,详解 tag 标签管理、commit 修订号应用、版本切换及回退全流程】
git·gitlab·jenkins·参数化构建