构建端到端 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
SCMGitHub
CI/CDJenkins (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

  1. 开发者将代码推送到 GitHub
  2. 通过 Ngrok 暴露的 webhook 自动触发 Jenkins 流水线——无需手动启动。
  3. 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:
Back to Blog

相关文章

阅读更多 »

Rapg:基于 TUI 的密钥管理器

我们都有这种经历。你加入一个新项目,首先听到的就是:“在 Slack 的置顶消息里查找 .env 文件”。或者你有多个 .env …

技术是赋能者,而非救世主

为什么思考的清晰度比你使用的工具更重要。Technology 常被视为一种魔法开关——只要打开,它就能让一切改善。新的 software,...

踏入 agentic coding

使用 Copilot Agent 的经验 我主要使用 GitHub Copilot 进行 inline edits 和 PR reviews,让我的大脑完成大部分思考。最近我决定 t...