☰
90DaysOfDevOps 全景篇:CI/CD 管道 — 持续集成与持续部署的完整实践指南
2026/10/6 2:42:32 网站建设 项目流程
  • 文档/教程

【免费下载链接】90DaysOfDevOps

This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.

项目地址:https://gitcode.com/gh_mirrors/90/90DaysOfDevOps
点击查看免费下载

本篇是 90DaysOfDevOps 挑战 Day 70 的技术解读,围绕现代 DevOps 环境的支柱——CI/CD(持续集成/持续部署)管道展开:从软件开发生命周期(SDLC)的无限循环讲起,深入 CI 的自动化构建与测试、CD 的环境部署与制品交付,并结合本仓库中真实的 Jenkins Helm 部署清单、Kubernetes 权限配置与声明式 Jenkinsfile 流水线,给出可落地、可复现的实践路径。

为什么说 CI/CD 是现代 DevOps 环境的支柱

CI/CD(Continuous Integration / Continuous Deployment)管道通过自动化应用的构建(Build)、测试(Test)与部署(Deploy),从根本上弥合了开发(Dev)与运维(Ops)之间的鸿沟。正如本仓库 Day 70 英文原稿 与 韩文翻译版 所强调的:这不是一个可选项,而是现代 DevOps 环境的"支柱"(backbone)。

  • 快速高效地交付软件:把从代码提交到生产上线的过程压缩到分钟级甚至秒级。
  • 加速产品上市:通过有效的流程,让应用以最快速度触达市场。
  • 持续交付增量价值:无需等待数月甚至数年的版本发布周期,缺陷修复和新功能可以像"流水线"一样源源不断地流出。

它的核心价值在于:让开发者能够频繁地做出小而关键(small impactful changes)的变更,从而获得更快的修复速度和更高的功能产出速度。

软件开发生命周期(SDLC):永不停歇的无限循环

在深入 CI/CD 之前,先回到 DevOps 的理论基础。本仓库在 Day 5 的 DevOps 理论讲解 中已经系统性地介绍了这些概念,Day 70 则站在"更深入学习"的视角,重新强调 SDLC 中与 CI/CD 直接相关的关键环节。

软件开发生命周期(Software Development Life Cycle, SDLC)是一个永远重复的循环,因此通常被画在"无限循环"(infinity loop)中:

  1. 代码(Code):开发者编写代码;
  2. 构建(Build):代码被编译、整合在一起;
  3. 测试(Test):对代码进行缺陷检测;
  4. 部署(Deploy)/ 运营(Operate):发布到生产环境,供终端用户或客户使用;
  5. 监控(Monitor):收集反馈与运行指标;
  6. 计划(Plan):围绕反馈规划改进,然后"冲洗、重复"(rinse and repeat)。

CI 与 CD 恰好覆盖了这个循环中最容易出错的三个环节——构建、测试与部署,并把它们从"人工操作"变成"自动触发的流水线"。

深入 CI:持续集成的原理与工作流

持续集成的定义

持续集成(Continuous Integration)是一种现代软件开发实践,要求开发者每天多次将代码变更集成(integrate)到一个共享仓库中。其核心逻辑是:

  • 增量式代码变更,频率更高、更可靠;
  • 由 CI 触发的自动化构建与测试工作流步骤,确保合并进仓库的代码变更是可信赖的。

代码编写完成并 push 到 GitHub 或 GitLab 这样的代码仓库之后,"魔法"便开始了:自动化构建对代码进行验证,让团队或项目所有者尽早发现问题。

三类核心自动化测试

代码被分析后,会接受一系列自动化测试,其中最常见的三类是:

测试类型作用
单元测试(Unit Testing)测试源代码的单个独立单元(函数、方法、模块)
验证测试(Validation Testing)确认软件满足或适配预期用途
格式测试(Format Testing)检查语法及其它格式错误

测试以 Workflow 形式存在,随 push 触发

