构建端到端 CI/CD 流水线:Spring Boot、Jenkins、Kubernetes 与安全扫描
发布: (2026年1月6日 GMT+8 03:29)
6 min read
原文: Dev.to
Source: Dev.to
为什么我构建了这个项目
我之前接触过 CI/CD 的概念和工具,但总是存在一个差距:了解工具与构建完整系统之间的鸿沟。
大多数教程停留在 “Pipeline executed successfully”(流水线执行成功)这一步,而真实的 CI/CD 系统还涉及:
- 版本管理策略
- Webhook
- 代码质量门禁
- 安全扫描
- Kubernetes 部署滚动
- 失败、重启以及大量调试
于是,我决定构建一个真正的端到端 CI/CD 流水线,从 Git 推送开始,最终在 Kubernetes 上运行一个完整部署、具备安全性和可观测性的 Spring Boot 应用。本文记录了我的构建过程、出现的故障、解决方案以及所汲取的经验教训。
Source: …
流水线概览
| 层 | 技术 |
|---|---|
| 应用程序 | Spring Boot |
| 版本管理 | Maven + /release API |
| SCM | GitHub |
| CI/CD | Jenkins (Pipeline as Code) |
| 代码质量 | SonarQube |
| 暴露 | Ngrok |
| 容器 | Docker |
| 安全 | Trivy |
| 编排 | Kubernetes |
| 数据库 | MongoDB |
| 通知 | Jenkins Mailer |
该流水线在本地运行,但行为如同生产系统:
Git push → automatic Jenkins trigger
→ Maven build & tests
→ Application versioning with /release endpoint
→ Docker image build (immutable)
→ SonarQube code quality gates
→ Trivy image security scanning
→ Kubernetes deployment & rollout
→ Email notifications
→ MongoDB‑backed persistence
GitHub Push & Jenkins Trigger
- 开发者将代码推送到 GitHub。
- 通过 Ngrok 暴露的 webhook 自动触发 Jenkins 流水线——无需手动启动。
- Jenkins 克隆仓库并执行构建。
Maven 构建与测试
mvn clean test
确保:
- 代码能够编译。
- 单元测试通过。
- 在继续之前,构建是可部署的。
SonarQube Quality Gates
- Jenkins 将分析报告发送到 SonarQube。
- 流水线等待 Quality Gate 结果。
- 如果门禁失败,构建将停止,自动强制执行工程标准。
Docker 镜像构建(多阶段)
使用多阶段 Dockerfile:
- Build stage – 包含 Maven 和所有构建依赖。
- Runtime stage – 仅包含 JRE 和已编译的 JAR。
结果:更小、更安全的生产镜像。
使用 Trivy 进行安全扫描
在将镜像推送到注册表之前,Trivy 会对其进行扫描:
trivy image
- 检测到 Critical(严重)和 High(高)漏洞。
- 可以将流水线配置为根据严重性失败,确保有漏洞的镜像永不进入部署。
Kubernetes 部署与发布
所有检查通过后:
docker push /:${BUILD_NUMBER}
kubectl apply -f deployment.yaml
kubectl rollout status deployment/
Jenkins 容器问题与解决方案
| 问题 | 解决方案 |
|---|---|
Jenkins 在 Docker 容器内部运行,但需要构建 Docker 镜像,导致对 /var/run/docker.sock 的权限问题。 | - 将宿主机的 Docker 套接字挂载到 Jenkins 容器中(-v /var/run/docker.sock:/var/run/docker.sock)。- 在 Jenkins 镜像内部添加 docker 组,并将 jenkins 用户加入该组。 |
Jenkins(容器)在 Windows 主机上使用 127.0.0.1 无法访问 Kubernetes API 服务器。 | 使用 --add-host=localhost:host-gateway 运行 Jenkins 容器,将容器的 localhost 映射到主机网关,从而实现与 KIND 集群的通信。 |
当部署仍然引用 :latest 标签时,即使镜像已更改,Kubernetes 也不会触发新的发布。 | 实现 动态镜像标签:在 deployment.yaml 中将 IMAGE_PLACEHOLDER 替换为唯一的版本 ${BUILD_NUMBER}。这可确保每次更改都触发发布,提供确定性的回滚以及可追溯的镜像版本。 |
/release 端点
Spring Boot 应用程序公开一个 /release 端点,返回:
- 应用版本
- Jenkins 构建号
- 运行时环境元数据
这使得可以直接从应用程序验证哪个构建正在 pod 中运行。
自定义 Jenkins Docker 镜像
一个自定义的 Jenkins 镜像已预装以下工具:
- Maven
- Docker CLI
- Kubectl
优势:
- 在不同环境之间实现可重复性。
- 加快新团队成员的上手速度。
- 保持工具版本的一致性。
Lessons Learned
- Shift‑left security: Trivy 在部署前识别出关键 CVE(例如 Tomcat 远程代码执行)。
- Network boundaries matter: 管理 Jenkins、SonarQube、Kubernetes 和 Docker 之间的通信是最大的挑战。
- Event‑driven pipelines: 移除手动触发并依赖 GitHub webhook,使流水线真正实现 CI/CD。
- Automation builds trust: 了解系统之间的交互并系统性地处理故障,使 DevOps 从脚本提升为工程化。
参考文献
- GitHub repository:
- LinkedIn profile: