KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

06 · 交付形态演进:从脚本到声明式,再到 Agentic DevOps — keel 龙骨

这一章回答:Jenkins、GitLab CI、GitHub Actions、GitOps、Argo CD、Kubernetes、阿里云效……这些名词之间的关系是什么,以及一个具体团队该停在哪种形态。

这一章回答:Jenkins、GitLab CI、GitHub Actions、GitOps、Argo CD、Kubernetes、阿里云效……这些名词之间的关系是什么,以及一个具体团队该停在哪种形态。

技术选型的失败大多来自用别人的形态解决自己的问题:三个人的项目上 K8s 是负担,五十个服务的公司只用 shell 脚本是灾难。这一章给的是匹配依据。

一、四层模型:别把不同层的东西横向比较

④ 编排与调度层   Kubernetes / ECS / Nomad / Docker Compose
        ↑ 决定容器在哪跑、跑几个、怎么被替换
③ 交付方式层     GitOps(Argo CD / Flux)/ 传统 CD 推送 / 人工执行
        ↑ 决定"期望状态"存在哪、谁来把现实对齐过去
② 流水线层       GitHub Actions / GitLab CI / Jenkins / 云效 / CircleCI
        ↑ 决定触发器、作业、缓存、产物、权限
① 基础设施层      Terraform / Pulumi / 云厂商模板
        ↑ 决定机器、网络、存储这些前置条件

最常见的新手错误是把 GitHub Actions 和 Kubernetes 放在一起比。 它们分别在 ② 和 ④,一个负责"构建与触发",一个负责"运行与调度";两者经常同时使用。

同理,Argo CD 是 ③ 层的东西,它不负责构建与测试(这由 CI 完成),只负责"把 Git 里声明的状态持续对齐到集群"。经典分工是:CI 构建镜像并更新 manifest 里的镜像版本 → GitOps 控制器检测到 Git 变化 → 集群自动跟进。

二、四种交付形态:按团队规模匹配

形态 描述 适合 不适合 主要成本
脚本化 build.sh / deploy.sh,人工执行 单服务、单人维护、部署频率低 多人协作、需要审计 每次路径可能不同,故障难复述
流水线 CD(push 型) CI 系统在流水线里执行部署命令 绝大多数中小团队(10 人以下、服务数 < 10) 需要严格审计与 drift 治理 CI 系统需要部署权限,凭据集中在 CI 侧
GitOps(pull 型) 集群内的控制器持续从 Git 拉取并对齐状态 多集群、多团队、K8s 已就位 小规模或非容器场景 多一套系统要维护,YAML 治理有学习成本
Agentic DevOps AI agent 参与流水线执行与修复(见第 1 门课 05 章) 已有成熟流水线之上的增强 基础门禁都没搭好的团队 权限与审计复杂度上升

push 型 vs pull 型是这里最重要的概念差别:

push 型(CI 驱动):  CI 系统持有集群凭据 → 主动执行 kubectl/helm/API
                    优点:直观、与流水线一体
                    缺点:凭据集中在 CI;集群外的变更(手工 kubectl)无人察觉

pull 型(GitOps):  集群内的控制器拉取 Git → 无人除外地将集群对齐到声明
                    优点:凭据不出集群;Git 是唯一事实源;自动发现并纠正配置漂移
                    缺点:多一层抽象;正在进行金丝雀时应用会显示 OutOfSync(需要用 ignoreDifferences 处理这类字段归属)

三、工具选型的四个真实依据

不要从"哪个工具火"开始,从这四个问题开始:

问题 影响
代码托管在哪? GitHub → Actions 是最短路径;GitLab → GitLab CI;自建 Jenkins 通常因为历史包袱或内网合规要求
是否需要私有网络/内网部署? 金融/政企常见:数据不出网 → 自建 runner 或内网 Jenkins/云效
是否已上 Kubernetes? 没上:Compose/单机 + 脚本化就够;上了:Helm/Kustomize + Argo/Flux 才有意义
团队有没有人维护这套东西? 这一条最容易被忽略。 没有人维护的 Jenkins 会在两年后变成"谁都不敢碰但所有人依赖"的东西

国内常见组合示例:GitHub/GitLab + 自建 runner(内网打包)+ 镜像推私有仓库 + Compose 或 K8s 滚动更新 + 云厂商的监控告警。这条路径覆盖了绝大多数中小团队的实际形态,也是你应该能对答如流的一条。