这些测试被组织成Workflow,并配置为每次向 master 分支 push 时自动执行。这也是为什么几乎所有主流开发团队都会搭建某种形式的 CI/CD workflow——因为在全球化协作的开发团队里,来自不同时区、不同项目的开发者随时都可能提交新代码,构建一套自动化测试工作流、在代码被接受之前确保"所有人都在同一页面上",远比每次由人工执行高效得多。

测试全部通过并成功后,就可以将代码编译并推送到制品仓库——例如 Docker Hub。这个制品仓库中的镜像,将在后续 CD 阶段被消费和部署:

可以看到,CI 阶段本身与软件开发的日常节奏高度一致:创建应用、添加/修复缺陷、更新源代码管理、做版本管理,同时持续测试。

一个值得关注的行业趋势

原作者在文档中特别指出一个趋势:越来越多的商业软件(off-the-shelf software)开始以"制品"形式交付。比如从 Oracle、Microsoft 等供应商获取软件时,很可能是从 Docker Hub 类型的制品仓库中"消费"镜像,然后再用自己的 CD 管道把这些软件部署到自身环境中。这意味着 CD 能力将逐渐成为每个团队的基础设施级能力。

深入 CD:持续部署与环境的制品交付

持续部署的定义

当 CI 阶段产出了测试通过的代码版本,就进入持续部署(Continuous Deployment,CD)阶段:把代码发布到目标环境。这里的"环境"不仅指生产环境,通常还包括**暂存(staging)**等其它环境。

软件供应商会完整走通这个阶段,而原作者相信:未来我们所有人都将以这种方式部署所需的商业软件——即从制品仓库消费镜像,再通过 CD 管道投放至自己的环境。

CD 的关键:正确代码 + 正确配置 → 正确环境

在软件部署的第一天(v1 首版),下一步要确保的是:把正确的代码基座(code base)拉取到正确的环境。

  • 制品可能来自软件仓库(如 Docker Hub)——拉取最新发布版本;
  • 与此同时,还很可能从另一个代码仓库(Git 仓库)拉取应用配置;
  • 这些工作由CD 工具统一执行,把所有内容推送到目标环境。

需要特别强调的是:软件与配置的部署通常不会同时进行。更常见的做法是:

  1. 先进入暂存环境,携带新配置运行,验证一切正确;
  2. 这一步可以是人工测试步骤,也可以再次自动化(推荐自动化);
  3. 验证通过后,才允许代码被部署到生产环境。

当应用发布v2时,流程重复:将"应用 + 配置"部署到暂存,确认无误,再部署到生产。这种"暂存先行、生产随后"的分阶段推进,是降低发布风险的核心手段。

为什么必须使用 CI/CD

自动化与小问题的早期拦截

CI/CD 的价值在于把原本必须手动完成的工作自动化,并在小问题悄悄溜进主代码库之前将其拦截。可以想象,如果把坏代码直接推到客户面前,后果将不堪设想。

防止技术债(Technical Debt)

CI/CD 还有助于防止"技术债"的累积。技术债的概念是:主代码仓库会随时间不断被构建叠加,第一天采取的"捷径式修复",几年后会变成指数级昂贵的修复——因为当初那块"创可贴"式的修复,已经深深地交织、烘焙进所有代码库与业务逻辑之中。持续集成让每次变更都被即时验证,避免坏味道长期潜伏在代码库深处。

工具选型:Jenkins、ArgoCD 与 GitHub Actions

进入实战环节前,先明确一个关键认知:并非所有工具都必须同时承担 CI 与 CD 两种职责。

  • Jenkins:成熟的 CI/CD 平台,可跨多种平台工作,既能做 CI 也能做 CD;
  • ArgoCD:专注于CD 元素,尤其擅长把软件部署到Kubernetes 集群,是 GitOps 理念的代表实现;
  • GitHub Actions:与 GitHub 仓库深度集成的自动化工作流平台,workflow 以 YAML 文件"即代码"形式存在。

原文档在"资料(Resources)"一节为以上三款工具附有一批官方文档与入门视频资源,可直接在仓库的 day70.md(英文版见 day70.md)中查看。

实战佐证 1:用 Helm 在 Kubernetes 上部署 Jenkins

