想象你在经营一家四季爆满的餐厅。后厨里,帮厨们忙得脚不沾地,可菜品时好时坏——今天的招牌菜咸了,明天又忘了放葱花。你训斥厨师,他却委屈地说:“我记得是这么做的呀!”问题出在哪?出在“记忆”:每个人的脑袋都装着自己的版本,真正的标准却散落在聊天记录和口头禅里。 如果这间餐厅的墙上钉着一册《标准菜谱》,每一道菜的分量、火候、摆盘都白纸黑字写得清清楚楚;又有一位从不走神的品控主管,在每道菜上桌前,拿起菜谱对照一遍,发现不对立刻重做——这样的后厨还会乱吗? 在软件世界,这套“把菜谱钉在墙上”的玩法就叫 GitOps。Git 仓库就是那册《标准菜谱》,里面存放着每个服务“应该长成什么样”的声明式配置;Kubernetes 集群就是那个后厨;而 ArgoCD,就是那位永不疲倦的品控主管——它每时每刻盯着厨房,一旦发现成品和菜谱对不上,就自动整改,直到分毫不差。 接下来,我们一起走进这家“自动化餐厅”的后厨,看看 ArgoCD 这套“品控系统”如何安装、点单、同步、回滚、设门禁、接采购,以及如何用它给 AI 模型服务端出一盘“特调菜”。
掌握 ArgoCD 与 GitOps,意味着你不再是“对着控制台手忙脚乱”的运维新手,而是能用一条 git push 驱动整个生产环境优雅更新的平台工程师。这是 MLOps 和云原生时代最具性价比的技能之一。
可视化演示
展示GitOps持续部署流程、资源同步状态对比和版本回滚机制三个核心实践。
本节配有交互动效(进入视口后自动加载,约 3KB)。
GitOps持续部署流程 Git提交触发ArgoCD检测变更 ArgoCD同步清单到K8s集群 Git = Single Source of Truth 声明式部署:配置即代码
GitOps核心理念
曾经,这家餐厅的后厨靠大厨的经验和口口相传维持运转。可一旦某位厨师休假,同样的菜换个人来做,味道就变了。你终于明白:让厨房稳定的关键,不是更勤快的厨师,而是把“什么才是标准答案”钉死在墙上。
GitOps 正是这样的“菜谱至上”哲学。它的核心主张是:Git 仓库里的声明式配置,是集群一切状态的唯一事实来源(Single Source of Truth)。你将每个服务写成 YAML 提交到 Git,此后集群中发生的事情不再由某个人的记忆决定,而由仓库中最新的提交决定。
这背后的关键概念是“声明式”:你描述期望的结果,系统替你补齐过程。比如“我要 3 个副本”,而不是“执行 kubectl scale 命令”。GitOps 更进一步,把“描述本身”当作代码纳入版本管理;再配合 ArgoCD 这类控制器,实现“期望状态 - 实际状态”的自动收敛——只要发现偏差,就立刻让系统向期望状态移动。
于是后厨规矩变得简单粗暴:菜谱写“宫保鸡丁要放花生米”,那就必须放;谁觉得不对,先改菜谱再说话。整套变更日志,就是后厨的完整大事记。
- 集群状态 $S_{\text{cluster}}$Kubernetes 集群中所有正在运行的资源合集,相当于后厨灶台上正在完成的一道道菜。
- 同步算子 $\Phi$ArgoCD 的持续协调过程,反复执行“读菜谱→核对→整改”,是那位总在巡视的品控主管。
- 仓库期望状态 $G_{\text{repo}}$Git 仓库中所有声明式配置的总和,也就是钉在墙上的《标准菜谱》。
ArgoCD安装部署
既然决定推行菜谱至上,这家餐厅高薪聘请了一位品控主管,他的名字叫 ArgoCD。主管入职的第一步,不是马上到处挑刺,而是先给自己安排一间办公室(namespace),把桌椅板凳(组件)摆放整齐。
生产环境中,大家通常用 Helm 来安装 ArgoCD,因为 Helm 图表把数百个散落的 Kubernetes 资源打成一个“安装包”,你可以像签订正式合同一样,通过 values.yaml 约定端口、副本数、持久化等参数。当然,跳过 Helm 直接使用官方 kubectl 清单也同样可行,只是自定义能力会弱一些。
装好后,你会发现 ArgoCD 由三件套组成:repo-server(专职“跑腿员”,从 Git 仓库拉取并缓存文件)、application-controller(专职“稽查员”,比对 Git 与集群的实际差异)、api-server(专职“前台接待”,负责 Web 界面、命令行接口和权限校验)。三者协作,构成完整的“品控体系”。你可以用 kubectl get pods -n argocd 查看它们是否就位。
办公室布置妥当,品控主管已经掏出菜谱准备上岗。不过,他只会按“菜单卡”干活——下一节,我们来看看这张菜单卡怎么设计。
- repo-server 跑腿员拉取并缓存 Git 仓库中的菜谱文件,避免每次核对都去 Git 远程重新下载。
- application-controller 稽查员周期性对比 Git 期望状态与集群实际状态,差异一旦出现立即触发同步。
- api-server 前台接待对外暴露 Web UI 与 REST/CLI 接口,是所有人“进入后厨”的必经入口。
Application资源
品控主管再敬业,也不可能同时记住几百道菜的配方。所以他手里必须有一叠“菜单卡”:哪道菜对应菜谱的哪一章(source),在哪口灶台做(destination),发现偏差要不要立刻重做(syncPolicy)。
在 ArgoCD 中,这张卡片就是一个名为 Application 的自定义资源(CRD)。有意思的是,你完全可以用 GitOps 的方式管理 Application 本身——把它的 YAML 也提交到 Git 仓库,让 ArgoCD 通过另一个 Application 来管理这些卡片。
一个典型的 Application 长这样:
字段含义:source 指定了“菜谱在哪、看哪个分支、哪一行目录”;destination 指定了“在哪个集群、哪个 namespace 出菜”;syncPolicy 则交代了“整改纪律”。
主管手里有了卡片,才知道该翻哪一页菜谱、盯哪口锅。但光有卡片还不行,他还得知道“发现偏差后按什么纪律处置”——这就引出同步策略。
- source 菜谱位置包含 repoURL、targetRevision、path 三个小字段,告诉 ArgoCD 去 Git 仓库的哪个分支、哪个目录读取期望配置。
- destination 做菜地点包含 server 与 namespace,告诉 ArgoCD 把应用部署到哪个集群的哪个命名空间,相当于指定灶台和锅。
- syncPolicy 整改纪律定义同步是手动还是自动、要不要 selfHeal 自愈,以及同步前后的钩子动作。
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: order-servicespec: source: repoURL: https://github.com/flavor-family/apps.git targetRevision: main path: services/order-service destination: server: https://kubernetes.default.svc namespace: prod syncPolicy: automated: selfHeal: true
同步策略
有一天,品控主管巡视到甜品台,发现提拉米苏里没撒可可粉。按原规定,他会把问题记在本子上,等着老板过目后手动决定。可老板已经受够了半夜被叫醒的日子,决定授权主管:发现不合规,直接当场重做。
这段授权,在 ArgoCD 里就是 syncPolicy.automated。开启后,一旦 ArgoCD 发现 Git 期望状态与集群实际状态有差异,就自动执行同步,不需要人工点击“Sync”按钮。
实操中还有一个更“激进”的开关:selfHeal。它意味着:哪怕有人故意用 kubectl 偷偷改了集群里的资源,ArgoCD 也会立刻把这个“违禁动作”撤销,将资源恢复成 Git 里的样子。想要更精细的控制,还有 Sync Hooks(同步钩子)和 Sync Waves(同步波次),可以在应用升级前先跑数据库迁移,或者按顺序先更新核心服务再更新边缘服务。
有了自动整改的授权,主管手里的卡就真正“活”了——菜不对,当场掀桌重来。不过,如果重来的这道菜本身就被大家嫌弃呢?那就轮到回滚机制登场了。
- 偏差 $\Delta$期望状态和实际状态的差异总和,可能体现在副本数、镜像版本、配置项等地方。
- 同步时刻 $t_{\text{sync}}$自动同步被触发的时间点,可以来自 Git 的变更事件,也可以来自 ArgoCD 的周期性巡检。
- 目标 $\Delta \to 0$收敛是 GitOps 的最终目的,让一切实际资源都无限接近菜谱。
回滚机制
某天下午,主管依照最新菜谱做了一道“分子料理牛排”,结果全餐厅的客人都皱眉头。慌乱之中,老板大喊:“把上午那版经典牛排拿回来!”可上午的菜谱已经被覆盖了,怎么办?
好在 ArgoCD 从不丢东西。每一次同步,它都会把当时的 Git 版本号、参数、结果记录在 Application 的同步历史(history)里。回滚时,管理员只需指定历史中的某个版本,ArgoCD 会重新创建对应的旧版本状态,然后执行一次“反向同步”。
技术细节:这个过程的本质是“把目标状态切回旧版本,再同步一次”,而不是像数据库那样做逆操作。因为所有期望状态都完整地存在于 Git 历史里,ArgoCD 只是换一本旧菜谱,重新指挥后厨。你可以用 argocd app rollback <APP> <historyID> 之类的命令完成。
主管翻开工作日志,找到上午那版,重做。客人满意了。这一切发生在几分钟内,而且每一步都有审计记录。可等等——如果后厨人人都有权改菜谱,那不乱套了?这就说到门禁。
- 历史版本 $\text{history}_i$Application 的同步历史中的第 i 个状态快照,比如“上午 10 点那版菜谱”。
- 反向同步 $\xleftarrow{\text{sync}}$ArgoCD 执行一次以旧版本为期望状态的同步,把集群拉回到历史状态。
- 当前状态 $\text{current}$被替换前的实际集群状态,回滚完成后会变成 history_i。
RBAC权限
后厨里,帮厨、打荷、甜点师、主厨,职责各不相同。如果所有人都能拿到“万能钥匙”,菜谱被乱改只是时间问题。ArgoCD 的 RBAC 就是这扇后厨门禁:谁可以进哪个区域、碰哪本菜谱,全部白纸黑字写着。
ArgoCD 的 RBAC 模型基于 Kubernetes 的 Role/ClusterRole 和 RoleBinding。Role 定义了“能对什么资源做什么操作”,RoleBinding 则把角色绑定到具体的用户或服务账号。比如 role:readonly 只能看不能改,role:admin 才可以触发同步和删除应用。
除了基础 RBAC,ArgoCD 还提供 Project(项目)级别的隔离。每个 Project 划定自己的源仓库白名单、目标集群白名单和可用角色,相当于把后厨分成中餐区、西餐区、甜点区,谁也不能跨区操作。更进一步,你可以对接企业 SSO(单点登录)和审计系统,让每一次“进后厨”都可追溯。
门禁装好了,后厨安分了不少。然而,光靠品控主管一个人盯着是不够的——菜谱经常要改,食材从哪里来?这就该聊聊采购团队(CI)和品控主管的配合了。
- 用户 u、动作 a、对象 o一次权限判断的三个要素——谁、干什么、对什么资源干。
- 角色 role(a, o)角色声明了“允许的动作-对象”集合,相当于岗位说明书。
- 绑定 bind(u, role)把用户和岗位说明书绑定在一起,ArgoCD 的 RoleBinding 正是做这件事。
CI流水线集成
品控主管只负责“按菜谱做菜”,可他不会亲自去菜市场买食材。食材的采购、清洗、切配,早在进厨房之前就该完成。在软件世界里,这个“采购预处理”团队叫 CI(持续集成)。
开发提交代码后,CI 流水线(Jenkins、GitHub Actions 等)会编译代码、跑测试、构建镜像并打上版本标签,然后推送到镜像仓库(如 Harbor、Docker Hub)。关键在于:CI 通常不直接连接 Kubernetes 集群部署,而是把最新的镜像标签写回 Git 仓库,更新配置清单中的 image 字段。
ArgoCD 一旦检测到 Git 仓库的新提交,就自动开始同步:拉取新镜像、滚动更新应用。这就是“构建在 CI,发布在 CD,真理在 Git”的完整闭环。还可以借助 ArgoCD Image Updater 定时扫描镜像仓库,发现新 tag 后自动更新 Git 仓库中的版本号,实现 AI 工程中最常见的“训练出新模型→自动上线”链路。
采购团队和品控主管完美配合,整个餐厅的菜品更新进入自动化流水线。可这时后厨又来了个“AI 特调”窗口——模型服务的部署,也能这么玩吗?
- 新镜像标签 $\text{tag}$CI 构建产物打上的版本号,如 v1.2.0,相当于采购回来的“新鲜食材批次”。
- 更新菜谱 $\text{patch}(G_{\text{repo}},\ \text{tag})$修改 Git 仓库中配置文件的 image 字段,把菜谱中的指定食材换成新批次。
- 触发同步 $\text{ArgoCD}(\cdot)$ArgoCD 看到 Git 变化后自动执行同步,完成最终部署。
MLOps模型交付
如今,很多餐厅在菜单末尾加上一页“AI 特调”:由算法调整配方的分子料理。这些料理的“配方”往往来自数据科学家团队训练的模型——变化快、实验多、还经常要回滚。用 GitOps 来管正合适。
在 MLOps 实践中,模型本身连同它的推理服务代码、配置模板一起被纳入 Git 仓库管理。每次训练产出新模型,就把它封装进模型推理镜像(如基于 Triton 或 TorchServe),推入镜像仓库,然后更新 Git 中的部署清单。ArgoCD 自动完成:滚动替换旧 Pod、金丝雀发布、健康检查失败自动回滚。
Kubernetes 的滚动更新配合 ArgoCD 的自动同步,可以实现真正的“金丝雀发布”:先切 5% 流量给新模型,观察准确率/延迟指标,再逐步放大比例。这一切的期望状态仍然由 Git 仓库中的 YAML 描述——模型版本、副本数、内存限制,一目了然。模型服务出了问题?切换回旧版本 tag 只需一次 Git commit。
从传统 Web 服务到 AI 模型服务,“菜谱至上”的老规矩一脉相承。MLOps 工程师们,正如同既懂算法又懂后厨的新派厨师——他们需要的不只是神奇的配方,更是一套能让配方稳定复现的厨房纪律。
- 模型服务状态 $S_{\text{model}}$线上推理服务的实际运行状态,包括每个 Pod 的镜像版本和资源配置。
- 服务配置 $G_{\text{repo}}$描述模型服务副本数、HPA 策略、存活探针等期望配置的 Git 文件。
- 指定版本镜像 $\text{registry}(\text{version})$镜像仓库中对应某一版本的模型服务镜像,如 monitor/inference:v20240615。
AI 应用场景
模型服务的金丝雀发布
阶段:模型部署与发布
解决的问题:传统上线方式中,新模型直接替换全部实例,一旦效果崩了,所有用户立刻受影响。ArgoCD 可以做到先在 Git 中把新模型镜像 tag 写入 Deployment,通过调整副本比例渐进切换流量,出问题随时回滚。
具体案例:某电商搜索团队训练了新推荐模型,需要将线上 20 个推理实例逐步切换。MLOps 工程师在 Git 仓库更新镜像版本为 v2-canary,并配置 HPA 分阶段放大流量,ArgoCD 自动同步;观察 30 分钟的 CTR 与 P99 延迟后,再提交 full-release 完成全量切换。
多环境配置一致性管理
阶段:环境管理与配置同步
解决的问题:开发、预发、生产环境配置不统一,手工部署经常导致“在我机器上是好的,上了生产就崩”。GitOps 让三个环境分别使用 Git 仓库的不同目录,一次提交即可自动同步到所有环境。
具体案例:一家金融科技公司将 dev/staging/prod 三个环境的配置分别放在 Git 仓库的不同目录下,每个集群的 Application 指向对应目录。一次配置变更只提交一条 PR,ArgoCD 自动让三套环境保持一致,彻底消灭了“环境差异”引发的故障。
生产环境违规改动的自动纠正
阶段:运维监控与漂移检测
解决的问题:有同事登录生产集群手工修改了 Deployment 副本数,第二天高峰期服务过载没人承认。开启 selfHeal 后,ArgoCD 在几十秒内自动恢复为 Git 中的声明状态,并触发审计告警。
具体案例:某互联网公司 SRE 团队在核心链路开启 selfHeal,监控发现一次凌晨 2 点的非预期资源变更被 ArgoCD 自动纠正,审计日志定位到某实习生误操作,全程业务无感知。
Python 演示
#!/usr/bin/env python3"""gitops_simulator.py - 模拟 ArgoCD 的同步收敛循环""" from typing import Dict, List class GitRepo: """模拟 Git 仓库,保存期望状态(菜谱)""" def __init__(self, desired: Dict): self.desired = desired def read_apps(self) -> List[Dict]: return self.desired["apps"] class K8sCluster: """模拟 Kubernetes 集群上的实际状态(后厨菜品)""" def __init__(self): self.live: Dict[str, Dict] = {} self.sync_count = 0 def diff(self, desired: List[Dict]) -> List[Dict]: changes = [] for app in desired: name, version = app["name"], app["version"] if name not in self.live: changes.append({"name": name, "version": version, "action": "CREATE"}) elif self.live[name]["version"] != version: changes.append({"name": name, "version": version, "action": "UPDATE"}) for name in list(self.live.keys()): if name not in [a["name"] for a in desired]: changes.append({"name": name, "action": "DELETE"}) return changes def apply(self, changes: List[Dict]) -> None: for ch in changes: if ch["action"] == "DELETE": self.live.pop(ch["name"], None) else: self.live[ch["name"]] = {"version": ch["version"]} self.sync_count += 1 def snapshot(self) -> Dict[str, Dict]: return self.live class ArgoCD: """ArgoCD 控制器:循环比较并收敛""" def __init__(self, repo: GitRepo, cluster: K8sCluster): self.repo = repo self.cluster = cluster def reconcile(self) -> List[Dict]: return self.cluster.diff(self.repo.read_apps()) def sync_once(self) -> List[Dict]: changes = self.reconcile() if changes: self.cluster.apply(changes) return changes def main() -> None: desired_state = { "apps": [ {"name": "auth-api", "version": "v1.2.0"}, {"name": "order-api", "version": "v2.0.1"}, {"name": "ml-inference", "version": "v3.1.0"}, ] } repo = GitRepo(desired_state) cluster = K8sCluster() argocd = ArgoCD(repo, cluster) print("第 1 轮同步:部署全部应用") for ch in argocd.sync_once(): print(f" [{ch['action']}] {ch['name']}:{ch['version']}") print("\n开发者把 ml-inference 升级为 v3.2.0 并 push 到 Git") repo.desired["apps"][2]["version"] = "v3.2.0" print("\nArgoCD 巡检发现漂移:") for ch in argocd.reconcile(): print(f" 需要 {ch['action']}: {ch['name']} -> {ch.get('version', '')}") print("\n自动同步执行:") for ch in argocd.sync_once(): print(f" [{ch['action']}] {ch['name']}:{ch['version']}") print("\n最终集群状态:") for name, cfg in cluster.snapshot().items(): print(f" {name}: {cfg['version']}") if __name__ == "__main__": main()
class GitRepo:模拟 Git 仓库,保存期望状态,相当于钉在墙上的《标准菜谱》。def diff(self, desired: List[Dict]) -> List[Dict]:品控主管拿着菜谱逐道核对成品,返回需要创建、更新或删除的差异清单。changes.append({"name": name, "version": version, "action": "CREATE"})发现菜谱里有、后厨没有的“新菜”,记录为待创建。elif self.live[name]["version"] != version:同名的菜但版本不一致,说明这道菜需要“按新菜谱重做”。for name in list(self.live.keys()):反过来检查后厨里有、菜谱上却已下架的菜,记录为待删除。def apply(self, changes: List[Dict]) -> None:主管下令整改,把差异清单逐项落实。self.sync_count += 1记录同步次数,相当于工作日志里的“整改记录”。def reconcile(self) -> List[Dict]:执行一轮“读菜谱、做对比”的完整巡检。repo.desired["apps"][2]["version"] = "v3.2.0"模拟一次 Git 提交:把 ml-inference 这道“AI 特调菜”的菜谱版本升级。argocd.sync_once()自动同步:发现差异后立即执行整改,让集群状态向 Git 状态收敛。
常见误区
误区CI/CD 和 GitOps 不是一回事吗?我们项目里早就用流水线自动部署了,应该已经在用 GitOps 了吧,还需要 ArgoCD 吗?
正解这俩像“采购团队”和“品控主管”的分工。CI/CD 解决“代码如何变成镜像并发布”的自动化;GitOps 则是一种以 Git 为唯一事实来源、由控制器持续收敛集群状态的部署理念。你的流水线可能是“手动触发 + 脚本部署”,而 GitOps 要求所有变更先写回 Git,再由 ArgoCD 自动同步。关键区别不是有没有自动化,而是 Git 是否是唯一的“发布开关”。
为何常见:因为 CI/CD 与部署流水线经常同时出现,二者名字都带“持续”,界面又都在同一条流水线里,很容易混为一谈。
误区只要把新镜像推到 Docker Hub,ArgoCD 的 automated 同步就会自动拉取并部署,应该不用管 Git 吧?
正解ArgoCD 只认 Git,不直接监听镜像仓库。automated 的含义是“Git 里状态变化后自动同步”,它不会感知镜像仓库里的新 tag。想要自动追踪镜像,得额外部署 ArgoCD Image Updater,而它所做的也是先修改 Git 仓库中的 image 字段,再触发同步。只要 Git 配置没变,镜像再新也不会出现在集群里。
为何常见:因为 automated 这个词容易让人联想到“自动跟随镜像更新”,而忽略了它真正的含义是“自动执行 Git 声明状态的同步”。
误区生产环境新版本出问题,我直接 git revert 上一次提交再 push,ArgoCD 就会回滚,对吧?
正解git revert 会产生一条“反向修改”的新提交,相当于“在最新菜谱上写一个补丁”;而 ArgoCD 的 rollback 是把目标状态切回历史某个版本并重新同步,更直接、更贴近“恢复到当时那版成品”。revert 虽然也能达到类似效果,但会改动 Git 历史结构,且需要重新校验依赖。真正紧急时,用 argocd app rollback 切到指定 history 更干净。
为何常见:因为日常 Git 操作里 revert/reset 是常规回退手段,容易把 Git 的“记录逻辑”套用到 GitOps 的“状态同步逻辑”上。
误区为了排查问题方便,给所有工程师都绑上 admin 角色,反正有 ArgoCD 管着,不会出什么大事吧?
正解admin 意味着可以删除 Application、随时触发同步,等于给整间后厨发了万能钥匙。一旦有人误操作,ArgoCD 并不会阻止——它只会忠实地执行 Git 的声明,而 admin 可以直接绕过流程。正确做法是按最小权限分配角色,用 Project 隔离边界,并对操作日志做周期审计。权限放得越宽,GitOps“全自动”的优势就越容易变成“全自动事故”。
为何常见:因为配置细粒度角色需要理解 RBAC 模型,初期调试时为了省事直接上 admin,之后便一直沿用,埋下安全隐患。
面试题
Q1. GitOps 中,“单一事实来源”指的是什么?
- A.镜像仓库中的最新镜像
- B.Kubernetes 集群的当前状态
- C.Git 仓库中的声明式配置← 正确答案
- D.开发人员的本地代码
答案:C。GitOps 主张 Git 仓库中的声明式配置是集群状态的唯一事实来源。镜像仓库存放的是构建产物,是“食材”不是“菜谱”;集群当前状态是“成品”,可能因违规改动而漂移;本地代码尚未经过评审与提交,只有 Git 仓库中的配置被 ArgoCD 视为权威期望状态。
Q2. 首次部署时,ArgoCD 通过哪个对象声明“菜谱位置”?
- A.Deployment 对象
- B.Application 对象← 正确答案
- C.Namespace 对象
- D.ConfigMap 对象
答案:B。ArgoCD 用 Application 这个自定义资源来描述“菜谱位置、做菜地点和整改纪律”。Deployment 是 Kubernetes 里的业务工作负载,Namespace 是隔离空间,ConfigMap 是配置数据,它们都不是 ArgoCD 的点单入口。
Q3. ArgoCD 中负责比对 Git 与集群差异的组件是?
- A.repo-server
- B.application-controller← 正确答案
- C.api-server
- D.redis-server
答案:B。application-controller 是 ArgoCD 的核心稽查员,周期比对 Git 期望状态与集群实际状态;repo-server 负责拉取和缓存 Git 文件;api-server 负责对外接口;redis 只是缓存组件。
Q4. 要开启同步后自动整改且抵御外部手工改动,应配置什么?
- A.syncPolicy.automated 且 selfHeal: true← 正确答案
- B.syncPolicy.automated 且 prune: false
- C.syncPolicy.manual 且 selfHeal: true
- D.syncPolicy.manual 且 retry: true
答案:A。自动整改需要 automated 为 true,且 selfHeal 打开才能把外部手动修改也纠正回来。prune: false 反而会保留被删除的资源,manual 模式不会自动同步,所以只有 A 组合完整满足需求。
Q5. 如果生产环境新版本出问题,ArgoCD 回滚的本质是什么?
- A.执行 kubectl undo 撤销上次变更
- B.反转镜像 tag 并自动 commit
- C.以历史版本为目标重新同步← 正确答案
- D.停止所有 Pod 等待人工排查
答案:C。ArgoCD 的回滚不是“撤销”操作,而是把目标状态切换为历史的某个版本并重新执行同步。kubectl undo 并非标准命令;反转 tag 仍需在 Git 中声明;停止所有 Pod 是不负责任的做法。C 准确地描述了回滚机制。
Q6. ArgoCD 中 Project 的主要作用是?
- A.把 Git 仓库包成私有 Helm 仓库
- B.隔离不同应用的资源与权限边界← 正确答案
- C.加速镜像拉取并缓存本地层
- D.自动生成 Kubernetes 的 Service
答案:B。Project 提供资源隔离与权限边界,限制哪些仓库、集群和角色可被使用。它不把 Git 变成 Helm 仓库,不缓存镜像,也不自动生成 Service,这正是 ArgoCD 多租户场景的核心能力。
Q7. 在纯 GitOps 流程中,CI 流水线完成镜像构建后,下一步正确做法是?
- A.直接 kubectl set image 到生产集群
- B.通过 Helm 手动升级 Release 再提交
- C.把新 tag 写回 Git 仓库触发同步← 正确答案
- D.上传镜像并把 tag 发给运维群
答案:C。纯 GitOps 流程要求一切变更先落 Git。CI 构建镜像后,应把新 tag 写入 Git 仓库的部署清单,由 ArgoCD 自动同步。直接 kubectl set image 会绕过声明式流程,手动 Helm 升级同样会造成集群与 Git 不一致,发消息给运维群更是倒退。
Q8. 以下哪些属于 ArgoCD 同步策略(syncPolicy)能配置的能力?
- A.自动同步(automated)← 正确答案
- B.自愈恢复(selfHeal)← 正确答案
- C.同步钩子(hooks)← 正确答案
- D.CI 代码编译(build)
答案:ABC。syncPolicy 能配置 automated、selfHeal 以及 hooks 等同步行为。“CI 代码编译”属于 CI 阶段,不归 syncPolicy 管。ArgoCD 管的不是“把代码变成镜像”,而是“把 Git 里的期望状态变成集群现实”。
Q9. 以下关于 ArgoCD 回滚机制的说法,正确的是?
- A.每次同步会生成一条历史记录← 正确答案
- B.回滚本质是切回旧状态并重新同步← 正确答案
- C.回滚不需要访问 Git 历史版本
- D.rollback 后会自动提交新 commit 到 main
答案:AB。ArgoCD 每次同步都会记录历史,回滚本质是切回旧状态再同步。回滚需要从 Git 历史读取配置,rollback 动作由 ArgoCD 完成,并不会主动向 main 分支提交新 commit,因此 C 和 D 都是错误的。
Q10. 在 MLOps 场景中使用 ArgoCD 部署模型服务时,合理的做法包括?
- A.模型推理镜像版本在 Git 中声明← 正确答案
- B.通过滚动更新实现金丝雀比例切换← 正确答案
- C.模型文件直接存放在 Deployment 中
- D.健康检查失败时自动回滚旧版本← 正确答案
答案:ABD。MLOps 场景下,模型推理镜像的版本应在 Git 中声明,流量切换可以通过滚动更新实现,健康检查失败时可配置自动回滚旧版本。模型文件通常应随镜像或对象存储提供,直接写进 Deployment 既不现实也无法做版本管理,因此 C 错误。