蓝胖的四次元口袋头像
关注

GitLab+Jenkins CI-CD自动化部署实战

作者:没有四次元口袋的蓝胖
日期:2026-09-15
标签:CI/CD, GitLab, Jenkins, DevOps


写在前面

这是一篇 CI/CD 自动化部署实战记录。从 GitLab 代码托管、分支规范制定,到 Jenkins 自动化构建部署,完整记录了团队从零搭建 CI/CD 流水线的全过程。


一、项目背景

团队之前的部署流程:每次代码提交后,需要 手动登录服务器mvn clean package → 上传 jar/war 包 → 重启 Tomcat,流程繁琐且容易出错。

目标:引入 GitLab + Jenkins,实现"代码推送即自动构建,构建完成即自动部署"。


二、GitLab 分支规范与代码管理

2.1 Git Flow 分支策略

分支用途保护策略
master生产环境代码Protected,禁止直接 push,必须通过 MR
develop开发测试环境Protected,禁止直接 push,必须通过 MR
feature/*功能开发分支从 develop 拉出,开发完提 MR 回 develop
hotfix/*紧急修复从 master 拉出,修复完同时合并到 master 和 develop

2.2 分支保护配置

GitLab → Settings → Repository → Protected branches:

  • master、develop 均设置为 Protected
  • Allowed to merge:Maintainers
  • Allowed to push and merge:No one(禁止直接 push)
  • Require approval:至少 1 人审核

这样所有代码合并必须走 MR 流程,从制度上保障代码质量。

2.3 🎯 面试高频问题

Q:MR(Merge Request)和 PR(Pull Request)有什么区别?

本质一样,只是叫法不同。MR 是 GitLab 的叫法,PR 是 GitHub 的叫法。都是"我改了代码,请审核后再合并"。

Q:为什么不直接 push 到 master?

没有审核流程 = 任何人都能把未测试的代码推上线。MR 机制强制 Code Review + 构建验证,是生产环境的基本保障。


三、Jenkins 环境搭建

3.1 安装 Jenkins

Jenkins 基于 Java,需要先装好 JDK。这里选择用 Tomcat 部署 WAR 包的方式:

# 1. 下载 Jenkins WAR 包
wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/latest/jenkins.war

# 2. 放到 Tomcat 的 webapps 目录下
cp jenkins.war /opt/tomcat/webapps/

# 3. 启动 Tomcat
/opt/tomcat/bin/startup.sh

# 4. 访问 http://服务器IP:8080/jenkins
# 首次访问需要输入初始密码
cat /root/.jenkins/secrets/initialAdminPassword

3.2 插件安装

首次进入 Jenkins 选择"安装推荐插件",之后手动补充关键插件:

插件作用
Git Plugin从 GitLab 拉取代码
Maven Integration支持 Maven 项目构建
Publish Over SSH将构建产物传输到远程服务器
Email Extension构建结果邮件通知
GitLab Plugin与 GitLab 集成(Webhook + 构建状态回传)

3.3 全局工具配置

Jenkins → 系统管理 → 全局工具配置:

  • JDK:指定 JAVA_HOME 路径
  • Maven:指定 Maven 安装目录
  • Git:指定 git 可执行文件路径

3.4 凭据管理

Jenkins → Credentials → 添加凭据,配置 GitLab 的访问凭证:

  • 类型选择:SSH Username with private key(推荐)或 Username with password
  • Scope:Global(全局可用)

💡 最佳实践:所有密码、Token 都通过 Jenkins Credentials 管理,不要在脚本中硬编码!

3.5 🎯 常见坑点

坑1:Jenkins 的 SSH 密钥权限问题

Jenkins 以 jenkins 用户运行,生成 SSH 密钥后要确保 .ssh 目录权限是 700,密钥文件权限是 600,否则 SSH 连接会被拒绝。

坑2:Maven 构建时内存不足

默认 Jenkins 的 JVM 内存可能不够,大项目构建时 OOM。解决方法:修改 jenkins.xml 或启动脚本中的 -Xmx 参数。


四、Freestyle 项目配置(核心)

4.1 创建项目

Jenkins → 新建任务 → 输入项目名称 → 选择"构建一个自由风格的软件项目"。

4.2 第一阶段:源码管理

  • Source Code Management:选择 Git
  • Repository URL:填写 GitLab 仓库 SSH 地址(如 [email protected]:group/project.git
  • Credentials:选择之前配置的 GitLab 凭据
  • Branch Specifier*/develop(根据项目环境选择分支)

4.3 第二阶段:构建触发器

选择 Build when a change is pushed to GitLab

  • Jenkins 会生成一个 Webhook URL,格式类似:
    http://jenkins-server:8080/project/项目名称
    
  • 将此 URL 填入 GitLab → Settings → Webhooks
  • 勾选 Push events
  • 点击 Add webhook

Webhook 工作原理

git push → GitLab 检测到 push → 向 Jenkins 发 HTTP POST → Jenkins 触发构建

⚠️ 注意:GitLab 服务器必须能访问到 Jenkins 的地址。如果是内网环境,需要确保网络互通。

4.4 第三阶段:构建步骤(Build)

选择 Execute shell,填入构建脚本:

#!/bin/bash
echo "===== 开始构建 ====="

# 设置环境变量
export JAVA_HOME=/usr/local/java/jdk1.8
export MAVEN_HOME=/usr/local/maven
export PATH=$MAVEN_HOME/bin:$JAVA_HOME/bin:$PATH

# Maven 编译打包(跳过测试)
mvn clean package -DskipTests

# 检查打包结果
if [ $? -ne 0 ]; then
    echo "构建失败!"
    exit 1
fi