本仓库的 2022/Days/CICD/Jenkins/ 目录保存了 Day 71 起 Jenkins 实战的完整部署材料,其中 steps.md 记录了端到端部署步骤。下面结合仓库中的真实清单文件逐段讲解:

第一步:准备本地 Kubernetes 环境与命名空间

minikube start kubectl create namespace jenkins # 或者使用仓库中的声明式清单: kubectl create -f 2022/Days/CICD/Jenkins/jenkins-namespace.yml kubectl get namespaces

jenkins-namespace.yml 非常简单,只声明了一个名为jenkins的 Namespace,作为 Jenkins 控制器的隔离空间。

第二步:添加官方 Helm 仓库

helm repo list helm repo add jenkinsci https://charts.jenkins.io helm repo update

第三步:创建持久卷(PV)与 ServiceAccount(RBAC)

kubectl apply -f 2022/Days/CICD/Jenkins/jenkins-volume.yml kubectl apply -f 2022/Days/CICD/Jenkins/jenkins-sa.yml

jenkins-volume.yml 定义了一个hostPath类型的 PersistentVolume:

  • storageClassName: jenkins-pv:与 Helm values 中persistence.storageClass对应;
  • capacity.storage: 20Gi:分配 20Gi 容量;
  • accessModes: ReadWriteOnce:单节点读写;
  • persistentVolumeReclaimPolicy: Retain:PV 释放后保留数据,防止误删 Jenkins 数据;
  • hostPath.path: /data/jenkins-volume/:宿主机上的数据落盘目录。

jenkins-sa.yml 则一次性创建了三个 RBAC 对象:

  • ServiceAccountjenkins(位于 jenkins 命名空间):供 Jenkins 控制器 Pod 使用;
  • ClusterRolejenkins:授予对statefulsets、services、replicasets、pods、pods/log、pods/exec、persistentvolumes、persistentvolumeclaims、deployments、configmaps、secrets、events等资源执行create/get/watch/delete/list/patch/update的权限,也覆盖nodes的读取类权限——这是 Jenkins 以 Kubernetes 为云(cloud)动态调度代理 Pod 的基础;
  • ClusterRoleBindingjenkins:将上述 ClusterRole 绑定到system:serviceaccounts:jenkins组,使 jenkins 命名空间下的所有 ServiceAccount 都具备该权限。

第四步:通过 Helm 安装 Jenkins 控制器

chart=jenkinsci/jenkins helm install jenkins -n jenkins -f 2022/Days/CICD/Jenkins/jenkins-values.yml $chart

jenkins-values.yml 是本次安装的核心配置,几个关键项值得展开:

  • controller.image: "jenkins/jenkins"+tagLabel: jdk11:使用官方镜像的 jdk11 变体;
  • adminUser: "admin"+adminSecret: true:启用 Chart 内置管理员账户,初始密码由 Helm 自动生成(见下文获取方式);
  • servicePort: 8080+serviceType: ClusterIP:控制器服务端口;minikube 环境可改用 NodePort,生产环境可用 LoadBalancer 或配合 Ingress;
  • healthProbes: true:启用 startup/liveness/readiness 三类探针,对/login端点做 HTTP 探测,配合failureThreshold、periodSeconds等参数保障控制器在插件重启等场景下的健康恢复;
  • installPlugins:预装四个关键插件——kubernetes:1.31.3(Kubernetes 云/动态代理)、workflow-aggregator:2.6(Pipeline 流水线)、git:4.10.2(Git 源码管理)、configuration-as-code:1.55.1(JCasC 配置即代码);
  • JCasC.securityRealm:以"配置即代码"方式声明本地安全域,使用${chart-admin-username}/${chart-admin-password}占位符注入管理员凭据,并设置allowsSignup: false(禁止匿名注册)、enableCaptcha: false;authorizationStrategy采用loggedInUsersCanDoAnything(登录用户可操作、禁止匿名读取);
  • agent:默认代理镜像jenkins/inbound-agent:4.11.2-4,containerCap: 10限制最多并发 10 个代理 Pod,podRetention: "Never"表示构建完成后立即回收代理 Pod;
  • persistence.enabled: true+storageClass: jenkins-pv+size: 8Gi:控制器数据持久化到前述 PV 对应的存储类。