四、声明式带来的三个收益(和一个代价)

收益 ①  可审计:谁在什么时候把什么东西改成什么样,全在 Git 历史里
收益 ②  可回滚:回滚 = revert 一次提交,而不是"记得上次的手工操作"
收益 ③  自动纠偏:控制器检测到实际状态偏离声明时会自动还原(或告警)
代价    任何东西都要 YAML 化——包括"临时改一下"这种想法的消失

代价那条值得展开:GitOps 会强制所有变更走流程,这在提升了可靠性的同时也会让"快速改一下"变得笨重。 因此生产走严格 GitOps、开发/调试环境保留手动通道,是常见的折中。

实践中的三条防坑规则:

五、进阶路线图:不要跳跃

阶段 A  脚本 → 流水线:              先把"每次都跑同样的检查"做实
阶段 B  流水线 → 不可变产物:         构建出带有版本与 digest 的产物,先停止在生产机上重新构建
阶段 C  产物 → 环境声明化:           Compose/Helm 描述拓扑,配置与密钥外部化
阶段 D  环境 → GitOps 对齐:          控制器持续对齐,漂移自动发现
阶段 E  全套都已成熟时 → Agentic:    让 AI 参与失败归因、测试生成、自动修复,边界见第 1 门课 05 章

每个阶段都要先回答:"没有它,当前最痛的问题是什么?" 答不上来就不要上——因为下一阶段的复杂度是实打实要付的。

六、结合你的情况:怎么谈"我们公司没有这些"

面试时坦诚的分层话术(按顺序说,效果最好):

  1. 先讲现状:公司项目当时是"Compose + Nginx + 脚本化部署 + 日志轮转 + 值班窗口",规模和技术栈决定它在阶段 A/B 之间。
  2. 再讲自己做到哪一档:在开源项目里完整跑通了阶段 A 到 B,包括产物不可变、幂等发布、OIDC 免长期令牌、发布前产物冒烟。
  3. 然后讲取舍判断:不是所有团队都需要 GitOps——我会在什么条件下引入(多服务多集群、需要审计与漂移治理时),以及在什么条件下不引入(小规模、没有人专职维护 K8s)。
  4. 最后讲边界:没在线上百台规模验证过的东西,我不吹。

这套话术的杀伤力在于:它同时展示了做过、懂取舍、且诚实。 面试官分辨的是"背过理论"和"知道什么时候不该用",第 3 点通常是最缺的那部分。

动手:可观察结果

动作 产出物 判断标准
画出自己项目所处的层与形态 一张四层标注图 能指出哪一层缺失、缺了它的具体代价
对比 push 型与 pull 型 一份差异表 能回答"凭据在哪、漂移怎么被发现"
写一份工具选型说明 一页 rationale 至少回答四个依据中的三个
手工改一次集群里的某个字段 一次自动纠偏演示 手工改动集群后,控制器将其纠正回来
列出自己想引入下一阶段的触发条件 条件清单 条件是客观的(服务数/团队数/审计要求),不是"因为它很火"

故障注入

注入方式 观察什么 说明的现象
手工 kubectl 改一个生产字段 GitOps 是否发现并纠正 发现不了 → 漂移开始累积
打开 prune 然后误删一个 YAML 对应的生产资源是否被删 这就是 prune 的风险;关键资源应被保护
把 CI 的部署凭据配置得过宽 谁能用它做什么 集中式凭据是 push 型最大的软肋
同步顺序依赖没声明 sync 是否卡住 CRD/命名空间顺序错误会卡在 Progressing
为小规模项目强行引入 K8s 半年后谁在维护它 没人维护的平台=团队风险源

自测题

  1. GitHub Actions 与 Kubernetes 分别属于四层模型里的哪一层?为什么不能横向比较?
  2. push 型 CD 与 GitOps pull 型在"凭据放在哪"和"漂移怎么被发现"上有什么区别?
  3. GitOps 的自动清理(prune)会带来什么具体的风险?怎么防?
  4. 工具选型四问中,哪一问最容易被忽略?忽略后通常怎么收场?
  5. 面试官问"你们公司没有 CI/CD"时,你的四步分层话术是什么?

进入 keel 阅读