echo "===== 构建成功 ====="
ls -lh target/*.jar

4.5 第四阶段:部署(Publish Over SSH)

Publish Over SSH 插件配置

Jenkins → 系统管理 → 系统配置 → Publish over SSH:

  • Path to key:SSH 私钥路径
  • SSH Servers:添加目标服务器信息
    • Name:自定义标识
    • Hostname:目标服务器 IP
    • Username:登录用户名
    • Remote Directory:远程基础路径

每个项目的 Post-build Action 配置

  • Source filestarget/*.jar(要传输的文件)
  • Remove prefixtarget(去掉路径前缀)
  • Remote directory/opt/app/project-name(部署目录)
  • Exec command(传输后执行的远程脚本):
#!/bin/bash
# 进入部署目录
cd /opt/app/project-name

# 备份旧版本
cp app.jar app.jar.bak.$(date +%Y%m%d%H%M)

# 停止旧进程
pid=$(ps -ef | grep app.jar | grep -v grep | awk '{print $2}')
if [ -n "$pid" ]; then
    kill -9 $pid
    echo "已停止旧进程: $pid"
fi

# 启动新应用(nohup 后台运行)
nohup java -jar app.jar --spring.profiles.active=prod > /dev/null 2>&1 &
echo "应用启动成功!"

4.6 🎯 面试高频问题

Q:构建和部署是怎么分开的?

构建在 Jenkins 所在的服务器执行 mvn clean package,产出 jar/war 文件。部署通过 Publish Over SSH 插件,将构建产物传输到目标服务器,再通过远程 Shell 脚本重启应用。两步分离的好处:构建服务器不需要和应用服务器是同一台,职责清晰。

Q:部署脚本里为什么要备份旧版本?

方便回滚。如果新版本上线后发现问题,可以快速把 .bak 文件改名恢复,不用重新构建。


五、多环境部署策略

环境分支触发方式说明
开发环境develop自动触发(git push 即构建部署)快速迭代,方便开发自测
生产环境master手动触发(Jenkins 点击"立即构建")安全可控,防止未经审核的代码上线

为什么生产环境要手动触发?

  • 防止误操作把未审核的代码推上线
  • 生产发布需要运维或负责人确认发布时间窗口
  • 可以配合上线前的检查清单(数据库变更、配置变更等)

六、构建通知与质量门禁

6.1 邮件通知

Jenkins → 项目配置 → Post-build Actions → E-mail Notification:

  • 勾选 Send separate e-mails to individuals who broke the build
  • 构建失败时自动通知相关开发者

6.2 GitLab 构建状态集成

安装 GitLab Plugin 后:

  • MR 页面会显示 Jenkins 构建状态(✅ Success / ❌ Failure)
  • 构建不通过 → 禁止合并,从流程上保障代码质量

6.3 🎯 常见坑点

坑1:邮件通知发不出去

Jenkins 默认邮件配置需要设置 SMTP 服务器。如果用 QQ/163 邮箱,需要在邮箱设置中开启 SMTP 服务并获取授权码,不是登录密码。

坑2:Webhook 配置了但不触发构建

排查步骤:

  1. 检查 Webhook URL 是否正确(注意端口和项目名称)
  2. 检查 Jenkins 项目是否勾选了 “Build when a change is pushed to GitLab”
  3. 在 GitLab Webhook 页面点 “Test” → “Push events”,查看返回状态码
  4. 检查网络:GitLab 服务器能否访问 Jenkins 地址

七、整体部署架构图

┌──────────┐     git push      ┌──────────┐    Webhook     ┌──────────┐
│ Developer │ ───────────────→ │  GitLab   │ ────────────→ │  Jenkins  │
│  (本地)   │                  │ (代码仓库) │               │ (构建服务器)│
└──────────┘                   └──────────┘               └─────┬────┘
                                                                │
                                                     SSH 传输 jar/war
                                                                │
                                                                ▼
                                                          ┌──────────┐
                                                          │ App Server│
                                                          │ (Tomcat)  │
                                                          └──────────┘
                                                                │
                                                         用户访问
                                                                ▼
                                                          ┌──────────┐
                                                          │  Browser  │
                                                          └──────────┘

八、写在最后

学习建议

  1. Shell 脚本是运维的基本功awksedgrepfind 必须熟练,部署脚本离不开它们
  2. Jenkins Freestyle 适合入门,但工作中更推荐 Pipeline(Jenkinsfile),支持代码化配置、并行执行、阶段控制,建议后续学习
  3. CI/CD 不仅仅是工具配置,更重要的是理解流程设计——分支策略、环境隔离、安全门禁、回滚机制
  4. 实操建议:自己搭一套 GitLab + Jenkins 环境,从 push 到自动部署跑通全流程,面试时才能讲得清楚

🎯 面试高频三连问

Q1:描述一下你做的 CI/CD 流程?

开发在本地完成功能后,push 到 feature 分支 → 提 MR 到 develop → Jenkins 通过 Webhook 自动触发构建 → 构建成功后通过 Publish Over SSH 部署到开发环境 → 测试通过后提 MR 到 master → 运维手动触发构建部署到生产环境。

Q2:Jenkins Freestyle 和 Pipeline 有什么区别?

Freestyle 通过界面配置,适合简单场景;Pipeline 通过 Jenkinsfile 代码化配置,支持 stage、parallel、agent 等高级语法,适合复杂流程,且可以纳入 Git 版本管理。

Q3:如果 Jenkins 构建的包在目标服务器跑不起来,你怎么排查?

  1. 检查 JDK 版本是否一致;2. 检查环境变量是否齐全;3. 查看应用日志定位启动报错;4. 检查配置文件(application.yml)的环境是否匹配;5. 对比本地能跑的环境和服务器环境的差异。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/2301_78547133/article/details/165573959

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--