第五步:修正 PV 目录权限并重启控制器

minikube ssh sudo chown -R 1000:1000 /data/jenkins-volume kubectl delete pod jenkins-0 -n jenkins kubectl get pods -n jenkins -w

Jenkins 官方镜像以 UID1000(jenkins 用户)运行,而hostPath卷的宿主机目录默认属主可能是 root,因此需要将/data/jenkins-volume递归授权给1000:1000,随后删除jenkins-0Pod 让其以正确权限重建。

第六步:获取管理员密码并登录

kubectl exec --namespace jenkins -it svc/jenkins -c jenkins -- /bin/cat /run/secrets/chart-admin-password && echo kubectl --namespace jenkins port-forward svc/jenkins 8080:8080

打开浏览器访问http://localhost:8080,用admin与上面取出的密码登录,然后执行插件更新即可开始使用。

实战佐证 2:声明式 Jenkinsfile —— 容器化流水线的完整结构

仓库中的 Pipeline/Jenkinsfile 展示了一条完整的声明式(Declarative)Pipeline,是"CI 验证 → 镜像构建 → 镜像推送"这条自动化链路的直接落地:

  • podTemplate:用内联 YAML 定义一个一次性运行 Pod,包含两个容器——maven:3.8.1-jdk-8(构建/测试容器,sleep 99d保持存活)和gcr.io/kaniko-project/executor:debug(镜像构建容器,挂载名为kaniko-secret的 Secret 到/kaniko/.docker,即把 Docker 凭据以config.json形式提供给 kaniko 使用);
  • stage('Clone Repository'):在流水线节点上git clone示例应用仓库的main分支(对应源码托管仓库中的 HelloWorld 演示项目);
  • stage('Build Image'):进入maven容器执行构建(示例中以echo "Tests passed"模拟测试通过的验证步骤);
  • stage('Test Image'):进入kaniko容器执行/kaniko/executor --context \pwd` --destination <镜像名>: `,在无需 Docker Daemon 的情况下完成镜像构建并推送到制品仓库——这正是文档中所描述的"测试通过后编译并推送制品仓库"的真实实现。

配套的 Pipeline/Dockerfile 则是最小可运行应用的构建配方:

FROM busybox:latest ENV PORT=8000 ADD index.html /www/index.html # 健康检查(原文指令,需结合具体环境修正后使用) HEALTHCHECK nc -z localhost $PORT # 启动内置 httpd,监听 $PORT,服务 /www 目录,直至容器被停止 echo "httpd started" && trap "exit 0;" TERM INT; httpd -v -p $PORT -h /www -f & wait

该镜像将index.html放入/www,用 busybox 内置的httpd启动一个静态 Web 服务——这正是 CD 阶段将要被拉取、部署到目标环境的最小制品样本。

小结与下一步

Day 70 从理论到工具为 CI/CD 画出了一张完整的"全景图":CI 负责把每天多次的代码集成变成自动化的构建与测试,CD 负责把测试通过的制品连同配置安全地推进到暂存与生产环境,而自动化带来的即时反馈与对技术债的遏制,是这套体系长期运转的根本动力。

在工具层面,本仓库已经为接下来的动手环节准备好了完整的 Jenkins 落地素材(CICD 目录),后续将依次深入 Jenkins 的更多细节、ArgoCD 在 Kubernetes 上的 GitOps 式持续部署,以及 GitHub Actions 的 workflow 编写。下一站是 Day 71。

  • 文档/教程

【免费下载链接】90DaysOfDevOps

This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.

项目地址:https://gitcode.com/gh_mirrors/90/90DaysOfDevOps
点击查看免费下载
上一篇:PHPStan 错误标识 `new.trait` 全解析:为什么不能 `new` 一个 Trait,以及如何修复
下一篇:Hive 多智能体生产运行时(Multi-Agent Harness)完整指南:Colony 集群模型、Queen/Worker 架构与零配置快速上手

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询