ArgoCon-EU-2025-笔记-全-
ArgoCon EU 2025 笔记(全)
001:为 ArgoCD 定义 SLO 与 SLI —— 一种基于指标的可观测性方法



在本节课中,我们将学习如何为 ArgoCD 定义服务等级目标(SLO)和服务等级指标(SLI)。这是一种以指标驱动的方法,旨在提升系统的可观测性,并确保服务可靠性符合用户期望。



核心概念介绍

上一节我们介绍了课程主题,本节中我们来看看几个核心概念。
服务等级指标 是一个可测量的指标,用于指示系统的性能或可靠性。对于 ArgoCD,示例可以是同步操作的成功百分比或同步操作的持续时间。
服务等级目标 是为 SLI 设定的目标,需要在特定时间段内达成。对于 ArgoCD 的示例,目标可以是:在过去 30 天内,95% 的同步操作应在 20 秒内成功完成。
传统监控方法的利弊
传统监控方法是多年来系统可靠性的重要支柱。当需要调试某些事件或性能下降时,它是一个很好的工具。你可以构建仪表板,一眼就能看到所有系统信息。
以下是传统方法的一些优点:
- 它提供了历史数据和图表,使你能够分析并发现模式。
- 即时警报可以大大减少事件响应时间。
然而,传统方法也存在一些缺点:
- 它往往是反应式的。收到警报时,问题已经对客户产生了影响。
- 过多的警报会导致警报疲劳和数据过载。
- 一个最大的问题是:这些指标能回答“你的客户对服务满意吗”这个问题吗?
SLO 与 SLI 方法的转变

SLO 和 SLI 方法改变了我们看待服务可靠性的方式。我们应该选择以客户为中心的指标,即那些对客户重要且有用的指标。
拥有错误预算为你提供了一个工具和框架,让你可以采用数据驱动的方法来选择下一步工作的优先级。简单来说,如果你的 SLO 是 99.9%,那么剩余的 0.1% 时间或错误事件就是你的错误预算。这是你假设可以接受的服务降级水平。

为 ArgoCD 定义 SLO 的实践步骤

当我们开始为 ArgoCD 制定 SLO 时,我们从 CI 系统的经验中获得了灵感。最初,我们面对 ArgoCD 提供的数十个指标感到无从下手。这些指标并没有帮助最终用户更好地理解我们系统的健康状况。
因此,我们退后一步,思考如何将指标转化为有意义的 SLO。以下是我们的方法:
首先,你需要识别关键用户旅程。思考用户在系统中为实现目标所采取的关键路径。然后,将这些旅程映射到每个步骤上的一些可测量事件。接着,这些事件应转化为来自 ArgoCD 或其周边系统的可用指标,以帮助你构建指标并将其转化为布尔指示器(成功或失败)。最后,你可以计算成功事件或失败事件的百分比。
一旦我们定义了指标,就需要为它们设定目标。如何做到这一点?首先,分析历史性能数据。基于此,我们可以设定既可实现又对我们平台工程师有意义的目
标。同时,我们还需要考虑用户期望和业务需求。我们的系统平台需要足够好,以满足他们的使用。
一个好的建议是从保守的目标开始,在达到较低目标后再向更高目标迈进。当然,由于在关键路径上的重要性不同,我们系统的不同组件可能有不同的目标。最后,我们始终需要与客户沟通,并根据他们的反馈进行调整。
ArgoCD 部署流程与常见瓶颈
让我们思考一下 ArgoCD 内部部署流程中可能出现的常见瓶颈。以下是简化的部署流程:
- ArgoCD 触发检测(通过 Webhook 或从 Git 拉取)。
- 获取 Git 仓库源码。
- 通过 Helm 和 Kustomize 生成清单。
- 应用控制器协调,获取应用期望状态并计算需应用的差异。
- 使用 Kubernetes API 更新和创建新资源。
- 评估这些资源的健康状况。
- 同步完成,触发同步后钩子。
- 发送配置的通知。
以下是该流程中常见的瓶颈:
- Git 操作:大型仓库、网络问题或同时处理大量仓库可能导致请求耗时显著增加。
- 清单生成:复杂的 Helm 图表可能需要大量时间处理。
- 资源更新与协调:严重依赖目标 Kubernetes 集群的 API 速度。
- 用户界面:用户习惯通过 UI 检查部署状态,如果 UI 不可用或缓慢,会让他们感到焦虑。
但我们需要记住,这是我们作为平台工程师对部署旅程和流程的看法。对于许多开发者来说,他们需要简单性:提交代码,然后“黑箱”完成部署。对他们来说,重要的问题是:我的代码是否成功部署?部署花了多长时间?我能否检查部署状态?
优化 SLO 与 SLI 列表
我们开始着手改进 SLO 和 SLI 列表。首先,我们移除了一些不必要或无用的指标。例如,ApplicationSet 在我们平台中仅用于创建新服务,且服务上线流程耗时较长,但我们从未收到相关投诉,因此决定暂时隐藏这些指标。
接下来是重新审视一些 SLI 的查询。例如,最初我计算了所有事件,但后来意识到我们的 ArgoCD 同时处理生产和非生产环境的部署,包括一些设计上允许失败的预发布环境。因此,在查询中,我选择了仅针对生产目标集群的指标。
最后,我将一些指标合并为更复杂的查询。例如,Git 请求性能原本为不同类型的请求单独计算,但可以创建一个包含不同目标的查询,并将其合并为一个指标。
修订后的 SLO 列表示例
以下是修订后的 SLO 列表示例(部分目标仍在优化中):
- 应用健康与同步成功率:仅计算生产环境的应用。
- Repo 服务器 Git 请求性能:衡量 Git 操作性能。
- Pending Git 请求:计算 5 分钟间隔内的最大值,有助于捕获未被第一个 SLI 覆盖的卡住事件。
- Pending Kubernetes 请求:对 Kubernetes API 请求采用相同方法。
- Kubernetes 请求可靠性:将 404 视为成功事件,因为并非所有资源在部署前都存在于目标集群。
- 应用控制器协调性能:为生产和非生产环境设置不同的 SLO。
- 队列等待时间:一个复杂的查询,合并了不同类型工作队列的计算,但设置了不同的目标。
为了弥补合并查询可能降低的可见性,我们构建了补充仪表板。例如,左侧显示一个错误率的数字,右侧则用图表展示不同类型事件的情况,这样就能清晰地看出是协调队列出了问题。
后续步骤与总结
我们可能的后续步骤包括:
- 持续改进:重新审视 SLO,并与关注它们的人员保持沟通。
- 更新仪表板:添加更多像上一节提到的补充图表。
- 利用 CI 指标:使用 CI 系统的指标来计算与 Git 流程相关步骤的性能和可靠性。
- 利用 Webhook:构想利用 ArgoCD 的 Webhook 通知来构建服务,计算端到端部署时间或应用处于不同步状态的时间等高级指标。
本节课中我们一起学习了为 ArgoCD 定义 SLO 和 SLI 的方法。总结如下:
- 谨慎选择能代表系统潜在问题的正确指标和查询。
- 在错误预算耗尽时设置警报,以便主动处理系统可靠性和性能问题。
- 持续改进并与 SLO 的利益相关者保持沟通。
- 采用基础设施即代码的方法(如 Terraform)来管理 SLO 配置,便于迭代和回滚。
- 保持 SLO 简单明了:一个简单的数字,辅以解释性的附加信息。

感谢你的关注。
002:使用 Argo Rollouts 和 Kubernetes Gateway API 实现多向流量渐进式交付



概述
在本节课中,我们将学习如何结合使用 Argo Rollouts、Kubernetes Gateway API 和 Istio Ambient Mesh 来实现一个面向生成式 AI 应用的、安全且可观测的渐进式交付流程。我们将通过一个实际演示,展示如何控制入口、出口和东西向流量,并安全地推出新版本应用。

自我介绍与背景
我的名字是 Lynn Song,是 Solo.io 公司的开源负责人。我来自美国东海岸北卡罗来纳州的一个小镇。今天早上我了解到,我的公司是所有 CNCF 项目的最大贡献者,这让我作为开源负责人感到非常自豪。
今天,我将向大家介绍 Kubernetes Gateway API、Istio Ambient Mesh 和 Argo Rollouts,并展示一个我自己开发的生成式 AI 演示应用。
核心组件介绍
上一节我们进行了简单的介绍,本节中我们来看看演示中将用到的几个核心项目和概念。


以下是本次演示将使用的主要组件:
- Kubernetes:作为基础容器编排平台。
- FluxCD:用于 GitOps 持续交付。
- Istio & Gateway API:用于服务网格和流量管理。
- Argo Rollouts:用于实现金丝雀发布等渐进式交付策略。
- Streamlit:用于构建演示应用的前端 UI。
- Prometheus & Kiali:用于监控和可视化服务网格流量。
- Ollama:用于在本地运行大型语言模型(LLM)。



Istio Ambient Mesh 简介
在深入演示之前,我们需要先理解 Istio Ambient Mesh 的核心概念。它与传统 Istio 的主要区别在于架构。
传统 Istio 在每个应用 Pod 中注入一个 Envoy 代理(sidecar)。而 Ambient Mesh 引入了两种新的组件:
- ztunnel:这是一个运行在节点上的 L4 代理,用于处理节点上所有 Pod 的相互 TLS(mTLS)和简单的授权策略。它用 Rust 重写,比 Envoy 更轻量。
- waypoint proxy:这是一个按需部署的 L7 代理。租户(例如命名空间)可以共享一个 waypoint 代理来处理 HTTP、gRPC 等 L7 流量,从而将代理与业务 Pod 解耦。
启用 Ambient 模式非常简单,只需为命名空间添加标签即可,无需重启应用 Pod。
# 启用 Ambient Mesh 并指定使用 waypoint 代理
kubectl label namespace default istio.io/dataplane-mode=ambient
kubectl label namespace default istio.io/use-waypoint=true
演示环境概览
现在,让我们进入实际的演示环节。首先,我来展示一下预先设置好的 Kubernetes 集群环境。
我的 Kind 集群中已经安装了以下组件:
- Argo Rollouts 控制器
- Argo CD
- 一个简单的客户端应用(用于发送 curl 请求)
- 演示用的 AI 应用
- 部署在
default和egress-istio命名空间中的 waypoint 代理 - Istio Ingress Gateway
- Istio Ambient(包含 ztunnel)
- Prometheus 和 Kiali
- 在集群外本地运行的 Ollama(LLM 服务)
为了控制出口流量(例如访问集群外的 Ollama),我创建了一个 ServiceEntry 资源。它指示流量在访问特定主机时,应该经过 egress 命名空间的 waypoint 代理。

同时,我使用 Kubernetes Gateway API 定义了三种网关类(GatewayClass)来控制不同方向的流量:
- ingress 类:控制从集群外部进入的流量。
- egress 类:控制从集群内部流向外部服务的流量。
- waypoint 类:控制集群内部服务间的东西向流量。
Gateway API 的 status 字段对于调试非常有用。
演示第一部分:基础应用与流量可视化
一切就绪,让我们启动演示应用。首先,我将端口转发到 Istio Ingress Gateway,以便从外部访问应用。
应用前端是一个简单的界面,允许用户提问。我问了第一个问题:“伦敦最值得做的三件事是什么?”。请求的流向是:
- 用户 -> Istio Ingress Gateway
- Ingress Gateway -> 演示应用 Pod
- 演示应用 Pod ->
egresswaypoint 代理 egresswaypoint 代理 -> 集群外的 Ollama 服务(使用 Llama2 模型)
现在,让我们在 Kiali 控制台中查看流量图。你可以清晰地看到请求是如何流经各个组件的:从 Ingress Gateway,到应用,再到 waypoint,最后到达外部服务。所有流量都通过 mTLS 进行了加密。

演示第二部分:集成 RAG 与 Argo Rollouts 发布

我对当前应用的回答质量不满意,因为它对特定领域知识(如 Argo Rollouts 和 Ambient Mesh)不了解。为了解决这个问题,我决定集成一个 RAG(检索增强生成) 微服务,它能够基于我提供的文档来回答问题。
我使用 Argo CD 来部署这个新的 RAG 服务。Argo CD 会监控我的 Git 仓库,并将其中定义的 Kubernetes 资源同步到集群中。这些资源包括:
- RAG 服务的 Deployment 和 Service。
- 一个 Rollout 资源,定义了金丝雀发布策略。
- 一个 AnalysisTemplate,用于在发布过程中基于 Prometheus 指标(如 HTTP 成功率)进行自动验证。
部署完成后,我尝试上传一个关于 Ambient Mesh 的 PDF 文档,并再次提问。这次,RAG 服务成功地基于文档给出了准确的回答。
演示第三部分:执行金丝雀发布
虽然 RAG v1 能处理 PDF,但我希望 v2 版本还能支持 TXT 文件。我已经构建并推送了新的镜像。

现在,我们使用 Argo Rollouts 来执行一次金丝雀发布,将应用从 v1 升级到 v2。
# 触发 Rollout,更新镜像版本
kubectl argo rollouts set image rag rag=your-image:v2

Rollout 过程开始:
- 暂停 - 手动验证:首先,v2 的 Pod 启动,但流量不会自动过去。我通过设置特定的 HTTP 头(
X-Canary: rollout-canary)将我的测试流量导向 v2,并验证 TXT 文件上传功能是否正常。 - 自动推进 - 60% 流量:在 Argo Rollouts 仪表板上,我点击“Promote”。Rollout 进入下一阶段,将 60% 的流量切到 v2。Argo Rollouts 会自动查询
AnalysisTemplate中定义的 Prometheus 指标,检查错误率。 - 自动推进 - 100% 流量:由于指标健康,Rollout 自动完成,将 100% 流量切换到 v2,并逐步终止 v1 的 Pod。
在整个过程中,Kubernetes Gateway API 的 HTTPRoute 资源与 Argo Rollouts 协同工作,动态地将流量权重在 stable 和 canary 服务之间进行分配。


总结与挑战
本节课中,我们一起学习了如何构建一个现代化的云原生应用交付流水线。我们整合了多项技术:
- 使用 Kubernetes Gateway API 统一管理了入口、出口和东西向流量。
- 利用 Istio Ambient Mesh 提供了零信任安全层(mTLS),而无需修改应用。
- 通过 Argo Rollouts 实现了安全、自动化的渐进式发布。
- 借助 Prometheus 和 Kiali 实现了发布过程的可观测性。
最终,我们成功地将一个不理解领域知识的 AI 应用,通过集成 RAG 和安全地金丝雀发布,升级成了一个能够基于特定文档进行智能回答的应用。
我的挑战是:在了解了如何使用 Gateway API、Ambient Mesh、Argo Rollouts 和 Kubernetes 构建如此酷炫的应用之后,请你也动手构建一些有趣的东西吧!也许我们能在下一届 ArgoCon 大会上见到你的分享。


003:Argo 知识问答!



在本节中,我们将通过一个模拟的问答环节,快速回顾和测试关于 Argo 项目及其子项目的核心知识。我们将逐一解析问答中涉及的关键概念,帮助你巩固理解。
现在,让我们开始问答。

第一个问题:什么是 Argo 项目?
大多数人都答对了。Argo 是一个开源的云原生工具集,用于在 Kubernetes 上运行工作流、管理集群以及实现 GitOps 风格的持续交付。
第二个问题:哪个 Argo 子项目主要用于基于声明式 GitOps 的持续交付?
这个问题比较简单。答案是 ArgoCD。ArgoCD 是一个为 Kubernetes 而生的声明式 GitOps 持续交付工具。
上一节我们介绍了 ArgoCD 的用途,本节中我们来看看它的一个核心功能。
第三个问题:ArgoCD 的哪个功能能够实现 Git 仓库中应用清单的自动同步?
这个问题稍有难度。答案是 自动同步(Auto-Sync)。当启用此功能后,ArgoCD 会持续监控 Git 仓库,并在检测到清单文件与集群中运行的应用状态不一致时,自动进行同步。
接下来,我们关注另一个重要的子项目:Argo Rollouts。
第四个问题:Argo Rollouts 提供哪些高级部署策略?
今天上午已经有几个关于 Rollouts 的演讲,看看大家是否认真听了。答案是 蓝绿部署和金丝雀发布。Argo Rollouts 扩展了 Kubernetes 的 Deployment 资源,提供了这些更安全、可控的部署方式。
那么,Argo Rollouts 具体扩展了哪种 Kubernetes 资源呢?这就是我们的下一个问题。
第五个问题:在 Argo Rollouts 中,它扩展了哪种 Kubernetes 资源来实现渐进式交付?
答案是 Deployment。Argo Rollouts 通过自定义资源定义(CRD)引入了 Rollout 资源,它是对标准 Kubernetes Deployment 的增强。
现在,让我们转向用于事件驱动的子项目:Argo Events。
第六个问题:事件源(Event Source)在 Argo Events 中扮演什么角色?
很好,看来大家都了解 Argo Events。事件源负责 从外部系统(如 webhook、消息队列、日历等)检测和消费事件,并将其转化为 Argo Events 可以处理的内部事件。
了解了事件源,我们来看看触发器。以下是关于 Argo Events 触发器的问题。
第七个问题:以下哪项不是 Argo Events 中有效的触发器?
这个问题难住了一些人。常见的有效触发器包括启动一个 Argo Workflow、发送一个 Slack 消息等。无效的选项需要根据具体题目判断,但核心在于理解触发器是用于定义事件发生后要执行的动作。
接下来,我们回到 Argo Workflows。
第八个问题:使用 Argo Workflows 进行 Kubernetes 原生工作流编排的主要优势是什么?
除了它来自最棒的开源项目这一点。主要优势在于它能够 将复杂的工作流定义为 Kubernetes 资源,利用 Kubernetes 的调度、资源管理和弹性能力来运行多步骤的流水线或批处理作业。
现在,让我们深入一些中级问题,看看 ArgoCD 如何管理应用状态。
第九个问题:ArgoCD 如何检测 Kubernetes 应用中的漂移?
答案是 通过持续比较 Git 仓库中声明的期望状态与 Kubernetes 集群中的实际运行状态。当两者不一致时,ArgoCD 会将其标记为“不同步(OutOfSync)”。
最后是两个趣味知识题。
第十个问题:Argo 吉祥物头盔里有什么?
这可能是最难的问题。答案是 太空章鱼。Argo 的吉祥物是一只戴着太空头盔的章鱼,象征着其灵活、多触手(集成多工具)且适用于云原生“太空”的特性。
第十一个问题:第一届 ArgoCon 在哪里举行?
对于元老级用户来说,应该知道。答案是 线上虚拟会议。早期的 ArgoCon 是以虚拟形式举办的。
问答环节结束。恭喜获奖者!
以下是本场问答的最终排名:
- 第三名:Villiaus
- 第二名:Martton
- 第一名:Felix B
请注意,下一场演讲将在10分钟后开始。
本节课中我们一起学习了 ArgoCD 的自动同步与漂移检测、Argo Rollouts 的部署策略及其扩展的 Kubernetes 资源、Argo Events 的事件源与触发器角色,以及 Argo Workflows 的编排优势。通过问答形式,我们快速回顾了这些核心概念,希望帮助你加深对 Argo 项目生态的理解。


005:一统江湖的引擎——使用 Argo Workflows 统一云工作负载


在本节课中,我们将探讨如何利用 Argo Workflows 作为统一的调度引擎,来整合和管理多样化的云工作负载。我们将从背景和问题出发,介绍两种核心策略(迁移与集成),并通过具体示例说明实现方法,最后总结成果与展望。
背景介绍
我是 Sebastian,来自德国吉森大学,是一名分布式系统研究员和 DevOps 工程师。我们团队专注于云计算,特别是从计算角度为生命科学研究提供支持。作为生物信息学背景的研究者,我们需要处理海量序列数据的计算任务,因此对计算能力有很高要求。
我们大学是德国一个大型网络的一部分,为生命科学研究人员提供社区云服务。研究人员可以免费获得存储、计算等资源。我们提供了 OpenStack 环境,并大量投资于 Kubernetes,这也是我们今天讨论 Argo Workflows 的原因。此外,我们还拥有一些 HPC 实例和供用户使用的虚拟机。
我们的 Argo Workflows 之旅始于大约五年前。我的硕士论文主题就是关于如何利用 Kubernetes 和 Argo Workflows 来满足计算需求。我们在这方面相当成功,目前运行着近 12 个集群用于计算任务,最大的一个集群拥有约 5000 个核心。我们有些工作流会运行数天甚至数周,有些工作流则拥有大量 Pod(我见过最大的约有 3 万个 Pod)。我们主要将这些工作流用于分析任务:用户提交数据,进行分析,然后获得结果和可视化报告。
我们开发的一个非常有用的模式是:一个 Kubernetes 集群、一个允许用户上传数据的 Web 前端、一个简单的 API。这个 API 与 Argo Workflow 集群通信,基于工作流模板调度工作流。通过这种方式,我们建立了一个易于使用的按需计算系统。
为什么选择 Argo Workflows?
我们选择 Argo Workflows 的原因如下:
- 灵活性高:几乎可以用它完成所有任务。
- 可扩展性强:拥有插件系统和工作流模板,可以作为工作流的构建块。
- 易于 API 访问:可以通过标签和注解将数据与工作流一起存储,这样后端就不需要数据库了。
- 事件系统完善:可以通过外部事件触发工作流,便于与消息队列等外部世界进行深度自动化集成。
- 与 Kubernetes 深度集成:作为 Kubernetes 上事实标准的工作流引擎,几乎是唯一选择。
- 生态系统庞大:例如 Python 库、ArgoCD 集成、Argo Rollouts 等,使用起来非常方便。
面临的问题
然而,我们的现实情况有所不同。我们有许多用户,其中大多是博士生,他们带着自己的想法和各自的工作流引擎而来。因此,我们不得不管理一个由众多工作流引擎、工具和环境组成的“大杂烩”。其中很多系统在开发者离开后仍需维护,这给我们带来了巨大的管理负担。
公有云的承诺是“一切尽在掌握”,提供统一包装和 API。但自己搭建时,往往会得到许多专为特定场景设计的工具,它们不易集成,且维护成本高昂。这样做的好处是独立自主、数据保护更强,但缺点也很明显:同时维护数十个系统需要大量人力资源和专业知识,新成员上手也非常困难。
解决方案:统一调度引擎
大约两年前,我们提出了一个问题:Argo Workflows 能否成为我们所有任务的通用调度引擎?
最初的答案是“也许”。经过进一步思考,我们认为答案是“可以”。为此,我们制定了两种策略:
- 迁移:将现有工作流改造成 Argo Workflow。
- 集成:对于无法轻易迁移的系统,保持原样,使用 Argo Workflow 作为触发器来启动、监控并收集结果。
决策依据
我们制定了一些决策指标:
- 是否有硬性要求(如法规要求)必须使用现有系统?如果是,则只能选择集成。
- 工作流是否非常复杂或小众?如果是,集成可能是更好的策略。
- 团队是否拥有足够的现有解决方案的专业知识?如果只有一名即将毕业的博士生在维护,那么迁移的压力就很大。
- 你的流水线是否可移植?是否已经是容器化的?迁移到容器有时也很棘手。
策略一:迁移示例
我们尝试迁移了一些 HPC 工作负载。我们的 Slurm 集群中有许多工作流可以很容易地用 Argo Workflows 重写,因为它们模式简单:数据输入、处理、结果输出。
遇到的主要挑战包括:
- 共享文件系统:Slurm 集群通常有共享存储,而在 Argo 中可能需要通过对象存储(如 S3)或
ReadWriteMany卷来传递数据。 - 共享权限:需要将 HPC 用户和基于角色的访问控制迁移到 Kubernetes 集群。
- 内部数据库访问:Kubernetes 集群可能无法直接访问某些内部数据库。
- 专用硬件:如 FPGA、GPU 等,需要在 Kubernetes 集群中提供同等能力。
对于 Apache Airflow 工作流,如果它们主要使用 Python 函数,那么迁移到使用 Hera(一个用于构建和运行 Argo Workflows 的 Python 库)就非常直接。通常可以重用原有函数,只需少量修改,一两天就能完成迁移。
对于无服务器函数(我们之前主要使用 Apache OpenWhisk),如果主要是 Python 函数,迁移也很容易。我们使用 UV 模板,UV 是一个快速的 Python 包安装器和解析器。它的优点是可以内联创建依赖,在运行时构建环境,之后自动清理,无需为每个任务构建专门的容器镜像。
策略二:集成示例
集成策略保持现有系统不变,使用 Argo Workflow 作为包装器。
以下是集成 HPC Slurm 工作负载的示例步骤:
- 准备步骤:从一个简单的镜像(如 Debian/Alpine)开始,将输入数据从云环境(如 S3)放入 HPC 共享环境。
- name: prepare-data container: image: debian:latest command: [sh, -c] args: ["# 将数据从S3复制到HPC共享目录的代码"] - 执行步骤:运行 Slurm 命令(例如
sbatch),并使用--wait参数等待作业完成。- name: run-slurm-job container: image: slurm-client-image command: [sbatch] args: ["--wait", "my_job_script.sh"] - 收尾步骤:从 HPC 共享环境中获取结果,并传回云存储(如 S3)。
- name: collect-results container: image: debian:latest command: [sh, -c] args: ["# 将结果从HPC目录复制回S3的代码"]
对于 Apache Airflow,集成方式类似:在 Argo Workflow 中触发一个已注册的 Airflow DAG,并轮询其状态直至完成。
对于 Apache Spark,可以利用 Kubeflow Spark Operator。在 Argo Workflow 中创建一个 SparkApplication 资源,并监控其状态。
成果与优势
通过实施这两种策略,我们获得了统一的开发者体验。所有工作流都可以在 Argo 仪表板中查看和管理,这为我们跟踪 KPI 和指标提供了便利。我们实现了类似大型云提供商“一切尽在掌握”的承诺。
工作流模板在这个过程中发挥了巨大作用,它极大地简化了新用户的上手过程,因为我们为各种常见任务准备了可复用的模板集合。
局限性与挑战
当然,这种方法也存在一些局限性和挑战:
- 低延迟工作负载:Argo Workflows 可能不是最佳选择。
- 流处理:持续处理数据流的环境具有挑战性。
- 性能开销:集成策略会引入额外的步骤,带来一定的性能开销。
- 专用硬件支持:如前所述,仍是问题。
- 多集群管理:管理多个 Argo Workflow 实例并进行联邦并不容易。
总结与展望
本节课中,我们一起学习了如何将 Argo Workflows 用作统一的云工作负载调度引擎。我们介绍了迁移和集成两种核心策略,并通过 HPC、Airflow 等实例说明了具体做法。工作流模板是成功的关键因素之一,它提升了开发体验和管理效率。
最后,我有一个关于 Argo Workflows 未来的愿望清单:
- 更好的多集群同步:希望有一个代理 Argo 工作流集群能将状态同步回主集群。
- 更智能的资源请求与限制:希望资源请求能根据历史运行情况更精细地调整,以应对资源需求波动大的工作负载。
- 与批处理调度器集成:例如与 Volcano 或 Kueue 项目集成,以便在 Kubernetes 内实现更深度的作业优先级调度。
- 更好的数据管理集成:例如与 FUSE 更好地集成,实现外部存储的便捷挂载。
- 自动化转换工具:希望有更多工具能自动化从其他工作流系统(如 Airflow 到 Hera)的转换过程。

虽然我们尚未实现“一切皆用 Argo”的目标,但未来可期。
006:重新定义 ArgoCD 的多集群故事



在本教程中,我们将探讨 ArgoCD 多集群架构的演变历程、当前面临的挑战,并介绍一种有望解决这些问题的全新架构模式——ArgoCD Agent。我们将从历史回顾开始,逐步分析现有方案的优缺点,最后深入讲解新架构的设计原则、当前功能与未来规划。
历史回顾:ArgoCD 多集群架构的演变
最初,ArgoCD 仅通过一个单一的 应用控制器 Pod 来管理所有集群。这个 Pod 被配置了适当的凭证,可以连接到远程集群并在那里协调清单。
这是一种简单直接的机制,尤其适用于只有少数集群的场景。远程集群除了提供一个服务账户和适当的权限外,无需额外配置。
然而,这种机制也带来了一系列问题:
- 连接开销巨大:ArgoCD 会与远程集群建立长连接并进行资源监视,以便对集群内的任何变化做出反应。根据集群的规模(资源数量)和活跃度(变更频率),应用控制器本身很快就会达到垂直扩展的极限。
水平扩展:集群分片
为了扩展到管理更多集群,项目引入了 集群分片 机制。
分片允许你水平扩展应用控制器,每个副本负责一组或一个“分片”的集群。
这种方法确实有助于提升可扩展性,但并未解决远程集群访问方式上的根本性挑战。你仍然需要稳定、低延迟的网络连接,维护高权限凭证,并且网络流量并未减少。
分片本身也带来了新的挑战:
- 当集群数量庞大时,你需要扩展控制平面集群以承载管理所有这些资源所需的所有应用控制器副本。
- 核心问题仍未解决:应用控制器的垂直扩展需求、集群到分片的映射策略、网络要求等。
- 一个重大挑战是:当你需要扩展时,必须根据最大、最繁忙的集群来调整配置,无法为每个集群单独优化。如果你的集群阵列是非同构的,最终可能导致大量资源浪费。
分布式部署:每集群一个 ArgoCD
为了解决上述问题,一些人尝试在每个集群上都安装一个 ArgoCD 实例。
这并非一个坏主意,它解决了许多之前提到的问题,因为每个 ArgoCD 实例只与其安装所在的集群通信。
但它也带来了新问题:
- 配置被有效地分散到了所有集群中。
- 缺乏集中的可观测性。
- 阻碍了通过 ApplicationSet 等方式实现更智能的高级应用推广模式。
- 你需要为所有 UI 保存一长串书签。
引入新范式:ArgoCD Agent
那么,能否在保留上述方案优点的同时,引入一个中央控制平面来处理可观测性和管理,并消除我们讨论过的所有负担呢?
答案是肯定的。这就是由 Jan 发起的开源项目——ArgoCD Agent。
让我们翻转一下视角,让工作负载集群中的组件“指向”中央控制平面。这样,我们就可以从一个地方管理和观察它们。

上图是一个简化示意图:
- 蓝色方框代表现有的 ArgoCD 组件。每个被管理集群上都有一个应用控制器,而承载 UI 的 ArgoCD API 服务器只安装在控制平面集群上一次。
- 绿色方框是 ArgoCD Agent 新增的组件。我们在控制平面上有一个“Principal”组件,在每个被管理集群上有一个“Agent”组件。
这些组件的主要目的是交换关于 ArgoCD 配置的信息,主要是 Application 资源,也包括其他配置如 AppProject 和仓库配置。
默认情况下,Agent 和 Principal 通过 gRPC 在 TLS 保护的连接上进行通信。简而言之,Principal 会通知 Agent 关于应用规约(Spec)的变更,而 Agent 会通知 Principal 关于应用状态(Status)的变更。
ArgoCD Agent 的设计原则
上一节我们介绍了 Agent 的基本构成,本节中我们来看看指导其开发的核心设计原则。
- Agent 主动发起连接:拓扑结构上,Agent 需要知道如何到达 Principal,但 Principal 无需知晓 Agent 的位置信息。只要工作负载集群有办法回连到控制平面,它们无需对外暴露。
- 工作负载集群操作自治:控制平面不会、也不会成为拓扑中的单点故障。即使控制平面或 Principal 宕机,你虽然无法配置新应用或修改/删除现有应用,也无法获得集中可观测性,但工作负载集群上的应用控制器仍能正常运作,可以获取 Git 提交并协调变更。
- 默认无外部依赖:核心思想是让安装和起步变得简单。开箱即用,不需要持久化存储、第三方认证系统、数据库或消息队列。用户和开发者应该能够使用标准的 Kubernetes 集群即可开始。当然,我们也承认对于大规模设置这可能不够,因此我们在架构的关键部分添加了扩展点,以便在需要时与第三方系统集成。
- 与标准 ArgoCD 兼容:你不需要任何特殊的、专为 Agent 定制的 ArgoCD 版本,无论是在 Agent 端还是控制平面端。我们围绕 ArgoCD 核心设计 Agent 功能,如果我们认为需要在 ArgoCD 核心中进行更改,我们会倡导在那里进行更改,而不是仅在 Agent 中实现。
ArgoCD Agent 的当前能力与未来路线图
了解了设计原则后,现在我们来具体看看 ArgoCD Agent 目前能做什么,以及未来的发展计划。
目前项目处于早期开发阶段,但在本次会议前刚刚发布了首个公开版本。以下是已实现的核心功能:
- 应用资源 CRUD 操作:你可以在 Principal 上创建和操作应用,Principal 知道应该将变更提交给哪个 Agent。同样,Agent 会将状态变更提交回 Principal。
- 近实时状态同步:应用的所有状态,包括其同步状态,都将在 Principal 上近乎实时地可用。
- 同步与刷新操作支持:从 Principal 发起的同步和刷新操作将被传播到正确的 Agent。
- 基础 AppProject 同步:目前,Principal 上管理的所有 AppProject 会被同步到所有 Agent,而不是特定的某个。我们知道这并非最优,并计划改进。
- 实时资源视图:你将能够像在标准 ArgoCD 设置中一样,在 Principal 上集中查看来自 Agent 系统的实时资源。
- 管理 CLI:我们提供了一个 CLI,可用于管理 Principal 上的某些配置,例如 Agent 凭证。
对于今年余下的时间,我们有一个中短期路线图,高优先级事项包括:
- 弥合与标准 ArgoCD 体验的差距:例如在 UI 中查看期望清单、计算并显示期望状态与实时状态之间的差异,以及提供深入应用洞察的资源树视图。
- 支持资源操作:例如重新部署、删除 Pod 资源,以及任何已实现的自定义资源操作。
- 增强多租户体验:改进 AppProject 的同步机制,实现选择性同步,仅同步到需要的地方。同样,未来也将支持私有仓库。
- 大规模场景优化:探索比当前更高效的 Agent 与 Principal 之间的认证方式,并实现 Agent 向 Principal 的自动注册。我们正在考虑与 SPIFFE/SPIRE(CNCF 旗下的零信任工作负载认证协议)进行集成。
社区参与
最后但同样重要的是,我们需要社区的帮助。虽然目前主要是红帽的员工在推进这个项目,但这绝不是一个仅限于红帽的项目。Jan 在业余时间启动了它,我们有意在它所属的优秀开源社区——Argo 社区中培育它。
我们非常欢迎任何人花时间测试这个项目,验证我们的想法,提供反馈,提出新想法,或者分享你希望如何使用 Agent 的具体需求。即使是贡献一点文档,我们也非常欢迎。项目目前托管在 argoproj-labs 下,我们希望确保它适合所有人,并渴望听到你们的反馈。
这个项目的可能性才刚刚开始,是无穷无尽的,我们将感激收到的每一份社区贡献。
总结
在本教程中,我们一起学习了 ArgoCD 多集群管理架构的演进历程。我们从单一控制器模式开始,探讨了集群分片带来的扩展性与复杂性,并分析了每集群部署 ArgoCD 的优缺点。最后,我们重点介绍了全新的 ArgoCD Agent 架构,它通过引入 Principal 和 Agent 组件,在保持工作负载集群自治性的同时,提供了集中的管理和可观测性,并遵循简洁、兼容和无单点故障的设计原则。尽管项目处于早期阶段,但其路线图展示了解决现有挑战和增强多租户、大规模管理能力的清晰愿景。社区的参与和反馈对于这个项目的成功至关重要。

如果你有后续问题,可以在 CNCF Slack 的 #argo-cd-agent 频道中找到 Jan。此外,如果你正在考虑安装 Agent 并担心管理和维护的复杂性,今天晚些时候我们同事 Josh Packer 的演讲将展示如何将 ArgoCD Agent 模型与 Open Cluster Management 集成,从而简化生命周期管理和配置。



007:Argo CD 临时访问实战 - 在运行中汲取的经验教训



大家好。

我是 Kitty Lampkin,Intuit 公司的平台与开源部门高级产品经理。
我是 Leonardo,Intuit 公司的资深软件开发工程师,同时也是 Argo 项目的维护者。
在本教程中,我们将探讨 Argo CD 临时访问扩展的实际应用。这是 Argo Labs 项目之一,旨在解决 Argo CD 使用中可能遇到的一些问题。
课程概述
我们将首先介绍 Intuit 公司及其技术背景,然后深入探讨我们在开发者平台中遇到的问题。接着,我们会讲解对临时访问扩展所做的增强改进、取得的成果,并展望未来的计划。
Intuit 公司及其技术栈
Intuit 是一家金融科技公司,为美国纳税人提供 TurboTax 等税务解决方案,也为加拿大市场及小型企业提供财务软件。
从屏幕上的数据可以看出,我们为外部客户运营的规模非常庞大。同样重要的是,我们必须确保内部开发者平台也能高效、大规模地运行。
Intuit 的 ArgoCD 平台
我们以速度和精度运营 ArgoCD 平台。我们拥有超过 50 个 ArgoCD 实例和 345 个以上的 Kubernetes 集群,工作流规模巨大。每天处理超过 2400 个 PR,我们必须确保部署流程能够跟上这种速度和精度,以便为最终用户提供优质的财务服务体验。
在如此大规模运营的同时,由于身处金融行业,我们必须严格遵守合规要求。我们遇到了一些挑战。
面临的挑战
Leo 在之前的 ArgoCon 大会上曾介绍过临时访问扩展及其解决方案背景。为了让听众更好地理解本次内容,我们遇到的主要问题包括:
- 缺乏细粒度权限控制:无法精确分配不同级别的操作权限。
- 安全风险:不当的权限分配可能导致安全漏洞。
- 部署冻结未强制执行:无法有效阻止未经授权的部署。
- 变更未记录:所有对生产环境的变更,包括通过 ArgoCD UI 执行的操作,都需要有变更请求记录。
生产环境中的 UI 操作分析
以 Intuit 为例,我们观察了生产环境中每周通过 ArgoCD UI 执行的操作类型。
从饼图中可以看到,“删除资源”是 ArgoCD UI 中最常执行的操作。
“删除资源”可能意味着删除一个卡在“进行中”或“不健康”状态的 Pod 以重启它,这是一个常规操作。但它也可能意味着删除一个实时的 ReplicaSet、Deployment 或 Rollout 对象。
我们需要确保:第一,对这些操作有可追溯性;第二,只有了解其影响的人员才能执行这些操作。并非所有应用开发者都需要或应该拥有删除实时 Deployment 的权限。我们希望实施细粒度的策略,将高级权限授予少数特定人员,而让更多人只拥有删除 Pod 等基础权限。
引入临时访问扩展
我们引入了临时访问扩展。如上图所示,该扩展在 UI 顶部添加了一个“请求权限”按钮。默认情况下,用户只有只读权限。点击请求权限后,用户可以输入其角色(支持多角色),系统将处理该访问请求,批准或拒绝后,用户即可在 UI 内执行相应操作。
收到的反馈与改进方向
推出该扩展后,我们收到了内部用户的大量积极反馈,但也识别出可以改进的地方。软件需要持续迭代优化。本次演讲重点关注的四个改进主题是:
- 用户拥有多角色:如前所述,不同开发者拥有不同权限,且单个开发者可能被分配多个角色。系统需要能够动态获取这些角色信息,Argo CD 不应预设角色定义,而应能对接外部角色管理系统。
- 动态角色支持:系统需要能够动态响应用户的角色变化。
- 变更请求关联:必须确保变更请求被正确提交和关联。
- 用户体验优化:UI 需要为支持这些动态角色提供良好的用户体验。
接下来,我们将详细介绍如何解决这些问题。
增强功能一:多角色支持
在 Intuit,我们有多角色的概念。例如,通过开发者门户,用户可能拥有“开发者”、“DevOps工程师”等角色,这些角色允许他们执行不同的操作。我们希望将这种体验引入 Argo CD。
我们在临时访问扩展中添加了角色选择区域,允许用户选择执行特定应用操作所需的最低权限角色,这遵循了最小权限原则。
增强功能二:动态角色绑定
那么,如何启用这些角色,并使其能根据用户动态变化呢?这是通过临时访问扩展提供的两种 CRD 资源实现的。
第一种是 RoleTemplate。它包含名称、描述和策略列表,允许 Argo CD 管理员定义针对特定角色需要提升的权限策略。
第二种是 AccessBinding。它将上述的 RoleTemplate 与群组声明进行绑定。AccessBinding 中的主体列表与用户登录 Argo CD 时令牌中携带的群组声明相关联。
例如,在接下来的演示中,我的用户将关联到 group1,因此我将能够被提升到特定的角色。
增强功能三:插件机制
下一个增强功能是插件机制。我们引入插件概念的主要原因是 Intuit 要求所有对生产环境的变更都必须有已批准的变更请求,用户才能获得提升的访问权限。
但我们的变更请求 API 是专有的,而我们希望从第一天起就保持该解决方案对开源友好。这就是我们实现插件拆分机制的主要原因。
插件工作流程
插件如何与整个权限提升流程协作呢?
- 用户正常登录 Argo CD,获得包含群组声明的令牌。
- 用户启用临时访问扩展,点击权限按钮并选择提升权限的选项。
- 此时会创建一个名为
AccessRequest的新资源,触发临时访问控制器的调和循环。 - 如果临时访问控制器配置了插件,调和循环将调用插件中的
GrantAccess操作。 GrantAccess操作可以返回三种状态:pending、granted或denied。- 如果返回
pending,调和将结束并在一段时间后重新调度(例如每15秒或每分钟)。 - 如果返回
granted或denied,流程将继续。
- 如果返回
- 假设返回
granted,临时访问控制器将继续操作为用户授予访问权限。这意味着更新 Argo CD 的 AppProject 资源,将用户与项目中定义的角色关联起来,从而提升其访问级别。
插件实现
插件是实现特定 Go 接口的二进制文件。该接口主要包含三个操作,其中顶部的两个(Init 和 Revoke)是可选的,GrantAccess 是唯一必需的操作,它驱动着上述整个流程。
我们为本次演讲创建了一个参考实现的“睡眠插件”。当调用 GrantAccess 操作时,它会睡眠15秒,然后返回 granted 或 denied,用于测试所有状态转换以及插件与控制器的互操作性。
增强功能四:条件化扩展
最后一个增强是条件化扩展。这是 Argo CD UI 的一个概念。对于 Intuit,我们需要临时访问提升操作仅对生产环境应用可用。因此,我们需要一种机制来引导扩展决定是否应启用。
这通过特定的配置驱动。在安装临时访问扩展时,可以应用一个补丁到 Argo CD API 服务器,配置条件化扩展。该配置告诉扩展,应查找具有特定键值对的标签,以决定是否启用临时访问扩展。
功能演示
现在进行演示。我在本地运行了两个 Argo CD 应用。
在第一个应用中,可以看到新的权限按钮和显示当前权限的小部件。而在另一个应用中,该按钮不存在。这正是条件化扩展的作用:第一个应用配置了标签 argocon-demo: true,因此启用了临时访问扩展。
点击权限按钮,可以看到我可以被提升到的当前角色列表。
在提升权限之前,我们先查看与此 Argo CD 应用关联的项目。可以看到,目前只配置了一个名为 admin 的角色。
再查看我的用户登录信息,可以看到我的用户关联了两个群组声明:group1 和 group2。正是这一点使得 AccessBinding 允许我在获得权限提升时被提升到特定角色。
回到应用列表,尝试执行一些操作。默认情况下,我的访问权限是只读的。尝试重启一个 Deployment,会收到权限被拒绝的提示。
现在,选择能重启 Deployment 的最低权限角色,即 developer 角色。点击请求按钮,可以看到访问请求的状态变为 requested。这个状态由插件驱动。插件将睡眠15秒,然后返回 granted。
一段时间后,状态更新为 granted,小部件也相应更新。现在再次尝试重启 Deployment,操作成功。
但如果尝试编辑 Deployment 的规格,仍然会被拒绝,因为 developer 角色不允许此操作。
因此,尝试将权限提升到允许编辑 Deployment 规格的角色,即 devops 角色。请求访问 devops 角色并获得授权后,可以将 Deployment 的副本数从2改为3并保存成功。
最后,演示删除一个 ReplicaSet,这是 devops 角色不允许但 admin 角色允许的操作。请求 admin 角色访问权限,获得授权后,即可删除 ReplicaSet。
现在回到项目查看角色配置。与之前不同,现在看到了三个由临时访问控制器动态创建的新角色。查看 admin 角色,因为我的访问尚未过期,所以我的用户名仍关联其中。而其他角色的访问已过期,我的用户名已不在其中。用户与特定角色关联的时间完全由控制器配置和管理。
安装与文档
关于安装,所有细节都记录在临时访问扩展的 GitHub 仓库中。仓库中有一个 examples 文件夹,除了作为参考实现的“睡眠插件”外,还有详细的插件实现文档,逐步说明了如何为公司实现自己的插件。
关键成果
我们实现了这个很酷的功能,演示也很成功。那么,我们取得了哪些成果呢?
- 100% 的变更记录:通过 Argo CD UI 对生产环境所做的所有变更,现在都关联了变更请求。从合规角度看,这是一个巨大的成就。
- 遵循安全最佳实践:通过查看每个角色的访问权限,开发者可以根据最小权限原则,选择执行操作所需的角色。这让安全团队非常满意。
- 用户友好的体验:UI 不仅显示“请求权限”,还能向开发者展示其当前角色,例如“开发者”、“DevOps工程师”、“管理员”等。这些角色可以针对您的组织进行定制。
- 提升开发效率与保持控制:允许开发者在日常工作中提高生产力,同时不损害控制力或合规与安全要求。
- 100% 开源兼容:Intuit 非常重视开源,我们希望确保在解决自身问题的同时,也能回馈社区。这个解决方案完全开源兼容。
Intuit 深度参与开源社区,不仅是 Argo 项目的创建者和维护者,还贡献于众多其他开源项目,并两次获得终端用户奖。
总结

在本教程中,我们一起学习了 Argo CD 临时访问扩展的核心概念、Intuit 在实际应用中遇到的挑战以及相应的增强解决方案。我们探讨了多角色支持、动态角色绑定、插件机制和条件化扩展等关键功能,并通过演示直观展示了其工作流程。最终,该方案实现了完全的变更可追溯性、细粒度的权限控制,并提升了开发者体验,同时保持了与开源社区的兼容性。


009:一键自动化 - 使用 Argo CD Autopilot 简化一切


概述
在本节课中,我们将学习如何使用 Argo CD Autopilot 项目来简化 Argo CD 的安装、管理和恢复过程。我们将探讨其核心概念、工作流程,并通过一个实际演示来展示如何从零开始恢复一个完整的 Argo CD 环境及其管理的应用。
章节 1:Argo CD Autopilot 项目简介
大家好。

今天下午大家感觉如何?是不是有点累了。

累是好事。好消息是我准备了一个演示,它可能会出错,也可能让今天变得非常精彩。
快速举手示意一下,我看不太清楚,但有多少人以前使用过 Autopilot 项目?哦,看来不多。是的,从贡献者的活跃度来看,这确实不是一个非常活跃的项目。我们将在最后讨论这一点。今天我将向你们介绍几个我自己的实际用例,正是这些用例让我重新开始使用它。
首先从这张幻灯片开始,这是我。
我叫 Dustin Van Busker,在 Codefresh 工作了七年半。当 Argo Autopilot 项目启动时,我参与了项目的初始阶段,后来离开了。目前我在 Octopus 工作。我最近的一个项目让我重新开始使用 Autopilot。我在寻找一种通过 GitOps 安装和管理 Argo CD 的方法。从 Codefresh 成立第一天起,我们就将 GitOps 作为标准实践,这意味着所有配置都存在于版本控制中,我们按照 GitOps 原则正确地执行所有操作。因此,我将做一个简短的闪电演讲,希望时间足够,我们看看演示效果如何。
Argo Autopilot 项目有几个常见的用例。
我今天的演讲基本上应用了所有这些用例。第一是帮助我简化 Argo CD 的安装,并将其置于 GitOps 管理之下。这意味着 Argo Autopilot 项目将在版本控制中帮我更新所需的路径、放置所需的配置,使 Argo CD 能够通过 GitOps 操作管理自身。
正如我提到的,这个项目大约始于四年前。当时 Codefresh 正在尝试为我们的用户寻找一种安装 Argo CD 的好方法。很多人都是 Argo CD 的新手,Helm 图表还不够成熟。你会看到 Autopilot 项目的一些设计理念与此产生共鸣。它使用 Kustomize 的方式是为 Kustomize 编程的,但这并不意味着你不能使用 Helm,只是 Helm 不是一等公民。它需要你启用 Helm 才能通过 Kustomize 部署,Helm 有一些优势,但也有一些不足。
第二点是,利用我为 Argo 安装本身建立的相同 GitOps 结构来管理我的应用程序。
理想情况下,我们希望所有配置都在版本控制中,并且结构相似。这样,当我们在查看不同环境时,不会发现环境之间的配置组织方式不同。这为我们未来进行环境间升级等操作提供了坚实的结构基础。我不会过多涉及环境间的升级,但我确实需要能够做到这一点,因为我自己的工作建立在这个基础之上,并且需要这个结构就位。
第三点对我来说是一个锦上添花的功能,并且我已经让一切正常运行:由于所有配置代码都有备份,我实际上可以使用 Argo Autopilot 来恢复整个 Argo 集群组件以及我自己的 Argo CD 应用程序。
章节 2:Autopilot 的工作原理与部署模型
现在深入了解 Autopilot 及其工作原理。Autopilot 是一个 Argo 项目,它是一个二进制文件,位于你、你的 Kubernetes API 和你的版本控制系统之间。它帮助从你的本地机器将这些组件连接起来。基本上,当你在本地机器上时,你可以引导一个集群、安装 Argo CD 并进行配置。你还可以添加额外的应用程序,它会帮你为你的 GitHub(我认为它也支持 GitLab、Bucket 等其他版本控制系统)建立应用程序的结构。它还会使用 app install 命令为你建立应用程序的结构。最后,你可以通过指定引导命令来安装 Argo,然后指向配置仓库的目录,从而将所有内容重新安装到一个新集群中。这就是我今天要演示的:使用那个引导功能,指向版本控制系统,并告诉它现在将所有内容部署到一个新集群上。
对我来说,它作为一个恢复过程也非常有效。
我的用例是,我最近接手了一个新项目,需要在多个不同的集群上安装 Argo CD。这通常不是我职责的一部分,因为我的公司已经有相关的自动化流程。但现在我们从不同的角度看待 Argo 开源项目,所以我必须找到一种新的安装方法。我选择了 Autopilot 并开始了部署。我的部署有点独特:我不想使用中心辐射模型。在很多情况下,很多人使用中心辐射模型,这没有问题。但我喜欢在每个集群上使用一个 Argo CD 来管理该集群,这对我来说更容易。这样做有一些好处,我稍后会介绍在每个集群上运行 Argo CD 的优势。但我立刻意识到,除非我有一种可预测的方式来安装和管理 Argo CD,否则我将陷入维护的噩梦。这就是为什么我选择了 Argo Autopilot 项目。
除此之外,我还需要将应用程序部署到位,以便通过我的项目管理这些应用程序。这些应用程序必须按照特定的结构部署,因为我需要将配置文件映射到从环境到环境的特定目录结构中,它们必须完全匹配,并且必须可预测地部署。最后,作为一名开发人员,有时我的集群会莫名其妙地消失,我经常自己不小心删除它们。
幸运的是,我是一名销售人员,所以没关系,我可以这样做并从中恢复。
以下是我采用的部署模型。我知道很多人使用中心辐射模型,这有很多优点。我们有一篇很棒的博客文章涵盖了每种 Argo 部署模型的优缺点。我为我的练习选择了独立模型。基本上,我想做的就是让 Argo CD 服务位于它所属的集群上。这样我获得了更好的隔离性。通过将 Argo CD 放在该集群中,我也获得了更高的可靠性。我不再依赖一个单一故障点来跨不同环境部署我所有的 Argo 应用。
当然,还有关注点分离和更好的安全性。例如,如果这个 Argo CD 是用于开发、预发布或生产环境,你可以设置特殊的 RBAC,给特定团队权限,不必担心中心辐射模型带来的那种多租户问题。你可以基本上分离这些不同的环境。此外,你不再需要在环境之间建立网络连接,不必担心这个 Argo CD 是否能连接到那个集群的 API,因为它将能够通过集群内 API 进行内部连接。
当然,这带来了复杂性。这里有一些缺点,我认为 Argo Autopilot 非常适合帮助我解决这些问题。其中一些就是管理和更新,比如如何可靠地更新我的 Argo CD 安装,如何管理它,以及如何恢复它。这些就是我将在我的用例中涵盖的内容,以及 Argo Autopilot 如何满足我的需求。实际上,我正是试图通过使用 Autopilot 来做这些事情来简化 Argo CD 的管理。
章节 3:使用 Autopilot 管理 Argo CD 与应用程序
第一点,管理 Argo CD 本身。我想要一种简单的方法来安装和配置一切,并且希望所有配置都进入版本控制。我打算使用一个单一仓库将所有配置放在一个地方,这样我就可以从一个地方查看和管理它们。当然,对于 Argo Autopilot 来说,这不是必须的。你可以将不同的集群指向不同的仓库,让它们分开管理,这取决于你。但这帮助我简化了到这些集群的边缘部署。我知道我需要多个安装,我希望它们都有备份。我该怎么做呢?我直接使用 Argo CD Autopilot 引导了我的每一个集群,配置它们,将它们放入版本控制系统仓库,包括所有相关配置。最终,我进入了应用程序部署阶段。
以下是该仓库布局的大致样子。有开发、预发布和生产环境。有不同的方式来组织这个结构,我们可以使用不同的仓库,也可以注入我们自己的文件夹结构,满足任何要求。然后我们可以使用 owners 文件来围绕这些不同的文件夹设置权限。在这里,我们可以看到当前由此集群管理的应用程序。bootstrap 文件夹将包含我需要的所有 Argo CD 配置文件。kustomization.yaml 将覆盖在 Argo CD 安装程序之上,允许我放入覆盖信息,指定并使该 Argo CD 安装具有我所需的配置、插件等。
当然,这一切都连接到内部集群。所以我不必管理一堆集群资源,而是只处理一个集群内资源。
现在,我需要考虑我的应用程序部署。我已经介绍了使用 GitOps 原则,拥有正确的仓库结构,这将帮助我以可预测的方式部署这些应用程序,然后我可以继续更新。更新作为自动化的一部分,我们希望它是可预测的。在很多情况下,你可以从 values 文件开始,设置路径映射,将环境名称作为路径的一部分,最终到达应用程序的 values.yaml 文件。这样,你只需通过更改路径就可以从系统到系统进行部署。这为我们提供了一种非常简单的方式来提升配置更改,也就是 values 文件的更改。顺便说一下,Helm 可以与此配合,或者 Kustomize 覆盖,任何这些都可以被引入。然后,就创建了一个简单的模式。这些都是它产生影响的不同方式,但你们都听说过,所以我将跳过,看看版本控制系统中的样子。
在这里,你可以看到我部署的演示应用程序。我有一个基础 kustomization.yaml,它指向我的其他 Kustomize 文件,基本上引入了 Kustomize 指针。然后我有一个覆盖层。在这个特定案例中,我只有一个。如果这是一个多集群方法,你可能会看到一个用于开发,一个用于预发布,一个用于生产。但在这里,我只有这个 Argo 管理的一个覆盖层,它与开发项目相关。项目是另一件你可以轻松创建的东西,Argo CD Autopilot 支持项目结构。你可以创建项目,并将你的应用程序归类到该项目下,就像我在这里做的那样。基本上,保持这种一致性对于我们在这些流程中开始提升非常重要。
章节 4:灾难恢复与现场演示
好的。另一件事,就像我说的,我可以在任何时候删除我的集群,可能是因为 IT 部门的人敲门说“哦,你的成本太高了,你能做点什么吗?”好吧,我可以直接让那些集群消失。我不必担心那些后果,因为现在我有了一个简单的方法,可以从版本控制系统轻松安装 Argo CD 以及该 Argo CD 安装下的所有应用程序。我可以将所有配置保存在版本控制系统中。无论出于什么原因我丢失了一个集群,比如我误操作了,或者我在清理资源的过程中不小心清理了错误的资源,我都可以使用这个命令。我只需从我的本地机器,正确设置到我想要恢复到的 Kubernetes 上下文的上下文,然后指定仓库并传入信息,这样我就可以点击按钮,从版本控制系统中存储的内容恢复一切。
现在是紧张刺激的演示时间。我将尝试切换屏幕,打开我的终端,希望你们能看到。好的,终端,大家都能看清吗?我就假设可以了。
好的,让我先确保我连接到了 Wi-Fi。我将从确保我的 Kubernetes 集群在线开始,给我一秒钟,它在下面。所以我得集中注意力看看。抱歉,他们不需要在那里看。只是试图确保这是正确的集群,它目前应该没有任何与 Argo CD 相关的东西。好的,是的,它上面只有 kube-system 和 metrics-server。
那么,我要尝试做的是使用 Argo CD Autopilot 来引导这个集群。让我看看我是否能真正看到它,好的。
嗯,等一下。回到这里。我从我的幻灯片中复制命令,因为不知为何我这里没有了,这让我担心这意味着我的令牌没有在这个特定的窗口上设置。我们希望它是设置好的。因为不知为何,我的终端没有任何历史记录让我恢复。也许我只是输错了。我确实输错了,我少打了一个破折号。基本上,我有我的仓库,好的,一切正常。让我们清除那个。这是二进制文件。我们有 autopilot recover 命令。好的,这就是我们想做的。基本上,我们将看到,我在这里运行它,它将开始从版本控制系统进行恢复过程,前提是它有网络连接。
我们希望它有。我相信从 Kubernetes 集群是有网络连接的。这个二进制文件的全部目的是,从我的本地机器,我希望能够将版本控制系统与我正在通信的 Kubernetes 集群(即那个 Kubernetes 上下文)结合起来。所以它会意识到它需要创建一切,目前什么都没有,然后它将恢复 Argo CD,并且我还有一些应用程序它也会恢复。我们应该能够看到,看看我能不能把它拖上来一点。我们可以看到最底部这里。我们应该能够看到一切被重新创建,然后希望我部署了 Sock Shop 应用,希望一切都能正常恢复。基本上,这将是我未来用来将整个演示站点安装到我的 Argo CD 集群的路径,我最终将拥有开发、预发布和生产环境。我计时过,恢复一切大约需要五分钟。但我保证我马上会展示 Argo CD 用户界面,然后大家可以鼓掌,我们会为此兴奋。
当 Argo CD 进入就绪状态后,这个进程最终会退出,然后 Argo CD 开始接手工作。基本上,Argo CD 被重定向到配置文件,它获取当前在下面的所有应用程序,开始部署所有这些应用程序,其中包括我的一堆演示应用:Sock Shop,我相信我还有一个 Guestbook,可能还有另一个演示应用在里面。
是的,一旦完成,我将打开并观察 Pod 一会儿,确保它们在线。一旦它们在线,它实际上还会在最后为我输出一个命令,让我可以执行端口转发代理到 Argo CD 用户界面。如果你已经注意到,我后面有一个浏览器打开,将导航到那个界面,并观察其他一切上线。
好的。Autopilot 已经完成了它需要做的工作,覆盖了一切。那么,我们继续,使用这个临时的用户名和密码。好的。
刷新这个窗口。当然,前面没有证书,因为我是一名销售人员。我不相信证书。好的。让我们在这里登录。
你会看到 Argo CD 在这里,而且版本控制仓库中的所有应用程序都在同步。你可能最关注、可能看不太清楚的是这里的 Sock Shop 项目。
我们可以看到我们的 Sock Shop 正在从版本控制系统启动。它有自己的覆盖层,我做一些额外的事情来为我的环境指定它,比如更改负载均衡器。是的,这一切都将启动并上线。它将在约五分钟内为我恢复一切。显然,这取决于你的集群有多少可用资源,以及你需要恢复多少应用。但这为你提供了一种可行的方法,从版本控制恢复到 Kubernetes 集群并连接一切。
我想我不会等它全部完成,除非有人想看到它进入健康状态。你至少可以看到它已同步,东西正在上线。我想我们可以往下看,看到我们有一些 Pod 仍在启动中。
但我要继续讲幻灯片了,因为我想谈到我认为最重要的事情之一。
章节 5:总结与行动号召
那就是我的行动号召。我注意到 Codefresh 仍然有一些贡献者在从事这个项目,但你知道,要让所有开源项目向前发展,我们需要更多的贡献者。所以我请求大家,如果你有兴趣推动这个项目前进,也许想看到 Helm 支持,或者看到恢复功能等其他方面的额外支持,请在演讲结束后,你可以通过日程表在线下载幻灯片。我将提供额外的资源。你可以参与 CNCF Slack 频道,你可以在 GitHub 上提供帮助,我们在那里有 issue。如果你打算使用它并想提交一些问题,请随意。我们仍在努力成为这个项目的主要贡献者。我本来应该有一位同事和我一起,他叫 Noam,Noam 今天在这里。如果你想和他聊聊 Argo Autopilot 以及我们未来的路线图,路线图也包含在 GitHub 仓库中。我们希望看到的一些改进,以及其他人提到的改进,以帮助我们推动这个项目向前发展,这些材料都在那里。所以,如果你想和 Noam 交流,你也可以找我谈谈我的使用经验。我已经离开它几年了,但大约三、四年前,我每天都在使用它来帮助大家安装 Argo。我知道很多人已经超越了那个阶段,他们有自己的 Argo 安装流程,也许是作为 Terraform 的一部分进行引导。但至少对于需要频繁创建和删除、并且希望恢复的集群,特别是从开发人员的角度来看,这可能是一个对你非常有价值的工具,对我来说就是如此。
是的,再次强调,这里有资源,你稍后可以获取。基本上,这是 Slack 频道,如果你想参与进来,和我以及 Noam 交流,向我们提出任何问题,或者成为贡献者,请联系我们。

总结

在本节课中,我们一起学习了 Argo CD Autopilot 的核心价值。它通过一个二进制工具,在本地机器、Kubernetes API 和版本控制系统之间架起桥梁,实现了 Argo CD 及其管理应用的声明式安装、配置和全量恢复。我们探讨了其在独立集群部署模型下的优势,如更好的隔离性、可靠性和安全性,并通过现场演示直观地展示了从零恢复整个环境的过程。最后,我们呼吁社区共同参与贡献,推动这个项目持续发展,以支持更多如 Helm 集成等高级功能。
010:从症状到解决方案的 ArgoCD 扩容指南


在本教程中,我们将学习如何诊断和解决 ArgoCD 在规模化部署中遇到的常见性能问题。我们将从 CPU 和内存使用率过高的症状入手,深入分析其根本原因,并提供具体的解决方案,而非简单的缓解措施。
概述
ArgoCD 是一个强大的 GitOps 工具,但随着管理集群、应用和资源的数量增长,可能会遇到各种性能瓶颈。本教程基于 Intuit 公司(ArgoCD 的主要贡献者)在运行多个不同规模实例时的实践经验,旨在帮助您系统地解决这些问题。
1:CPU 使用率过高问题
当您收到 CPU 使用率警报时,通常有两种选择:简单地增加 CPU 资源请求,或者深入调查根本原因。本节我们将探讨后者。
ArgoCD 应用控制器(Application Controller)的 CPU 消耗主要来自三个核心组件:
- Kubernetes 资源监视引擎:负责监视所有已连接集群中的资源更新。
- 应用调和循环:当资源变更与应用相关时,触发此循环以判断应用是否“不同步”。
- 同步循环:当应用不同步时,执行同步操作以应用资源。
其中,调和循环是 CPU 消耗的主要来源。它需要从仓库服务器获取清单,与 Kubernetes 中的实际状态进行比较,并计算差异。

如果您想精确分析 CPU 消耗,可以使用 Go 的性能分析工具 pprof 生成火焰图。
诊断高 CPU 使用率
假设在周日(无部署活动时)收到 CPU 警报,并发现调和活动率恒定在 32,000 次/分钟。这显然不正常。
根本原因在于,Kubernetes 资源(如 Horizontal Pod Autoscaler)的状态字段会频繁更新,每次更新都会触发 ArgoCD 的调和循环,即使这些状态变更并不影响 Git 中定义的期望状态。
解决方案:忽略不必要的资源更新
以下是减少不必要调和事件的方法:
- 排除无关资源:配置 ArgoCD,使其不监视那些永远不会通过 ArgoCD 部署的资源类型。
- 忽略资源更新:对于需要监视的资源,可以配置忽略特定字段(如
status)的更新。
具体操作:通过启用调试日志(短暂开启,例如30分钟)来识别哪些资源在频繁触发调和。然后,配置 resource.exclusions 或 resource.inclusions 以及 ignoreDifferences 来过滤这些更新。
例如,忽略所有资源的 status 字段更新:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
data:
resource.exclusions: |
- apiGroups: ["*"]
kinds: ["*"]
clusters: ["*"]
# 可以更精确地配置
应用此配置后,CPU 使用率从持续的 6-7 个核心降至接近零,仅偶尔出现峰值。
2:处理调和峰值与仓库服务器压力
上一节我们降低了平均 CPU 使用率,但引入了峰值。峰值会给系统其他部分带来压力,尤其是仓库服务器。
当调和循环需要访问仓库服务器,且所需清单不在缓存中时,操作会变慢(需要执行 Helm、Kustomize 等)。如果大量应用同时触发调和(例如,因缓存同时过期),仓库服务器的队列会被填满,导致同步操作严重延迟。

缓解与根本解决
以下是缓解峰值的方法:
- 延长调和超时时间:例如,从 3 分钟改为 1 小时。但这只是延迟了峰值,并未解决它。
- 配置 Git Webhook:确保代码提交后能立即触发调和,而不是等待超时。
- 配置清单生成路径:对于 Monorepo 或包含非部署文件(如
README.md,Jenkinsfile)的仓库,此配置至关重要。它可以避免无关文件的变更触发大量应用调和。
根本解决方案是引入抖动。


什么是抖动?
在调和超时时间的基础上,增加一个随机的时间缓冲区。例如,如果超时为 1 小时,抖动配置为 30 分钟,那么应用的实际刷新时间将分布在 1 小时到 1.5 小时之间。这能将潜在的峰值请求分散开。
配置示例(在 Application Controller 的部署参数中):
- --reconcile-timeout=3600s # 1小时
- --reconcile-jitter=1800s # 30分钟抖动

孤儿资源监视的影响

另一个可能导致调和率居高不下的因素是启用了“孤儿资源监视”。此功能会监视命名空间内所有资源的变更,而不仅仅是 ArgoCD 应用管理的资源。任何未知资源的变更都会触发调和。

建议:评估是否真正需要此功能。社区中有用户在禁用此功能后,调和活动与 CPU 使用率均大幅下降。

3:内存使用率过高问题
解决了 CPU 问题后,下一个常见警报是内存使用率过高,有时甚至达到 100 GB 以上,影响 Pod 调度。

内存消耗主要来自 Kubernetes 资源监视引擎的缓存。ArgoCD 会缓存它监视的所有资源对象。随着连接集群数量和集群内资源数量的增长,缓存会不断膨胀。
降低内存消耗的策略

- 减少监视对象:与优化 CPU 一样,排除不需要监视的资源类型。
- 配置集群命名空间过滤器:如果您的应用只部署在某个集群的少数几个命名空间中,可以配置 ArgoCD 仅监视这些特定的命名空间,这能带来显著的内存改善。
- 配置方式:在集群的 Secret 或
argocd-cmConfigMap 中设置namespaces字段。
- 配置方式:在集群的 Secret 或
- 利用 RBAC:通过 Kubernetes 的 Role 和 RoleBinding 限制 ArgoCD 服务账户的权限。ArgoCD 将无法监视它没有权限访问的资源,自然也不会缓存它们。
最终手段:分片
如果经过上述优化后内存使用仍然很高(例如 80 GB),最后的解决方案是分片。
分片原理:将应用控制器拆分为多个分片(Shard),每个分片负责管理一部分集群。这可以通过轮询调度或均匀分布算法实现。

挑战:默认的分片策略可能不会考虑集群的“重量”(即资源多少)。一个生产集群的缓存可能远大于多个测试集群。
解决方案:手动将集群分配给特定的分片,以实现内存使用的均衡。您可以通过在应用控制器部署中设置 --shard 参数并手动分配集群来实现。
通过手动分片,可以将内存负载均匀分布到多个较小的 Pod 上(例如每个 Pod 15 GB),从而更容易被 Kubernetes 调度。
4:ArgoCD 响应缓慢问题

当用户报告“ArgoCD 变慢”时,需要系统性排查。
首先,确定问题是全局性的(所有应用都慢)还是仅限于特定应用。然后检查以下方面:
- 工作队列:检查应用控制器的队列深度。健康的系统队列应接近零。持续积压的队列是性能瓶颈的标志。
- CPU 限制与限流:即使 CPU 使用率不高,如果设置了过低的 CPU 限制,也可能导致 CPU 被限流,从而拖慢所有操作。考虑适当提高或移除 CPU 限制。
- 并行度设置:ArgoCD 可以配置
status.processors(调和并行度)和operation.processors(同步并行度)。注意:只有在 CPU 资源充足的情况下,增加并行度才能提升性能。否则会适得其反。 - 外部依赖:ArgoCD 严重依赖 Git 仓库和 Kubernetes API 服务器。
- Kubernetes API 服务器:可以使用 Kubernetes 审计日志来监控 ArgoCD 的 API 调用情况。从 ArgoCD 3.0 开始,提供了客户端指标,便于监控是否达到客户端速率限制或是否存在高延迟。
- 一个重要陷阱:当您为了优化内存而配置集群命名空间过滤器时,可能会意外增加对 API 服务器的连接数。例如,从监视整个集群改为监视 6 个命名空间,连接数可能从 100 激增到 600,如果超过默认连接池限制(如 500),就会造成瓶颈和临时死锁。

总结

在本教程中,我们一起学习了诊断和解决 ArgoCD 规模化部署中核心性能问题的方法:
- CPU 使用率高:其与调和活动强相关。通过忽略不必要的资源更新(特别是
status字段)可以大幅降低 CPU 消耗。 - 调和峰值:峰值会给仓库服务器等组件带来压力。通过配置抖动,可以将集中式的调和请求分散开,使系统负载更平滑、可预测。
- 内存使用率高:主要源于资源缓存。通过排除资源、配置命名空间过滤器、利用 RBAC 以及最终的分片策略,可以有效控制内存增长。
- 响应缓慢:需要从队列、CPU 限流、并行度设置以及 Git 和 Kubernetes API 服务器这些外部依赖进行综合排查。
最后,请记住优化 ArgoCD 性能就像冲泡一杯完美的意式浓缩咖啡:一次只调整一个参数,观察效果,然后迭代。不要同时更改所有设置,否则您将无法确定是哪个更改带来了改善(或问题)。如果您在社区中解决了独特的性能问题,非常欢迎分享您的经验。
011:默认配置的隐患与多租户 ArgoCD 的安全加固


概述

在本教程中,我们将学习如何识别和修复 ArgoCD 默认配置带来的安全风险。ArgoCD 的默认设置非常宽松,旨在简化初始部署,但这在多租户环境中会带来严重的安全隐患。我们将从访问控制和资源限制两个方面,详细介绍如何通过配置应用项目、RBAC 策略和 Kubernetes 原生安全机制,来构建一个安全的 ArgoCD 环境。
默认配置的问题与挑战
ArgoCD 的默认配置非常宽松,几乎所有功能在默认情况下都是启用的。这是因为 ArgoCD 的设计初衷是易于设置和快速上手。安全方面的考虑通常需要在后续阶段进行。


许多管理员,即使阅读了关于如何正确配置 RBAC 和将应用拆分到不同项目的文档,在实际操作中仍倾向于使用默认配置。因为超越默认配置意味着需要投入更多的工作量,并维护更多的代码。通常,管理员只会进行最低限度的安全配置,例如设置单点登录、禁用默认的 admin 用户以及创建一些基本的 RBAC 规则。

然而,仅依赖这些基础配置是危险的,因为它假设开发者不会故意破坏系统。实际上,如果开发者有意为之,他们可以绕过这些限制。本教程的目标是展示默认配置的危险性,并提供简单的步骤来显著提升 ArgoCD 安装的安全性。
ArgoCD 的演进:从单租户到多租户
在 ArgoCD 使用的初期,通常是一个开发者使用一个 ArgoCD 实例,部署一个应用到单个 Kubernetes 集群的单个命名空间中。这是一个单租户环境。
随着 ArgoCD 使用规模的扩大,多个团队开始访问同一个 ArgoCD 实例。这个实例现在管理着多个应用,这些应用将资源部署到不同集群的不同命名空间中。此时,单租户环境就演变成了多租户环境。
在多租户环境中,不同的安全需求开始出现:
- 团队访问控制:平台团队通常可以访问所有业务应用和基础设施应用,而开发团队只能访问自己的应用,不能访问其他团队或基础设施的应用。
- 操作权限控制:不同角色的人员应具有不同的操作权限。例如,A 开发团队可以查看和更新其应用,而 B 开发团队可能只能同步和查看其应用,平台团队则可以对任何应用执行任何操作。
- Kubernetes 资源操作限制:需要限制谁可以更新或查看应用 A 的资源,以及谁可以删除应用 B 的 Pod。
幸运的是,ArgoCD 拥有非常灵活的安全机制,可以支持广泛的需求。
ArgoCD 安全概览
ArgoCD 的安全主要涉及两个相互独立的方面:
- 对 ArgoCD 资源的访问限制:控制谁可以同步、查看或删除一个 ArgoCD 应用。
- 对 Kubernetes 资源的访问限制:控制可以将哪些 Kubernetes 资源部署到哪些命名空间和集群。
应用项目 资源将这两个方面结合在一起。它用于分组应用,并控制以下内容:
- 受信任的 Git 仓库和 Helm Chart 仓库。
- 可部署的目标集群和命名空间。
- 可部署的 Kubernetes 资源类型。
- 通过 ArgoCD RBAC 控制用户对应用的访问权限。
接下来,我们将深入探讨第一个方面:控制对 ArgoCD 资源的访问。
控制对 ArgoCD 资源的访问
要理解这部分,首先需要了解 ArgoCD RBAC 模型的工作原理。
ArgoCD 安全策略的构成要素
ArgoCD 安全策略由以下几个核心部分构成:
资源
资源是策略作用的对象,主要包括:
applications:应用。applicationsets:应用集。projects:项目。logs:Pod 日志。exec:在 Pod 中执行命令。
需要注意的是,project 本身也是一种资源。

动作
动作定义了可以对资源执行的操作,主要包括:
get:获取/查看。create:创建。update:更新。delete:删除。sync:同步。
并非所有动作都适用于所有资源。例如,sync 动作就不适用于 applicationsets 或 projects。
- 查看 Pod 日志 (
logs) 本质上是只读操作,在语义上被视为get动作。 - 在容器中执行命令 (
exec) 可能会改变运行中容器的环境,在语义上被视为create动作。 update和delete动作可以在两个层面上操作:ArgoCD 应用层面,或该应用管理的资源层面。
策略语法与结构
策略的基本语法结构如下:
p, <subject>, <resource>, <action>, <object>, <effect>
以下是每个字段的含义:
p:策略的保留字。<subject>:策略主体,即“谁”。可以是角色、用户或组。建议使用角色。<resource>:策略作用的资源类型(如applications)。<action>:允许或禁止的动作(如get,sync)。<object>:策略作用的具体对象。可以是“项目中的某个应用”或“项目本身”。使用通配符*表示“任何”。<effect>:效果,取值为allow(允许)或deny(拒绝)。
策略示例
以下是几个策略配置示例:
示例 1:允许只读角色访问项目内所有应用
p, role:team-a-readonly, applications, get, team-a/*, allow
这条策略表示:team-a-readonly 角色被允许获取(查看)team-a 项目中的任何应用。
示例 2:拒绝只读角色访问特定应用的日志
p, role:team-b-readonly, applications, get, team-b/app1, deny
这条策略表示:team-b-readonly 角色被禁止获取(查看)team-b 项目中 app1 应用的日志。
示例 3:细粒度 RBAC - 允许删除特定应用中的 Pod
p, role:team-b-delete-pods, applications, delete, team-b/app1, allow
这条策略的 action 字段为 delete,object 字段指定了应用 team-b/app1,表示允许该角色删除该应用管理的资源(在此上下文中特指 Pod)。这展示了如何控制对应用所管理资源的访问。
示例 4:全局宽范围策略(平台管理员)
p, role:platform-admin, applications, *, */*, allow
这条策略表示:platform-admin 角色被允许对任何项目中的任何应用执行任何动作。由于这个角色不局限于任何特定项目,此类全局策略应配置在 ArgoCD RBAC ConfigMap (argocd-rbac-cm) 中,而不是在单个应用项目里。
应用项目建模建议
一个常见的场景是为每个团队创建一个单独的应用项目。但请注意,没有放之四海而皆准的方案。您应该始终分析您的组织结构和对访问的不同安全需求,然后根据您的具体需求来建模应用项目。
控制对 Kubernetes 资源的访问
上一节我们讨论了如何限制对 ArgoCD 资源的访问,现在让我们深入探讨如何限制可以通过应用项目创建哪些 Kubernetes 资源。
默认应用项目的风险
首先,所有 ArgoCD 应用都必须与某个应用项目关联。ArgoCD 默认提供的应用项目配置如下:
- 对可以从哪个代码仓库读取清单没有限制。
- 对可以部署到哪个集群和命名空间没有限制。
- 对可以部署哪些资源到这些目标没有限制。
这本身看起来就很不安全,因此不建议使用这个默认应用项目。良好的实践是锁定默认应用项目,然后创建符合需求的新项目。
锁定默认应用项目的方法:您无法删除或禁用默认项目,但可以修改它。只需创建一个名为 default 的应用项目资源,移除其所有权限,然后应用到集群即可。这样,默认项目就变得完全无用。

创建安全的应用项目:五个风险示例与修复方案
假设我们要为一个产品开发团队创建一个新的应用项目。他们通常通过 Git 提交配置文件(如 ConfigMap、Deployment、Service)与 ArgoCD 交互,偶尔通过 UI 进行同步。
以下是五个如果使用默认配置可能出错的地方,以及我们如何通过新应用项目来修复它们:
风险 1:创建高权限的 Kubernetes RBAC 资源
- 问题:默认配置下,开发者可以创建
ClusterRole和ClusterRoleBinding。他们可以借此授予自己或其容器访问整个集群的权限,从而无限制地运行任何kubectl命令。 - 修复:在应用项目中,使用
clusterResourceBlacklist字段来黑名单这些不需要的资源。spec: clusterResourceBlacklist: - group: “rbac.authorization.k8s.io” kind: ClusterRole - group: “rbac.authorization.k8s.io” kind: ClusterRoleBinding
风险 2:从任意 Git 仓库同步
- 问题:默认配置下,应用可以从任何 Git 仓库读取清单。攻击者可以将应用指向包含恶意代码的仓库,一旦同步,危险代码就可能进入生产集群。
- 修复:在应用项目中,使用
sourceRepos字段白名单允许的仓库。spec: sourceRepos: - “https://github.com/your-org/your-repo“ - “https://github.com/your-org/*” # 允许整个组织的仓库
风险 3:部署到任意命名空间和集群
- 问题:ArgoCD 应用清单时,效果等同于运行
kubectl apply。如果资源已存在,它会被覆盖。这意味着 ArgoCD 可以覆盖集群中的几乎任何资源。例如,开发者可以创建一个指向argocd命名空间的 ConfigMap 并覆盖 ArgoCD 自身的配置。 - 修复:在应用项目中,使用
destinations字段白名单允许的部署目标,或使用deniedNamespaces等字段进行黑名单限制。spec: destinations: - namespace: dev-team-a server: “https://kubernetes.default.svc” deniedNamespaces: - kube-system - argocd
风险 4:创建 ArgoCD 应用资源
- 问题:如果允许开发者创建
Application资源,他们需要指定一个应用项目。如果他们指向一个限制宽松的项目(如未锁定的默认项目或基础设施团队的项目),他们就能绕过所有限制。 - 修复:如果开发者不需要自助创建应用,最简单的方法是在应用项目中黑名单
Application资源。如果确实需要支持自助服务,则必须非常谨慎地设计项目引用规则和全局 RBAC。
风险 5:创建 ArgoCD 应用项目资源
- 问题:如果开发者可以创建
AppProject资源,他们总能创建一个没有任何限制的新项目并使用它,这使得之前所有的安全配置都形同虚设。 - 修复:开发者通常不应被允许创建
AppProject资源。您应该从其他地方(如平台团队)集中管理这些资源,并在应用项目中黑名单此资源。
超越 ArgoCD 的安全机制
Kubernetes 安全是复杂的,因此 ArgoCD 安全也很复杂。如果 ArgoCD 不支持您的特定用例或安全关切,您可以考虑集成其他项目,例如 OPA Gatekeeper、Kyverno,或者创建自己的准入控制 Webhook 来实施额外的策略。
通过 Kubernetes 原生 RBAC 进行限制
您可能会问,既然是在限制对 Kubernetes 资源的访问,为什么不能直接使用原生的 Kubernetes RBAC 呢?实际上,从 ArgoCD 2.13 开始,您可以通过一个 Alpha 特性来实现这一点:模拟同步。


模拟同步的工作原理
您可以为每个应用目的地配置一个新的服务账户。当 ArgoCD 执行同步操作时,将使用这个服务账户,而不是高权限的 ArgoCD 控制平面服务账户。这依赖于 Kubernetes 的模拟机制:一个用户(ArgoCD 服务账户)可以扮演另一个用户(您配置的低权限服务账户)。
这样,应用项目中对 Kubernetes 资源的访问控制就转化为了原生的 Kubernetes RBAC,可以简化 ArgoCD 管理员的配置工作。
配置步骤
- 在 ArgoCD ConfigMap 中启用此 Alpha 特性。
- 创建用于同步的低权限服务账户,以及所需的 Role、RoleBinding、ClusterRole 和 ClusterRoleBinding。
- 在应用项目清单中,为相关目的地指定服务账户名称。
spec: destinations: - namespace: dev-team-a server: “https://kubernetes.default.svc” # 指定用于此目的地的服务账户 serviceAccount: dev-team-a-sync-sa
这是一个 Alpha 特性,鼓励您进行测试、采用,并提供反馈以帮助其未来发展。
总结与核心要点
本节课我们一起学习了如何加固多租户 ArgoCD 环境的安全。以下是本次课程的六个核心要点:

- 配置单点登录:确保每个开发者使用自己的身份登录。
- 禁用默认管理员用户:不要使用本地
admin用户进行人工登录。 - 创建自定义应用项目:不要使用默认的、权限过大的应用项目。
- 为团队创建角色和策略:根据职责分离原则,配置细粒度的 ArgoCD RBAC。
- 限制可创建的资源、来源和目标:
- 使用
clusterResourceBlacklist等字段限制资源类型。 - 使用
sourceRepos白名单代码仓库。 - 使用
destinations或黑名单限制部署目标。
- 使用
- 锁定默认应用项目:通过创建一个无权限的
default项目来使其失效。

请记住,安全是一个持续的过程。建议您阅读官方 ArgoCD 文档中关于 RBAC 的详细说明,并参考社区相关的安全实践博客文章,以持续优化您的 ArgoCD 部署安全。
012:通过插件支持扩展 Argo CD CLI 功能 🚀
在本节课中,我们将学习 Argo CD 即将在 3.1 版本中引入的一项新功能:CLI 插件支持。我们将了解什么是 Argo CD 插件、它的工作原理、使用限制,并通过一个实际演示来加深理解。
什么是 Argo CD 插件?🤔


上一节我们介绍了课程概述,本节中我们来看看 Argo CD 插件的核心定义。
简单来说,一个 Argo CD 插件是一个独立的可执行文件。它的命名必须以 argocd- 作为前缀,并且需要存放在系统的绝对路径中。
它的核心作用是:任何放置在系统绝对路径中、以 argocd- 开头的二进制文件,都将成为 argocd 命令的一个子命令。这意味着你无需修改 Argo CD 的代码库或提交拉取请求,就能扩展其 CLI 功能。这与 Kubernetes 的 kubectl 插件系统工作原理类似。
插件的执行条件 ✅
了解了基本概念后,我们来看看一个二进制文件要作为 Argo CD 插件被执行,必须满足哪些条件。
以下是插件生效的三个必要条件:
- 命名前缀:二进制可执行文件的名称必须始终以
argocd-开头。这个约定是为了区分系统中可能与 Argo CD 关联的其他二进制文件。 - 执行权限:二进制文件必须拥有可执行权限。否则,Argo CD 将忽略它。
- 存放路径:二进制文件必须存放在系统的绝对路径中(例如
/usr/local/bin)。如果放在相对路径下,它将不会被执行。
插件命名与调用规则 📛
现在我们已经知道了插件的存放规则,接下来具体看看如何命名以及 Argo CD 如何调用它。
命名规则很简单:构建一个以 argocd- 为前缀的二进制文件,并将其放入系统绝对路径。
例如,如果你有一个名为 argocd-demo-plugin 的插件放在系统绝对路径中,那么:
argocd-demo-plugin这个二进制文件将被执行。- 在 CLI 中,它将成为
argocd的一个子命令,调用方式为:argocd demo-plugin。 argocd-demo-plugin这个二进制文件自身的任何参数或标志(flags),都会在argocd demo-plugin命令后传递并执行。
用伪代码表示这个调用关系是:
# 系统找到并执行: /absolute/path/argocd-demo-plugin --some-flag
argocd demo-plugin --some-flag
当前功能的限制 ⚠️
虽然插件系统很强大,但目前它存在一些限制,理解这些限制对于正确设计插件至关重要。
目前,该功能有两个主要限制:
- 无法覆盖现有命令:不能创建会覆盖 Argo CD 原有内置命令的插件。例如,Argo CD 已有
argocd version命令。如果你创建了一个名为argocd-version的二进制文件,当你执行argocd version时,Argo CD 会优先执行其内置的version子命令,而不会执行你的argocd-version二进制文件。因此,插件名称不应与任何现有的 Argo CD 子命令相同。 - 无法为现有命令添加子命令:不能使用插件为现有的 Argo CD 命令添加新的子命令。例如,Argo CD 有
argocd cluster命令。如果你想添加一个argocd cluster upgrade命令,你可能会尝试创建名为argocd-cluster的二进制文件,并期望upgrade作为其参数。然而,当你执行argocd cluster upgrade时,Argo CD 会识别出cluster是其内置子命令,因此会直接调用内置逻辑,而不会去查找和执行argocd-cluster这个二进制文件。
演示:插件实战 🎬
理论部分已经介绍完毕,本节我们将通过一个实际演示,看看插件是如何工作的。我们将以名为 mta(Manifest Transformation Advisor)的插件为例进行演示。
首先,我们查看当前系统绝对路径下有哪些相关的二进制文件:
ls /absolute/path/ | grep argocd
# 可能输出:argocd-cluster-list, argocd-helper, argocd-lovely-plugin, argocd-mta, argocd-version
- 执行
argocd-cluster-list:当我们运行argocd cluster-list时,Argo CD 会找到并执行argocd-cluster-list这个二进制文件。 - 执行
argocd-helper和argocd-lovely-plugin:同理,argocd helper和argocd lovely-plugin也会调用对应的二进制文件。 - 尝试覆盖内置命令:如果我们执行
argocd version,即使存在argocd-version这个二进制文件,Argo CD 也会执行其内置的版本命令,而不是我们的插件。这验证了“无法覆盖现有命令”的限制。
现在,让我们聚焦到 mta 插件。它是一个 CI 工具,用于将 Flux 组件转换为 Argo CD 兼容的资源。
- 扫描资源:我们可以使用
argocd mta scan命令来扫描集群中的 HelmRelease 和 Kustomization 资源。argocd mta scan # 输出显示在 default 命名空间中找到的 HelmRelease 和 Kustomization 资源列表。 - 转换 HelmRelease:我们可以将扫描到的 HelmRelease 资源(例如名为
podinfo的资源)转换为 Argo CD 的 Application(应用)。argocd mta convert helmrelease podinfo -n default # 输出转换后生成的 Argo CD Application YAML 清单。 - 转换 Kustomization:同样地,我们也可以将 Kustomization 资源转换为 Argo CD 的 ApplicationSet(应用集)。
argocd mta convert kustomization <kustomization-name> -n default # 输出转换后生成的 Argo CD ApplicationSet YAML 清单。
通过这个演示,我们可以看到 argocd-mta 插件如何无缝地集成到 Argo CD CLI 中,并提供了强大的清单转换功能。
总结 📝
本节课中我们一起学习了 Argo CD CLI 的插件支持功能。
我们首先定义了 Argo CD 插件是一个以 argocd- 命名的独立可执行文件。然后,我们详细说明了插件生效的三个必要条件:正确的命名前缀、可执行权限以及存放在系统绝对路径中。接着,我们解释了插件的调用规则,即 argocd- 之后的部分会成为 argocd 命令的子命令。我们也指出了当前版本的两个主要限制:插件不能覆盖 Argo CD 的内置命令,也不能为现有命令创建新的子命令。最后,通过一个 mta 插件的实战演示,我们直观地看到了插件从安装到执行的全过程。


这项功能极大地增强了 Argo CD CLI 的扩展性和灵活性,允许社区和用户在不修改核心代码的情况下,为其添加新的定制化功能。
013:使用 Argo Workflows 扩展时间序列分析 📈


概述
在本教程中,我们将学习如何利用 Argo Workflows 这一云原生工作流引擎,来解决大规模时间序列分析中遇到的挑战。我们将探讨时间序列分析的核心概念、常见工具的限制,以及 Argo Workflows 如何通过并行处理、数据分区和有向无环图等特性,高效地处理海量数据。
1️⃣:认识时间序列分析
时间序列数据是一种记录特定时间间隔内趋势的数据类型,而非随机记录数据点。这些间隔可以从毫秒到年不等。收集这些数据点是为了分析趋势和模式,并用于进行预测,例如今日天气或交通拥堵时长。
以下是时间序列数据的更多示例。
- 股票价格与市场趋势:金融领域跟踪价格随时间的变化。
- 应用程序性能:监控软件在不同时间段的响应时间和资源使用情况。
- 能源使用情况:记录用电量以识别高峰时段。
通过分析时间序列数据,我们可以做出更明智的决策。例如,通过观察能源使用图表,我们可以发现用电高峰在下午3点到8点,从而决定在高峰时段减少空调使用以节省电费。
2️⃣:时间序列分析的价值与挑战
上一节我们介绍了时间序列分析的应用。本节中我们来看看它对组织的核心价值以及实施时面临的技术挑战。
组织可以利用时间序列分析来预测未来趋势、检测模式和异常、发现潜在风险、制定商业策略,并通过领先趋势、响应变化和做出数据驱动的决策来获得竞争优势。
然而,进行时间序列分析说起来容易做起来难。完整的分析流程通常包括以下步骤:
- 收集数据
- 处理数据
- 创建可视化图表
- 构建分析模型
手动完成这些步骤极其耗时。虽然存在如 pandas、Matplotlib、Jupyter Notebooks 等工具库,但它们也有其局限性。当处理海量数据集时,我们主要面临三大挑战:
- 内存使用:工具如
pandas通常将整个数据集加载到内存中,处理GB、TB级数据时容易导致性能瓶颈甚至内存不足。 - 性能限制:许多工具是单线程的,严重限制了并行处理能力。处理海量数据时,“一次一个任务”的方式无法满足对速度的需求。
- 数据可视化:对于大型数据集,折线图等传统图表会因数据点过多而变得混乱难以解读,妨碍深度分析。
3️⃣:Argo Workflows 简介
面对上述挑战,我们需要一个强大的解决方案。这就是 Argo Workflows。
Argo Workflows 是一个开源的、容器原生的工作流引擎,用于在 Kubernetes 上编排并行任务。它专为运行容器化应用而设计,非常适合数据处理和机器学习等资源密集型任务。
让我们快速了解一个 Argo Workflows 的重要概念,它对于时间序列分析非常有用。
理解有向无环图
在 Argo Workflows 中,你可以将工作流定义为一个 有向无环图。DAG 更加灵活,允许任务在特定依赖项完成后立即开始运行。
你可以使用模板创建动态 DAG。这对于构建弹性的数据管道非常有用,可以提高效率和计算速度。对于复杂的工作流,DAG 更易于维护,并允许任务在运行时实现最大程度的并行化。
请记住 DAG 这个概念,因为它对解决之前提出的三个技术挑战至关重要。
4️⃣:使用 Argo Workflows 应对挑战
上一节我们介绍了 Argo Workflows 和 DAG 的核心概念。本节中我们具体看看如何用它来解决时间序列分析中的难题。
挑战一:解决内存使用问题
当处理 GB、TB 甚至 PB 级的数据集时,Argo Workflows 可以通过将数据划分为更小的分区来实现可扩展性,即 数据分区。
通过将处理步骤定义为容器,并利用共享存储卷中的工件来处理大型数据集和依赖关系,Argo Workflows 可以独立处理每个数据分区,从而提高效率和计算速度。
挑战二:突破性能限制
Argo Workflows 专为在 Kubernetes 上编排并行作业而设计。除了数据处理,时间序列分析还涉及模型训练、预测和特征提取等其他资源密集型任务。
Argo Workflows 提供了任务并行化、完成度跟踪和自动重试等机制。这非常适合时间序列分析,因为我们可以以分布式方式处理这些资源密集型任务。
例如,在以下工作流中,我们可以同时搜索数据集中的两个关键词(“hello”和“world”),而不是依次执行任务。
# 简化的并行任务示例
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: parallel-search-
spec:
entrypoint: main-dag
templates:
- name: main-dag
dag:
tasks:
- name: search-hello
template: search-template
arguments:
parameters: [{name: keyword, value: "hello"}]
- name: search-world
template: search-template
arguments:
parameters: [{name: keyword, value: "world"}]
- name: search-template
inputs:
parameters:
- name: keyword
container:
image: appropriate/search-image:latest
command: ["./search"]
args: ["{{inputs.parameters.keyword}}"]
挑战三:优化数据可视化
可视化是时间序列分析的重要组成部分。DAG 本身可以作为数据点之间因果关系的可视化表示。
DAG 中的箭头可用于建模因果影响,帮助识别时间序列的底层因果结构,揭示哪些变量正在影响其他变量以及影响的方向。与包含大量数据点的混乱折线图相比,DAG 通常更清晰易懂。
此外,Argo Workflows 还提供工件可视化功能,这对于需要使用 HTML、文本或 JSON 文件生成可视化结果的场景非常方便。
5️⃣:示例与总结
以下是演示如何使用时间序列数据和动态 DAG 的 GitHub 仓库二维码,可供参考。

总结
本节课中我们一起学习了:
- 时间序列分析能带来巨大价值,帮助组织获得竞争优势。
- 使用
pandas或Jupyter Notebooks等常见工具进行时间序列分析可能非常耗费资源和时间。 - Argo Workflows 是最佳解决方案,因为它专为并行处理而构建,能提高效率和计算速度。
- 它通过数据分区增强了可扩展性,并可用于为时间序列数据创建模型或可视化(如 DAG)。

但这只是 Argo Workflows 的一个用例。想象一下,我们还可以利用 Argo Workflows 强大的数据分区、任务并行化和 DAG 功能来做些什么。
感谢您的时间。




014:如何确保工作流有效?使用验证性 Webhook 双重检查你的 Workflow Spec 🛡️


在本教程中,我们将学习如何为 Argo Workflows 配置验证性 Webhook,以确保提交到 Kubernetes 集群的工作流定义在创建前就是有效的。我们将探讨默认验证机制的不足、验证性 Webhook 的工作原理、其带来的好处以及实施时需要考虑的注意事项。
问题陈述:无效的工作流为何能被接受?
上一节我们介绍了本教程的背景,本节中我们来看看 Argo Workflows 默认验证机制存在的问题。
Argo Workflows 通过 Kubernetes API 服务器提交时,默认不会进行完整的验证。这通常是因为 Argo 安装时使用了最小化的 CRD(Custom Resource Definition),其中包含的 OpenAPI 模式(schema)信息有限。这是由于 Kubernetes API 服务器对 CRD 大小的限制所导致的。
因此,如果你创建了一个包含无效定义的工作流(例如,在模板规范中使用了无意义的字段),API 服务器会直接接受它并返回 200 状态码。然而,当工作流在集群中实际执行时,它会失败并显示错误信息,指出定义中存在无效的规范。
更糟糕的是,即使工作流定义本身通过了模式验证,它也可能引用了集群中不存在的 WorkflowTemplate。这种情况同样不会在创建时立即失败,而是在工作流执行到后期阶段时才失败。
这两种情况都导致了糟糕的用户体验:用户提交工作流后收到了成功响应,但稍后在 Argo 服务器 UI 中查看时,却只看到执行失败和错误信息。
为何需要统一的入口点?
你可能会问,为什么不直接使用 Argo Server 或 Argo CLI 的 lint 功能呢?原因在于我们需要一个统一的入口点。
我们是一个多集群、多数据中心的平台,为租户提供跨多个数据中心的集群访问。除了工作流,我们还管理 ConfigMap 和 Secret 等资源。我们不希望用户需要记住不同的入口:创建工作流用 Argo Server,创建 ConfigMap 又得用 kubectl。
使用 Kubernetes API 服务器作为统一入口点,也使得与其他系统(如 GitOps 工具或开放集群管理)的集成更加容易,因为这些系统通常使用原生的 Kubernetes 清单,并不直接理解 Argo 的格式。
解决方案:验证性准入 Webhook 🎯
上一节我们明确了问题与需求,本节中我们来看看核心解决方案:验证性准入 Webhook。
验证性 Webhook 是 Kubernetes API 服务器准入控制的一部分。当你通过 API 服务器创建资源时,请求会经过一系列步骤:
- 经过变更性 Webhook。
- 进行针对 CRD 中定义的 OpenAPI 模式验证(这正是 Argo 最小化安装所缺失的)。
- 经过验证性 Webhook。
我们正是在模式验证之后的这个阶段进行验证。API 服务器会调用我们的验证性 Webhook 服务,由该服务判断工作流定义是否合法,并据此决定拒绝或接受该请求。
具体实现上,我们使用 kubebuilder 来引导创建验证性准入 Webhook 服务。在底层,我们直接使用了 Argo 代码库中的验证函数。
以下是核心验证逻辑的示意代码:
// 伪代码,示意调用 Argo 的验证函数
import “github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1”
func validateWorkflow(workflow *v1alpha1.Workflow) error {
// 调用 Argo 内置的验证逻辑
return validation.ValidateWorkflow(workflow, workflowLister)
}
Argo 的验证函数(位于代码库的 validate.go 文件中)提供了非常全面的检查,它不仅是检查工作流规范是否符合模式定义,还会深入检查诸如模板调用的每个参数、所有必需参数是否都已提供、工作流中引用的模板是否真实存在等许多方面。
通过直接调用这个验证函数,而不是依赖 Argo Server,我们降低了对集群中 Argo Server 部署的依赖。即使没有运行 Argo Server,我们也能执行相同的验证逻辑。
实施验证性 Webhook 的好处 ✅
以下是实施验证性 Webhook 带来的主要优势:
- 全面覆盖的验证:所有通过任何媒介(Argo Server UI、Argo CLI、
kubectl)提交的 Argo 资源都会得到验证。 - 隐式且强制的检查:用户无需额外执行
argo lint或argo submit --dry-run等命令,每一次提交都会自动触发验证。 - 即时反馈:所有格式错误的工作流(如前文提到的无效字段)都会被立即拒绝,不会进入系统。引用无效 WorkflowTemplate 的工作流也会在创建时被拒绝。
- 提升可观测性:工作流不会再在执行的后期阶段因定义问题而失败。所有与定义相关的失败都会在创建时立即返回给用户。
注意事项与缓解措施 ⚠️
上一节我们看到了验证性 Webhook 的优点,本节中我们来看看实施时需要注意的一些问题和应对策略。
因为验证性 Webhook 是 API 服务器准入控制中的关键一环,其部署可能出现问题。
- 服务可用性风险:如果 Webhook 服务因故离线,根据其配置方式,可能导致工作流提交被阻塞,甚至可能影响整个集群的可用性。
- 缓解措施:像对待任何关键部署一样,确保其高可用性。部署多个副本、设置完善的健康检查和就绪探针、在调用方配置适当的重试机制等。
- 验证性能开销:对于非常大的工作流定义,验证过程可能比较耗时。
- 缓解措施:为 Webhook 配置一个合理的超时时间(例如 3 秒)。如果预期有特别庞大的工作流,可以适当增加超时设置。
- 现有集群的兼容性:如果将一个验证性 Webhook 安装到已经存在 WorkflowTemplate 的集群中,需要确保集群中所有现有的模板都是有效的。
- 原因:Argo 的验证函数会去查找工作流中引用的所有模板。如果发现无效的模板,可能会导致解码错误,使验证函数以非预期的方式失败。
- 建议:在开启 Webhook 之前,先使用
argo lint等工具检查和清理集群中现有的无效模板。
总结
本节课中我们一起学习了如何利用 Kubernetes 的验证性准入 Webhook 来增强 Argo Workflows 的可靠性。

我们了解到,默认的 Argo 安装由于 CRD 限制,无法在 API 服务器层对工作流进行充分验证,导致无效工作流被接受并在后期失败。通过部署一个调用 Argo 内置验证函数的验证性 Webhook,我们可以为所有通过统一入口点(Kubernetes API 服务器)提交的工作流提供即时、全面、强制的验证。这极大地改善了用户体验和系统可靠性,确保只有有效的工作流才能进入执行阶段。在实施时,需要关注 Webhook 服务的高可用性、性能开销以及与现有环境的兼容性。
015:缓解 Argo CD 中的权限提升风险


在本教程中,我们将学习如何在多租户 Argo CD 环境中识别和缓解权限提升风险。我们将首先理解权限提升的概念,然后探讨 Argo CD 现有的多租户安全控制机制,最后介绍两种具体的缓解方法:使用 Kyverno 策略和启用新的“模拟身份同步”功能。
理解权限提升
权限提升是指攻击者利用系统漏洞、配置错误或安全弱点,试图从较低级别的访问权限获取更高级别系统或网络权限的行为。这与拥有初始访问权限但试图扩大其权限范围的攻击者有关。
一个常见的类比是国际象棋中的“兵升变”:当一枚最弱小的兵抵达棋盘底线时,它可以升变为威力最强的皇后。这形象地说明了低权限实体如何转变为高权限实体。
权限提升主要分为两种类型:
- 垂直权限提升:用户从低权限角色(如普通用户)提升为高权限角色(如系统管理员)。
- 水平权限提升:在多租户环境中,一个租户的管理员试图获取另一个租户的管理权限。
Argo CD 中的多租户安全控制
上一节我们介绍了权限提升的基本概念,本节中我们来看看 Argo CD 为多租户环境提供的核心安全控制机制。
Argo CD 内置了多层安全控制来管理多租户访问:
- 基于角色的访问控制:Argo CD 拥有自己的 RBAC 系统,同时依赖于底层的 Kubernetes RBAC。
- 应用项目:
AppProject是 Argo CD 中的管理资源,用于定义应用程序可以部署的源仓库、目标集群以及可部署的资源类型,是实施多租户隔离的关键。 - 安装范围:Argo CD 支持两种安装模式:
- 集群范围安装:Argo CD 对整个集群拥有完全控制权。
- 命名空间范围安装:Argo CD 仅能部署资源到特定的命名空间。
Argo CD 中的权限提升问题
了解了基本的安全控制后,我们需要分析这些控制机制在特定场景下可能存在的弱点。在 Argo CD 的标准架构中,权限流如下所示:
Argo CD 最终用户 -> Argo CD RBAC -> Argo CD Application Controller Service Account -> Kubernetes RBAC -> 目标集群
这里存在一个关键问题:Argo CD 应用控制器使用同一个高权限服务账户来同步所有租户的应用程序。这意味着,如果某个租户的应用需要高权限来部署特定资源,那么所有租户实际上都间接拥有了这些高权限。这为水平权限提升创造了条件,因为一个租户可能利用共享的高权限服务账户,访问或影响其他租户的资源。
缓解方法一:策略强化的应用项目
一种常见的预防方法是正确配置 Argo CD 应用项目。通过为每个租户定义明确的项目边界,可以限制其操作范围。
以下是使用策略引擎(如 Kyverno)来强制执行最佳实践的关键策略示例:
- 避免使用默认项目:强制所有应用程序都必须归属于一个明确定义的非默认项目。
- 强制执行全局项目:创建一个包含所有资源黑名单和通用配置的全局项目,并让所有租户项目继承或引用它。
- 实施命名空间隔离:确保每个租户的项目仅能访问其专属的命名空间。
通过上述策略,平台管理员可以为每个租户创建一个严格限制的 AppProject,从而在 Argo CD 层面建立安全边界。
缓解方法二:使用模拟身份进行应用同步
虽然策略强化有效,但它仍然依赖于共享的高权限服务账户。为了更彻底地解决根本问题,Red Hat 为 Argo CD 引入了一项新的 Alpha 特性:应用同步模拟。
该功能的核心思想是:允许 Argo CD 在同步应用程序时,模拟使用不同租户专属的 Kubernetes 服务账户。这样,每个租户的同步操作将受到其专属服务账户所绑定的 Kubernetes RBAC 权限的限制,实现了权限的完全解耦。
要启用和使用此功能,请遵循以下步骤:
- 启用特性标志:此功能默认禁用,需在 Argo CD 配置中通过
argocd-cmConfigMap 显式启用。 - 启用“任意命名空间应用”(可选):为了灵活性,可以允许在每个租户的命名空间中创建 Argo CD 应用。
- 在 AppProject 中配置目标与服务账户:这是最关键的一步。在
AppProject资源的spec.destinations字段中,现在可以为每个目标集群指定一个serviceAccount名称。示例如下:
当属于此项目的应用向apiVersion: argoproj.io/v1alpha1 kind: AppProject metadata: name: tenant-a-project spec: destinations: - server: https://kubernetes.default.svc namespace: tenant-a-namespace serviceAccount: tenant-a-sync-sa # 指定租户A专用的服务账户tenant-a-namespace同步时,Argo CD 将使用tenant-a-sync-sa这个服务账户的凭证和权限,而非控制器共享的高权限账户。
这种方法带来了显著优势:
- 有效防止权限提升:租户无法超越其服务账户的权限。
- 支持更灵活的集群配置:允许向同一集群 URL 使用不同的服务账户身份,突破了旧版本的某些限制。
- 遵循最小权限原则:平台管理员可以精确地为每个租户分配其所需的最小权限集。
- 直接集成 Kubernetes RBAC:无需在 Argo CD 的
AppProject和 Kubernetes 的RoleBinding之间手动保持权限同步。
总结与关键要点
本节课中,我们一起学习了如何缓解多租户 Argo CD 环境中的权限提升风险。
关键要点总结如下:
- 权限提升是多租户环境的核心安全威胁,分为垂直和水平两种类型。
- Argo CD 通过 RBAC、AppProject 和安装范围提供基础的多租户控制。
- 标准架构中共享的高权限服务账户是潜在的风险点。
- 方法一(策略强化):通过正确配置
AppProject并结合 Kyverno 或 OPA 等策略引擎强制执行最佳实践,可以在 Argo CD 层面建立有效的安全边界。 - 方法二(模拟同步):新的 应用同步模拟 功能(Alpha 阶段)通过允许每个租户使用专属的 Kubernetes 服务账户进行同步,从根本上实现了权限隔离,是更推荐的长期解决方案。
- 组合使用:无论采用哪种方法,结合策略引擎来持续验证和强制执行安全配置,都能极大提升 Argo CD 的整体安全状况。

通过理解和应用这些概念与工具,平台团队可以构建更安全、合规且易于管理的多租户 GitOps 平台。
016:驾驭复杂的多维部署


在本教程中,我们将学习如何在大规模、多维度的 Kubernetes 环境中,使用 ArgoCD 高效、可靠地管理应用部署。我们将重点解决部署可见性、告警精准度和自动化流程等挑战。
概述
大家好,我是 Mike Tujaron,Adobe 公司的首席云工程师,负责 Kubernetes 技术栈的架构设计。这位是 Carlos Santaana,来自 AWS 的高级 EKS 解决方案架构师。
首先,快速了解一下 Adobe 的环境规模。我们运行着一个非常混合的环境,包含 Flatcar 和 Ubuntu 操作系统。我们使用多个云服务提供商,业务遍布全球。目前我们有 430 个集群,并且数量还在增长。我们拥有超过 240 个 Helm Chart,它们可能被部署到这些集群上。最重要的是,与本次分享相关的是,我们的基础设施工程团队有 90 名开发者,分布在 7 个不同的国家。这些数字和多样性,都影响着我们使用 ArgoCD 向集群部署应用的方式。
核心问题:如何保持系统稳定运行
我们的核心问题是:如何保持系统稳定运行?仅在今年二月,我们就向整个集群舰队进行了 554 次 集群附加组件部署。平均下来,每天约有 20 次部署。考虑到我们的规模,ArgoCD 自带的监控指标难以满足需求。我们需要结合 Prometheus 指标和 ArgoCD 通知来填补空白。
海量的变更以及应用版本与舰队属性的多种组合,给我们带来了可见性问题。下图(虚构数据)展示了这个问题的复杂性:不同的集群版本、不同的应用、每个应用的不同版本,我们需要一种清晰、直观的方式将它们整合展示出来。

接下来,Carlos 将介绍我们如何整合这些信息。
解决方案:使用集群分组与属性
在 Adobe,我们采用的方法是给集群赋予属性。这些属性可以是创建 ArgoCD 集群密钥(Secret)时的标签(Labels)和注解(Annotations)。这提供了基于维护需求对集群进行分组的能力。
我们为每个附加组件(Addon)使用一个 ApplicationSet。这个 ApplicationSet 负责从 240 个可能的 Helm Chart 中,将特定的附加组件部署到各个集群。关键在于,无论 ArgoCD 实例有多少(Adobe 有多个实例,每个处理约 200-500 个 ArgoCD 应用),都使用单一的 ApplicationSet。这样,我们就可以基于 ApplicationSet 分组进行推广(Promotion)。
以下是如何进行分组的一个例子。例如,“生产”(Production)环境是一个分组,但你需要第二层分组,我们称之为“维护组”(Maintenance Group)。你可以将其理解为生产舰队中,你希望一起升级或打补丁的一组集群。最佳实践是,随着推广信心的增加,后续的组应包含更多集群,以加速推广过程,而不是线性地逐个集群进行。

如上图所示,生产环境下的 Group A 有 2 个集群,Group B 有 4 个集群。
ApplicationSet 配置示例
这在 ApplicationSet 中是如何体现的呢?以下是一个 ApplicationSet 的片段(非完整内容)。核心思想是使用扁平(flat)或合并(merge)集群生成器(Generator)。第一个生成器定义附加组件的默认版本,然后根据集群属性使用选择器(selector)。集群的属性决定了它将获得哪个附加组件及其版本。
例如,顶部的 c 或 d 环境获得版本 1.1.7。下一个是 staging 环境,它有 Group A 和 Group B,分别使用不同版本。再下一层是 production 环境,Adobe 在这里采用了金丝雀(Canary)发布:可能先在一个集群上部署,然后是 Group A(例如 2 个集群),再然后是 Group B(例如 3 个集群)。这样做的目的是最小化爆炸半径。
此外,Adobe 使用了大量自动化和 CI 工具来随时升级这些附加组件。我们通过拉取请求(Pull Request)进行管理,并使用 Prow 来管理这些 PR。随着渐进式同步(Progressive Sync)功能越来越稳定,我们计划未来采用它。目前它处于 Alpha 阶段,还缺少一些功能,比如处理同步波(Sync Waves)。
预期与非预期问题
随着部署的进行,你必须预料到各种问题。有些是预期的,有些则是非预期的。
- 同步开始阶段:可能出现 Git 访问权限缺失导致同步失败,或者应用/集群上设置了拒绝同步窗口(Deny Sync Window)。
- 试运行(Dry Run)阶段:可能因为集群上还没有所需的 CRD(Custom Resource Definition)而导致失败。例如,尝试部署 Prometheus 规则时,Prometheus Operator 可能尚未部署。
- 准入控制器(Admission Controller)问题:可能被 OPA Gatekeeper 策略阻止,或者我们内部的
precincts组件会检查集群是否存在中断或客户事件,从而阻止同步,以便运维团队在排查重大事件时,集群不会发生变更。 - 同步过程问题:可能推送了错误的镜像标签,或者应用因 ConfigMap 尚未创建而启动失败。
当然,还存在许多其他可能性。我们最喜欢的挑战之一是:测试并不总是有效。
创建自定义指标以增强可见性
我们的解决方案是创建新的监控指标。你可能不知道,Kube-state-metrics 有一个很酷的功能:可以捕获由 CRD 创建的 CR(Custom Resource)中的字段,并将其作为指标发出。
这意味着,你可以从 ArgoCD 的 Application CR 中抓取信息,例如操作状态的开始时间(operation.state.startedAt)和结束时间(operation.state.finishedAt),或者源版本(source.revision)等属性。我们还会从 AppProject 中提取信息,以获取应用或集群的同步窗口信息。
然后,我们使用 Prometheus 重写规则(Rewrite Rules)。这部分有些复杂,我们有一个包含约 350 行 YAML 配置的代码库来处理所有这些。一旦运行起来,它实际上相当简单。我们处理这些数据,结合 ArgoCD 已发出的 argocd_app_info 指标,创建出详细的指标。
我们整合了从 Kube-state-metrics 创建的其他指标,能够生成:
- 同步窗口指标:了解哪些应用或集群有拒绝/允许同步窗口。
- 长时间运行同步指标:识别哪些应用的同步耗时过长。
- 不同步应用指标:了解哪些应用因故处于不同步状态。
最酷的是,我们可以将这些指标与同步窗口指标结合。例如,如果一个应用不同步但处于拒绝同步窗口,或者反之。
解决“别打扰我”问题:精准告警
ArgoCD 有很好的通知机制,可以通过通知插件在应用不同步、不健康、降级、进行中时发送告警。但这里存在“别打扰我”的问题。
- 如果一个应用不同步,但设置了拒绝同步窗口,开发者真的需要被通知吗?可能不需要,因为你设置拒绝窗口是有原因的。
- 如果一个应用处于允许窗口且状态为“进行中”,你需要被通知吗?可能不需要,因为你可能刚刚做了部署。
- 但如果这个“进行中”状态持续了两个小时,你可能就需要知道了,因为大多数 Kubernetes 部署不会花两小时。
内置的 ArgoCD 通知机制可能导致很多误报。我们的自定义指标帮助我们过滤掉噪音,只获取真正失败的部署。
我们的过滤逻辑是:
- 首先收集不健康的应用程序(不健康、降级、不同步等)。
- 然后找出那些开始于 90 分钟前但尚未结束的同步(长时间运行)。
- 接着过滤掉那些处于拒绝同步窗口的应用。
- 最后,你将得到真正需要关注的不同步应用列表。
你可以将其整合到一个漂亮的仪表板中,并基于此发送告警。这样,当告警触发时,无论是开发者还是运维团队,收到的都是可操作且相关的信息,他们可以立即采取行动确保应用健康。
实战演示:搭建本地多集群环境
接下来,Carlos 将展示一个非常酷的演示。
我们将展示一个由几个部分组成的演示。在屏幕底部,我们使用了一个名为 idp-builder 的 CLI 工具。这个工具可以一键式引导整个环境:它会创建一个 Kind 集群,部署 ArgoCD、Nginx 和一个本地 Git 服务器。它会获取所有 YAML 文件并创建 Git 仓库。如果你修改了 YAML 文件,它可以在监视模式下自动提交和推送。之后,就完全由 ArgoCD 接管了。
在这个演示中,我们使用 vcluster 来模拟大量具有特定属性的集群。我们部署了几个有问题的“假”应用,例如长时间运行的、不同步的、降级的应用。vcluster 通过 External Secrets 注册到 ArgoCD。我们还使用了 kube-prometheus-stack Helm Chart,它为我们提供了 Prometheus、Grafana 和 Kube-state-metrics(我们将用它来收集应用和项目的信息)。
演示的一行命令如下(你需要先安装 Docker):
git clone <repo-url> && cd <repo-dir> && ./idp-builder up
在配置中,你可以看到 ApplicationSet 使用合并生成器来部署附加组件。我们还配置了 Kube-state-metrics 来抓取 ArgoCD 应用的同步开始/结束时间,并创建自定义指标。同时,我们从 AppProject 提取同步窗口信息,并使用 Prometheus 规则进行关联,最终生成我们关心的新指标。
在 ArgoCD UI 中,你可以看到一些应用处于降级状态。按照传统方式,你可能会收到告警。但在我们的方案中,如果这些应用有拒绝同步窗口,我们就不会收到打扰。Adobe 的做法是将其作为一个“闸门”:如果有人正在处理问题,他们会在应用上设置一个同步窗口,以停止告警。一旦窗口移除,就恢复正常监控。
另一个关键点是识别长时间运行的健康应用。在演示中,我们设置了一个规则:如果应用同步时间超过 30 分钟(生产环境可能设为 1 小时),就生成一个自定义指标。这在 ArgoCD 中很难直接发现。

可视化与告警集成
在 Grafana 仪表板中(这是自定义的,非 ArgoCD 自带),我们可以看到哪些集群和应用有同步窗口。这模拟了团队正在处理有问题的应用。如果我们移除了某个应用的同步窗口,它就会出现在仪表板底部的“需要关注”列表中,那里会显示降级的、不同步的以及长时间运行的应用。这正是我们希望触发告警(如 Slack)的时刻。
此外,我们计划将 Kube-state-metrics 配置示例和 Prometheus 规则贡献到 ArgoCD 上游,以便社区有更多可用的运维资产。
告警信息富化:精准触达负责人
我们过滤了信息,知道了问题所在,但有时这还不够:你该把问题告诉谁?你可以发送到一个通用的 Slack 频道,但如果负责人不在线呢?(我们有 90 人分布在 7 个国家)。
因此,我们需要用额外信息来丰富告警。我们运行一个代理,它会查找 ArgoCD 资源,追溯提交信息,找到是谁修改了应用、Helm Chart 或值文件仓库,然后用这些信息丰富告警,最后发送 Slack 消息。
消息不仅发送到通用频道,让所有人知道有问题,还会直接@那个负责人,说:“嘿,你的部署出了问题,需要处理一下。” 这对于长时间运行的同步特别有用,负责人不需要记得一小时后回来检查,系统会主动通知。
我们最近内部发布了这个功能,希望未来能将其通用化并贡献给社区。
总结与资源
本节课中,我们一起学习了在大规模、多维度 Kubernetes 环境中使用 ArgoCD 的挑战与解决方案。
我们探讨了如何通过集群属性与分组来管理复杂的部署矩阵,如何利用 Kube-state-metrics 和 Prometheus 规则创建自定义指标以增强部署可见性,以及如何过滤噪音、实现精准告警,并通过信息富化将问题直接推送给相关负责人。我们还看到了如何利用工具快速搭建本地演示环境。
相关资源(代码库、Prometheus 规则等)可以通过以下 QR 码获取。我们希望能将其纳入 ArgoCD Labs 或 ArgoCD 主代码库中。


感谢阅读,如果你有任何问题,可以通过 CNCF Slack 或 Kubernetes Slack 联系我们。
018:告别流水线——通过提交状态协调环境晋升
在本教程中,我们将学习如何利用声明式 API 和 Git 提交状态来替代传统的 CI/CD 流水线,实现自动化的、可控的环境晋升流程。我们将从 GitOps 的历史演变讲起,深入理解“无流水线”理念,并详细解析基于提交状态的环境晋升机制。


讲师介绍
我是 Michael Crenshaw,Intuit 公司的首席软件工程师,任职于 ArgoCD 和 Rollouts 团队,同时也是 Argo CD 项目的核心维护者之一。
这位是 Zach Uler,同样来自我们的 ArgoCD Rollouts 团队,他是 Argo Rollouts 项目的核心维护者。



关于 Intuit:我们是一家金融软件公司,提供会计软件、税务软件等服务。我们拥有庞大的用户基数,这意味着巨大的扩展性挑战。ArgoCD 和所有 Argo 项目是我们应对这些挑战的重要组成部分。Intuit 也是开源的大力支持者,曾两次获得 CNCF 终端用户奖,创建并开源了包括 Argo 在内的多个项目。我个人非常感谢 Intuit 允许我将维护开源软件作为工作的一部分。

议程概述
本次演讲名为“告别流水线”。我们需要了解为何要摒弃流水线,以及可能的替代方案。我们将回顾 GitOps 的演变历程,解释我们认为其未来的发展方向。我们将重点讨论环境晋升如何通过提交状态来实现。Zach 将为我们慢速演示 GitOps Promoter 项目中提交状态的工作机制,最后我们将探讨生态系统未来的发展。

告别流水线
首先,让我们明确什么是流水线,以及可能的替代方案。流水线包括 Argo Workflows、GitHub Actions、Jenkinsfile 等。声明式 API 则类似于 Kubernetes Pod 规范、StatefulSet 以及 ArgoCD Application 规范。声明式 API 更侧重于描述你“想要什么”,让系统自行解决如何实现;而流水线则更侧重于用非常明确的步骤描述“如何做”。



声明式 API 具有一些优势,我们将重点讨论关注点分离。在声明式 API 中,我可以提供一个用户关心的规范(例如环境晋升的步骤),而在后端,平台可以拥有另一个描述其关注点的独立规范。在流水线中,这些关注点往往会混杂在一起,形成“意大利面条式”的依赖关系。最终,开发人员不得不查看平台代码,而平台团队也需要查看开发人员的代码。这在调试体验中尤为明显,我的团队因此收到了大量支持请求。例如,当开发人员部署失败时,他们面对的是数千行 Jenkins 日志,其中大部分内容对他们毫无意义,因为这些代码是由平台团队编写的。因此,一个只关注其需求的声明式 API,可以让我们仅向用户暴露他们所需的错误信息和上下文。
关注点分离还能在定制化与合规性之间取得良好平衡。如前所述,流水线往往将事物紧密耦合。在 Intuit,我们曾提供一个 Jenkinsfile 作为晋升流水线,用户可以随意修改它,并且常常以平台团队不希望的方式修改。如果我们能提供一个声明式 API,只允许用户操作他们被允许的“旋钮”,那么对用户和平台双方来说,事情都会变得好得多。



GitOps 的演变历程
为了了解未来,我们需要理解 GitOps 的历史。在“史前时代”,一切非常简单。你有一个包含“干燥”清单(dry manifests)的主分支,例如 Helm values、定制化覆盖层(overlays)。Argo CD 会动态地水合(hydrate)这些清单,然后自动同步到集群。

但这种模式很快就被打破了。我们关闭了自动同步,让用户手动点击同步按钮,原因有二:第一,我们希望用户在真正部署之前能看到水合后的清单差异,以便他们理解将要部署的内容;第二,他们需要进行手动环境晋升门控(gating)。他们会先同步到开发环境,查看应用,可能运行一些手动测试,然后再同步到预发布环境,依此类推。


手动操作非常繁琐,没有持续多久。我们用晋升流水线取代了这些用户交互。流水线中会运行 argocd app sync,等待 ArgoCD 应用就绪,可能还会运行一些测试,然后进入下一个环境。这样我们实现了自动化,但用户却脱离了水合清单的体验,他们不再审查这些清单。因此,我们回到了在流水线中渲染清单的模式,即“渲染清单模式”,这样我们至少拥有了渲染后清单的完整历史记录,即使用户在合并前没有第一时间查看。如图所示,这里有很多流水线,这也是 Intuit 目前所处的状态:使用 Jenkins 流水线进行清单渲染和晋升。
现在,我们可以开始讨论用声明式 API 来替代这些明确定义的问题和解决方案,从而简化流程。
迈向声明式 API:替换水合流水线
第一步是替换水合流水线。ArgoCD 2.14 引入了一个名为 Source Hydrator 的新功能,它是一个声明式 API。它只是 Application 规范中的一个字段,名为 sourceHydrator。它只需指定包含干燥清单的分支,ArgoCD 就会为你水合这些清单,并将其推送到 Git,从而获得完整的审计历史。
Source Hydrator 的一个很酷的功能是,你不仅可以推送到一个水合分支,还可以按环境推送到多个分支,或者按你想要的任何方式拆分。例如,你可以将与开发环境相关的所有应用,将其清单推送到一个 dev 分支;预发布和生产环境也各自拥有自己的水合清单分支。

这是我们从历史走向我们认为的 GitOps 环境晋升未来的转折点。在进入晋升部分之前,我们只需要对这个图景再做一次调整。但我想暂停一下,特别说明:
这并非你听说过的基于分支的环境管理方式。今天已经有好几个人来问我们:“等等,我们不是不应该把环境放在不同的分支里吗?” 是的,没错。不要告诉你的用户用不同的分支来代表他们的环境。所有内容都应该进入主分支。这里提到的分支是在后端自动生成的,它们是自动化的,不存在基于分支的环境管理所带来的问题。这是不同的概念,我想在进入晋升部分之前澄清这一点。
实现环境晋升的关键调整
这个调整使我们能够实现环境晋升。我们不是简单地将清单水合到每个环境的分支,而是为每个环境准备一对分支。这为你提供了一个在变更生效前暂存提议变更的地方。
因此,Hydrator 将渲染后的清单推送到 dev-next、stage-next、prod-next 分支。我们称这些为“提议水合分支”。然后,我们自动为每个分支创建拉取请求(PR),指向我们称为“活跃水合分支”的分支(例如 dev、stage、prod)。图中加入了用户图标,表示我们可以回到这个历史点,让用户查看 PR、合并它、在应用上运行测试,然后合并下一个环境的 PR。这就是手动晋升。
在历史上,我们通常会用流水线来替代这个手动步骤。但我们认为,在这个系统中,环境晋升的定义已经足够明确,我们可以直接跳转到声明式 API。
这就是 Promotion Strategy。它是一个真实的 CRD,由一个真实的控制器管理,该控制器位于 Argo Project Labs 下的 GitOps Promoter 代码仓库中。
我将带你了解它的三个不同部分:
- 环境:这只是一个列表,列出了 ArgoCD 为每个环境自动同步的分支。这个列表的顺序决定了你晋升事物的顺序。但你仍然需要在环境之间设置门控。
- 提议提交状态:这些是你在合并拉取请求之前就知道的事情,例如检查 YAML 语法或检查是否有部署冻结。你不需要查看实时状态来确定这些事情。
- 活跃提交状态:这些代表在 PR 合并后你了解到的事情。例如,我的 Argo CD 应用在合并后是否变得健康?你可以根据需要为不同的环境运行不同的检查,例如,仅为预发布环境运行性能测试。
以上就是用户视角下的 GitOps 晋升体验。我们之前在“太空时代 GitOps”系列演讲中也讨论过这一点。现在,我们想带大家深入了解幕后,理解我们作为平台维护者如何为开发人员启用这种体验。
平台视角:简化与核心机制
让我们简化图表,只关注我们关心的部分。我们假设 Hydrator 正常工作并运行(尽管它目前处于 Alpha 状态,但我们会修复错误)。忽略图表的左侧。图表的右侧,ArgoCD 非常擅长自动同步,我们假设它能成功部署到 Kubernetes。中间部分是我们的工作。
我们有六个需要关注的分支。我们的工作就是对每个分支及其头部提交持有“意见”。这就是启用 GitOps Promoter 所需要做的全部事情:持有意见。
这些是我们持有的意见:
- 提议端:检查 YAML 语法,检查部署冻结。
- 活跃端:检查 ArgoCD 应用健康状态,运行性能测试。
我们需要将这些意见与 Promotion Strategy 控制器可以使用的东西关联起来。我们通过查看用户所做的“干燥”提交来实现这一点。例如,用户提交了“更新了镜像标签”,新提交的 SHA 是 5a2c...。
Hydrator 会向它推送到提议分支的水合清单提交中添加一个元数据文件,其中包含那个干燥提交的 SHA。当然,当 PR 被合并时,这个 SHA 也会出现在活跃分支中。但是,当我们需要向 Promotion Strategy 控制器表达我们的意见时,我们需要一种方法来区分这些不同的分支。我们利用 Git 的工作原理来实现这一点:每次提交都会获得一个唯一的 SHA。因此,每个位置都有一个我们可以关联意见的唯一 SHA。
我们使用另一个 CRD 来实现这种关联。这就是简化后的状态。作为平台管理员,为了给用户提供声明式的环境晋升,我们只需要关心这些。
这个 CRD 就是 CommitStatus。它同样位于 GitOps Promoter 项目中,目前已经可以工作。我们关心的部分是:
key:检查的名称,例如ArgoCDHealth。sha:例如4f6a1...,如果你还记得上一张幻灯片,这对应右上角活跃开发分支的提交。phase:状态,例如successful。
这样,我们就表达了“该应用已健康”的意见,从而允许进入下一个阶段。
如果你精通 SCM(例如 GitHub),你会注意到,在 GitHub 中,你只能通过在提议提交(即你将要合并到下一个分支的提交)上设置提交状态来阻止 PR 合并。因此,我们需要在提议分支上创建一个合成的提交状态来代表前一个环境的状态。例如,我们希望在开发分支的提交变得健康之前,阻止 stage-next 合并。我们就创建这个合成提交状态。
Promotion Strategy 控制器会为你完成这个工作。重申一下,你只需要关心对这些提交持有意见。一旦你表达了意见,Promotion Strategy 控制器就会为你复制它。你不需要担心背后的细节。
为了持有这些意见,你可能需要编写自动化程序来管理这些提交状态。Zach 将慢速手动演示如何管理提交状态,这将展示你如何将其自动化。
慢动作演示:提交状态管理
这个演示更像是展示如果你要编写一个控制器来自动化这些步骤,你会做什么。它基本上是一个控制器为了对这些分支表达意见而必须执行的任务。
我们从 GitHub 上的一个定制化布局开始,包含 base 目录和 dev、prod、staging 环境。我将对 base 做一个会影响所有环境的更改,然后提交这个更改。
正如 Michael 所说,我们拥有这些分支对。现在,Hydrator 将运行,并将所有不同环境的渲染输出提交到它们各自的 -next 分支。
我们应该能在 ArgoCD 中看到一系列拉取请求开始出现,这些 PR 也会在 GitHub 上显示。现在我们有三个 PR,分别对应三个环境。每个 PR 上都有一些提交状态,例如 ArgoCDHealth、Linting 等。
作为 Linting 提交状态管理器,我需要对我提议的变更分支 development-next 表达意见。我可以轻松地获取 development-next 分支的 SHA,并创建一个 CommitStatus CR,将 phase 设置为 pending。在 GitHub 上,我们会看到这个检查出现并处于待定状态。
然后,我作为 Linter 检查 YAML,一切看起来都很好。我将更新 CommitStatus CR,将 phase 设置为 success。这会使检查变为绿色。现在,Promoter 获得了合并(即晋升)这个 PR 到活跃运行状态的许可。
由于这是第一个环境,没有前序环境,我们暂时不关心那些在尝试晋升预发布环境时才生效的活跃提交状态。
现在 PR 已合并。我切换到 ArgoCD Health 提交状态管理器的角色,需要对当前运行的开发分支表达意见。我获取开发分支的提交 SHA,并报告我的意见:ArgoCD 是健康的,一切已同步。
这时,Michael 提到的“魔法复制”开始起作用。如果我们查看预发布环境的 PR,我们会看到由 Promotion Strategy 控制器管理的一些提交状态。我们可以看到,针对开发环境的活跃检查 ArgoCDHealth 仍然处于待定状态。作为 ArgoCD 健康状态控制器,我已经检查过,ArgoCD 是健康的,一切已同步,所以我可以报告活跃开发环境现在是成功的。在预发布环境的 PR 上,我们应该看到相应的检查变为绿色。
然而,Linting 检查还没有被报告,这只是因为我手动操作太慢,不如自动化系统高效。让我们继续获取 staging-next 的 SHA,并报告其状态。我们将其保持为 pending。我们会看到状态仍然不是“可合并”,因为我们需要提议分支上的 Linting 通过。我们报告 Linting 成功,一切变为绿色,Promotion Strategy 控制器现在可以合并这个 PR,这意味着我们已经将变更晋升到了预发布环境。
最后,我们来看生产环境。生产环境有更多的检查。我们获取 production-next 的 SHA,并报告所有提议端的检查状态,例如 DeploymentFreeze 和 Linting。我们还需要对活跃的预发布环境表达意见,获取其提交 SHA,并报告 IntegrationTest 和 ArgoCDHealth 状态。
现在,在生产环境的 PR 上,我们应该有需要变绿才能合并的提交状态列表。作为控制器,我们持续监控这些状态。假设性能测试已在预发布环境通过,我们报告这个状态。同时,ArgoCD 健康状态也已同步并运行良好,我们将其设置为成功。
在 GitHub 上,我们可以看到前一个环境(预发布环境)的合成提交状态已经同步且健康。剩下的就是 Linting 检查,我们报告它已通过。最后,作为部署冻结检查管理器,我们查询变更管理系统,发现当前没有部署冻结,因此我们可以报告允许合并。
Promoter 现在将介入,合并那个 PR。至此,你已经通过这三个阶段完成了环境晋升。
目前,我们只编写了 ArgoCD 提交状态管理器,它是 GitOps Promoter 的一部分。安装 GitOps Promoter 后,你就会获得“我的前一个 ArgoCD 应用是否已同步且健康”的检查。我们期待有更多贡献来添加额外的提交状态控制器,欢迎大家联系我们。
生态系统展望与总结
我们对演示顺利进行感到非常高兴。尽管这是今天的最后一场会议,但大家似乎都非常专注,非常感谢。
正如 Zach 所示,那是慢动作下的工作原理,你可以将所有步骤自动化。再次强调,这些都是平台端的工作,是幕后的部分。你的用户不需要担心这些。我们做这些工作是为了让用户获得一个无需思考的、优美的自动化晋升体验。

那么,GitOps 晋升领域的下一步是什么?首先,介绍一下 GitOps Promoter 代码仓库近期的动态:正如 Zach 所说,他编写了 ArgoCD 提交状态控制器,因此你可以开箱即用地获得 ArgoCD 健康状态作为晋升门控。最近社区也有几个 PR:Robin Lee 添加了 GitLab 支持(他今天也在现场),还有人添加了自定义 PR 标题和正文模板支持,以便你可以根据组织需求定制那些自动生成的 PR。
展望未来,我们希望支持更多的 SCM。我们与大厅里的一些人交流过,他们非常需要 Azure DevOps 支持,我们期待相关的 PR。我们还希望添加除 ArgoCD 之外的更多提交状态管理器,以便提供一套开箱即用的门控选项。最后,我们想要一个漂亮的 ArgoCD UI。CRD 本身很好,状态字段包含了丰富的信息。但 Zach 和我都不是 UI 开发人员,因此我们将寻求帮助来为用户构建一个漂亮的 UI 来展示所有这些信息。
Intuit 开源项目,请扫描二维码查看我们的 LinkedIn,了解相关动态。右边的二维码包含指向 CNCF Slack 频道(关于 GitOps Promoter)或 GitHub 仓库等的链接。也欢迎直接与我们交流,本周在 KubeCon 期间,我们大部分时间都会在 Argo 项目展台。






总结
在本节课中,我们一起学习了如何通过声明式 API 和 Git 提交状态来革新传统的 CI/CD 流水线。我们从 GitOps 的演变历史出发,理解了流水线带来的问题,并深入探讨了基于“分支对”和提交状态的环境晋升机制。通过分离关注点,平台团队可以构建自动化的门控系统,而开发人员则获得了一个简洁、可控的晋升体验,无需深入复杂的流水线细节。GitOps Promoter 项目为实现这一愿景提供了具体的工具和模式,标志着 GitOps 实践向更声明式、更高效的方向迈进。
019:使用Argo CD Agent与Open Cluster Management实现可扩展的GitOps


在本教程中,我们将探讨如何结合使用Argo CD Agent与Open Cluster Management(OCM)来构建高度可扩展、安全且具有弹性的GitOps部署架构。我们将从基础概念开始,逐步深入到具体的集成模式和工作原理。
概述
Open Cluster Management是一个CNCF沙箱项目,专注于多集群、多云环境下的Kubernetes管理。它提供了一个供应商中立的API,并基于Kubernetes API构建,使其易于集成和使用。通过与Argo CD的集成,OCM能够将GitOps实践扩展到大规模、分布式的集群环境中。
Open Cluster Management 核心概念
Open Cluster Management的核心架构基于中心辐射模型。您将集群注册到一个中心“Hub”集群,Hub会在每个被管理的“Spoke”集群上部署一个代理。
以下是其工作流程的关键组件:
- 集群注册:将您的Kubernetes集群注册到Hub。
- 代理与插件:Hub在每个Spoke集群上部署一个代理。这个代理可以加载各种“插件”来扩展功能。
- 工作负载分发:Hub可以将工作负载定义分发到选定的Spoke集群。这适用于分发像Argo CD
Application这样的资源对象。 - 放置规则:这是OCM的“特殊酱料”。它允许您以动态和策略性的方式对集群进行过滤和分组。放置规则可以基于:
- 集群标签
- 集群声明:一种自定义CRD,Spoke集群可以动态地向Hub报告其属性(例如,GPU类型、可用区)。
- 放置分数:基于资源利用率(如空闲CPU/内存)对集群进行排名。
Argo CD 与 OCM 的集成模式
上一节我们介绍了OCM的基础,本节中我们来看看它与Argo CD集成的三种主要模式。
模式一:推送模型(传统增强)
这是我们最早的集成方式。它增强了标准的Argo CD中心部署模式。
- 工作原理:Argo CD运行在Hub上。OCM的“放置”功能被集成到Argo CD的ApplicationSet中,作为一个“自定义决策资源”。ApplicationSet可以查询OCM的放置规则,动态获取目标集群列表,从而将应用部署到正确的集群组。
- 优点:实现了基于策略的多集群应用部署。
- 挑战:架构上仍然是中心化的推送模式,存在单点故障风险,且Hub需要与所有Spoke集群保持高速网络连接并存储其kubeconfig。
模式二:拉取模型
这种模式将Argo CD实例部署到每个Spoke集群上,实现了工作负载的本地化处理。
- 工作原理:
- 用户在Hub上创建标准的Argo CD
Application资源。 - 一个特殊的注解会阻止Hub上的Argo CD控制器处理这个应用。
- OCM控制器将这个
Application资源封装到一个ManifestWork对象中。 - OCM代理将
ManifestWork拉取到目标Spoke集群。 - Spoke集群上的本地Argo CD实例读取并同步这个应用。
- 用户在Hub上创建标准的Argo CD
- 优点:
- Spoke集群自治:即使Hub宕机,Spoke集群上的Argo CD仍能继续协调其应用。
- 消除高速链路依赖:Spoke集群独立从Git仓库拉取代码,Hub只负责分发应用定义。
- 提升安全性:Hub上无需存储Spoke集群的kubeconfig。
- 当前限制:应用状态的同步回Hub可能不完整,影响UI的完全展示。
模式三:Argo CD Agent 模型(推荐)
这是功能最全面、最具前景的集成模式,结合了前两种模式的优点。
- 核心思想:在Hub上运行一个轻量的“Principle”控制器,在每个Spoke集群上运行一个轻量的“Agent”控制器和必要的Argo CD组件(如Repo Server)。Agent主动从Principle拉取应用定义。
- 架构组件:
- Principle:运行在Hub,负责管理应用定义并响应Agent的请求。
- Agent:运行在每个Spoke集群,负责从Principle拉取分配给本集群的应用定义,并交给本地Argo CD控制器处理。
- OCM的增强作用:
- 自动化部署:OCM可以自动将Argo CD Agent及其相关组件(应用控制器、仓库服务器等)作为“插件”部署到新注册的Spoke集群。
- 配置管理:简化整个Argo CD Agent体系的配置。
- 增强安全性:贡献并集成了基于mTLS的认证,替代了默认的用户名/密码方式。
Argo CD Agent 的优势总结
以下是使用Argo CD Agent架构带来的关键优势:
- 高度可扩展:采用中心辐射模型,轻松应对成百上千的集群规模。
- 轻量级部署:在Spoke集群上仅部署必需的Argo CD组件,而非完整套件。
- 代理发起通信:Spoke集群上的Agent主动连接Hub,更符合安全边界要求(拉取而非推送)。
- 工作负载集群自治:Hub故障不影响Spoke集群上现有应用的持续协调。
- 消除高速网络依赖:适合边缘、船舶、车辆等间歇性连接环境。
- 安全设计:
- Hub无需存储Spoke集群的kubeconfig。
- 通过集成的mTLS认证,使用短期证书(OCM默认每小时轮换),安全性更高。
演示概览

在演示中,我们看到了如何使用OCM快速搭建Argo CD Agent环境:

- 定义插件模板:在Hub上创建一个AddOn模板,定义了要部署到Spoke的Argo CD组件和Agent。
- 部署插件实例:通过OCM的
ManagedClusterAddOn,将模板实例化并部署到指定的Spoke集群。 - 创建应用:在Hub上创建Argo CD
Application资源,目标指向特定的Spoke集群。 - 同步与删除:Agent将应用定义拉取到Spoke,本地Argo CD开始同步。从Hub删除应用后,更改也会同步到Spoke并清理资源。
安全贡献:mTLS 集成

团队为Argo CD Agent的安全做出了重要贡献。默认的Agent使用用户名/密码认证,这仍然存在凭证管理的挑战。团队增强了其mTLS集成能力:



- 工作原理:Agent使用由OCM自动管理和轮换的客户端证书向Principle进行认证。
- 优势:
- 无需密码:消除了静态密码的存储和管理。
- 自动轮换:OCM默认每小时轮换证书,即使证书泄露,攻击窗口也极短。
- 集群标识:从证书的Subject Name中提取集群名称,用于在Principle端标识请求来源。
总结

本节课中我们一起学习了如何利用Argo CD Agent与Open Cluster Management的强大组合来应对大规模GitOps部署的挑战。我们从OCM的基础概念出发,详细分析了三种集成模式,并重点介绍了最具优势的Argo CD Agent模型。该模型通过中心辐射、拉取通信、工作负载自治和安全设计等特性,为实现高度可扩展、弹性和安全的云原生GitOps架构提供了清晰的路径。您可以从Argo CD官方文档中关于OCM集成的部分开始实践。
020:使用 Argo Events 实现实时事件自动修复 🛡️


在本节课中,我们将学习如何利用 Argo Events 构建自动化的弹性系统,实现实时事件的检测与修复。我们将从核心概念入手,通过一个具体的演示案例,展示如何将监控告警、决策判断和修复动作串联成一个完整的自动化流程。
概述:什么是自动修复?
自动修复是指系统自动检测并解决故障的过程。一个理想的自动修复系统能够发现问题并尝试解决它,从而实现应用和基础设施的自愈。
你可以将其与现有的开发工具或流水线集成,以提供实时的故障缓解。例如,一个应用在99%的时间里运行良好,但偶尔会出现功能异常,通常简单的重启就能解决问题。在这种情况下,自动修复可以通过检查日志并重启服务来缓解问题,之后你的团队再添加永久性修复。这可以节省成本、时间并减少人工操作。
自动修复的工作原理
自动修复通常包含三个核心阶段:检测、决策和行动。
上一节我们介绍了自动修复的基本概念,本节中我们来看看它的具体工作流程。
以下是自动修复的三个阶段:
-
检测
- 这是一个持续监控系统的工具。
- 它通常检查系统中的所有日志、指标和活动。
- 当检测到异常时,该组件会发出警报。例如,使用 Prometheus 和 Alertmanager 设置规则,当 CPU 使用率超过90%持续一段时间时触发告警;或者使用 Grafana Loki,在日志中发现可疑内容时发出通知。
-
决策
- 该组件接收来自检测组件的通知,对其进行验证,并根据信息采取行动。
- 例如,你收到一个通知,称系统在某个端点上返回500错误。决策组件会验证此通知,并根据严重程度或其他预定义规则,决定是否触发修复动作。
-
行动
- 这是实际的修复动作。
- 它接收来自决策引擎的命令,并基于该命令启动适当的操作。这个操作可以是一个工作流、一个无服务器函数,或者一个简单的命令来回滚系统中的更改。
- 沿用上面的例子,修复动作可能是重启受影响的服务器,或者如果该服务最近有更新,则回滚到上一个版本。
Argo Events 简介
了解了自动修复的流程后,我们需要一个强大的工具来充当“决策”和“触发”的核心。这就是 Argo Events。
Argo Events 允许你定义强大的事件驱动工作流,使你的系统能够对故障、安全漏洞或业务触发器等事件做出反应,而无需人工干预。
Argo Events 是一个 Kubernetes 原生的事件驱动工作流自动化框架。它使用户能够使用事件源、传感器和触发器来定义和管理基于事件的自动化。
例如,Argo Events 可以接收你的 Webhook 事件,并将其传递给相应的传感器。该传感器随后会触发适当的操作,在本例中,这个操作是一个工作流。
Argo Events 的核心组件
Argo Events 主要由四个组件构成:




- 事件源:定义了从外部源消费事件的配置。它可以转换事件,并将事件分派到事件总线。例如,如果你想消费一个 Webhook,就需要创建一个 Webhook 事件源配置。
- 事件总线:传输层,负责将事件源连接到传感器。用于此目的的组件包括 Kafka、NATS JetStream 等。
- 传感器:监听来自事件总线的事件,并触发相应的操作。
- 控制器管理器:一个常规的 Kubernetes Operator,负责管理上述组件。

实战演示:自动响应加密挖矿告警
理论部分已经介绍完毕,现在让我们通过一个具体的演示来看看如何将 Argo Events 应用于实际场景。
在本演示中,我们将模拟一个场景:一个恶意行为者在夜间侵入你的环境,并在你的集群中运行加密挖矿程序。如果没有自动修复,你可能只有一些告警来告诉你 CPU 或 GPU 使用率激增,但这很可能被忽略直到早晨。因此,你需要一种更快应对此场景的方法。

演示流程如下:
- 检测:使用 Prometheus Alertmanager 通知 Argo Events 集群中正在运行加密挖矿程序。
- 决策:Argo Events 将接收此事件,对其进行过滤、处理,并触发高严重性的告警。
- 行动:随后执行一个 Argo Workflow。该工作流将捕获受影响 Pod 的元数据,然后使用网络策略隔离该 Pod,使用 Trivy 扫描容器镜像,并通过 Slack 或 PagerDuty 发出警报。
以下是演示中关键配置的说明:
- 事件源配置:我们配置了一个 Webhook 事件源来接收来自 Alertmanager 的告警。我们指定了端口、端点和使用 POST 方法。同时使用了 Bearer Token 进行身份验证。Argo Events 会过滤所有请求,仅当告警状态为
firing、严重性为critical且告警名称为cryptominer-detected时才采取行动。 - 传感器配置:传感器接收到事件后,会将其转换为更友好的结构,提取 Pod 名称、命名空间、实例和受影响的容器等信息。然后,传感器启动一个 Argo Workflow,并将转换后的值作为工作流参数传递。
- 修复工作流:工作流包含多个修复和数据收集步骤,目的是快速捕获所有数据并限制 Pod,直到值班人员前来检查。
- 使用
kubectl获取 Pod 日志和元数据,并将所有数据保存到 S3 以供进一步分析。 - 应用网络策略以隔离该 Pod,阻止其所有入站和出站流量。
- 使用 Trivy 扫描容器镜像以查找可能的安全问题。
- 通过 Slack 通知用户有关潜在加密挖矿程序的信息,并附上之前保存到 S3 的数据链接。
- 封锁节点,以防节点本身出现问题。
- 使用
通过这个演示,我们看到了一个完整的自动修复流程如何从告警开始,经过决策判断,最终执行一系列复杂的修复动作,全部自动化完成。
最佳实践与优势
在构建自动修复系统时,遵循一些最佳实践至关重要:
- 验证与过滤事件:不要每次发生事件都触发修复,只在需要时才行动。
- 添加重试策略和死信队列:以防处理过程中出现故障。
- 确保操作幂等性:避免多次触发同一操作。
- 为系统添加告警和监控:监控自动修复流程本身。
- 充分测试你的流水线:模拟各种场景并观察系统的反应。
使用 Argo Events 构建自动修复系统能带来诸多好处:
- 支持多种事件源和目的地,是开源且容器原生的。
- 即插即用,易于扩展和维护。
- 支持基本的事件过滤和丢弃,对于更复杂的逻辑,可以轻松添加工作流来处理。
- 可以组合多个事件源,例如,可以同时使用 Alertmanager 和 AWS Guard Duty 来检测加密挖矿,只有从两者都收到通知时才确认事件,这用 Argo Events 很容易实现。
- 通过自动化值班手册,可以最大限度地减少人为错误,自动化响应速度远快于人工。
- 降低运营成本和手动工作量,让工程师从重复性的故障排查中解放出来,专注于创新。
- 增强安全性,可以检测安全异常并立即触发缓解措施。
总结

本节课中我们一起学习了如何利用 Argo Events 实现实时事件的自动修复。我们从自动修复的核心概念和工作原理讲起,深入介绍了 Argo Events 作为事件驱动自动化框架的组件与能力。通过一个完整的加密挖矿告警响应演示,我们看到了如何将检测、决策、行动三个阶段无缝衔接,构建出自愈系统。最后,我们探讨了实施自动修复的最佳实践及其为系统弹性、安全性和运营效率带来的显著优势。希望本教程能帮助你开始构建自己的自动化修复流水线。
021:利用 Argo CD 管理 OCI 源内容


概述
在本教程中,我们将学习 ArgoCD 如何实现对 OCI(Open Container Initiative)仓库的原生集成。我们将了解其背后的工作原理、带来的优势、开发历程以及如何开始使用这一新功能。通过本教程,初学者可以理解如何将 OCI 仓库作为应用清单的存储源,从而在 Git 受限或更偏好容器化工作流的环境中部署应用。
核心组件:Repo Server 的工作原理
上一节我们介绍了本教程的概述,本节中我们来看看实现 OCI 集成的核心组件——Repo Server 是如何工作的。理解后端机制有助于明白 ArgoCD 如何支持 OCI。
ArgoCD 包含多个组件,如应用控制器、应用集控制器等。其中,Repo Server 是后端访问 Git、Helm 以及现在 OCI 的接入点。Repo Server 维护着几种不同的缓存:
- 内存缓存:用于存储版本信息。对于 Git 仓库,这包括提交哈希、标签和分支名;对于 OCI 仓库,则是镜像标签。
- 磁盘缓存:用于存储从 Git、OCI 镜像等提取的所有文件。
- Redis 缓存:用于存储渲染后的清单。
OCI 的实现需要与这些缓存和功能点集成。幸运的是,OCI 的工作方式与 Git 和 Helm 足够相似,使得集成变得相对顺畅。
在 Repo Server 内部,为了实现这些缓存和功能,OCI 层需要完成以下三个核心步骤:
- 解析版本:访问 OCI 仓库,获取所有标签,根据用户指定的版本范围(如语义化版本)进行匹配,并找到最新的一个,然后将版本列表缓存起来。
- 获取制品:拉取 OCI 清单(Manifest)制品。通常,一个 OCI 制品包含一个层(Layer),该层包含了用于生成清单的所有文件。
- 提取内容:将上述文件提取到磁盘,使其可供渲染逻辑使用。
所有渲染逻辑在 Git、Helm 和 OCI 之间都是相同的,这保证了可靠性。但上述前三个阶段必须由 OCI 层具体实现。
使用 OCI 的优势
上一节我们了解了 Repo Server 如何支持 OCI,本节中我们来看看使用 OCI 作为源能带来哪些实际好处。
最大的优势在于,你无需改变现有的 ArgoCD 使用模式。你可以沿用与 Git 或 Helm 仓库相同的模式,只是将内容打包成新格式并推送到 OCI 注册表,而非 Git 仓库。
以下是使用 OCI 源的具体优势:
- 突破环境限制:在许多组织(尤其是受严格监管的行业)的生产环境中,可能不允许使用 Git。此时,可以使用必须可用的 OCI 制品注册表(如容器镜像仓库)来存储清单。
- 简化演示与测试:对于创建演示或测试场景,无需搭建 GitLab 或配置防火墙规则开放 Git 访问,可以直接使用 OCI 仓库中的内容。
- 增强安全与元数据:OCI 社区的工作使得可以在主要部署制品之外,存储各种额外的元数据和安全性制品。例如,你可以在包含 ArgoCD 所需文件的 tar 包上附加签名,或添加其他元数据,未来可能支持基于制品类型的搜索或过滤。
- 提供更多选项:对于 Helm 用户,现在有多种使用方式:作为扁平的 Git 仓库、OCI Helm 图表、传统 Helm 仓库,或作为 OCI 制品。这为在不同架构环境中工作提供了灵活性。
功能开发历程与社区协作
上一节我们探讨了使用 OCI 的优势,本节中我们来回顾一下这个功能从构想到实现的开发历程,这离不开开放的社区协作。
OCI 支持功能是许多人共同努力的成果。其愿景最初由 Red Hat 的 Andy 在两年前提出,并形成了详细的提案。来自 Akuity、Intuit、Microsoft 等公司的开发者(如 Blake、Michael)也基于客户需求(如在隔离环境中的部署需求)推动了这一功能的开发。
开发过程并非一帆风顺。从 2023 年到 2025 年,团队经历了漫长的努力。初始概念验证(POC)很快完成,但后续的“最后 10%”工作(如理解 OCI 规范细节、设计单层还是多层结构、如何与 ArgoCD 现有架构无缝集成)花费了大量时间进行打磨和重构。
跨社区协作是成功的关键。ArgoCD 社区与 OCI 规范社区(特别是 Auras 项目)保持了紧密沟通。通过专门的 Slack 频道,来自全球(北美、欧洲、亚太)的贡献者共同讨论、设计和实现。Microsoft 的团队也基于新的用例,投入资源帮助推进开发。
这个功能预计将在 ArgoCD 3.1 版本中正式发布。
组织支持对开源的重要性
上一节我们看到了社区协作的力量,本节中我们强调一个更深层的成功因素:组织对开源贡献的支持。
实现这样一个重大功能,需要贡献者投入大量连续的时间。如果没有所在组织的支持,允许员工在工作时间内参与开源开发,这几乎是不可能完成的。
- 时间投入是关键:开发者通常有繁忙的内部任务。获得组织批准,将一部分工作时间(即使是 5% 或 10%)用于特定开源功能开发,是极其宝贵的。
- 多元贡献模式:开源项目既需要能够快速提交错误修复的贡献者,也需要能够长期深入项目、负责设计评审和方向指导的资深贡献者。两者都需要组织的支持。
- 互利共赢:组织支持开源,不仅能推动项目发展,也能为组织带来技术影响力、人才吸引力和对项目方向的发言权。Microsoft 等公司投入开源,也需要了解社区的真实需求来指导投资方向。
如何使用 OCI 源
上一节我们强调了成功背后的支持体系,本节中我们回到技术层面,看看如何在 ArgoCD 中实际配置和使用 OCI 源。




在即将发布的 ArgoCD 3.1 中,将引入一个新的 OCI 客户端类型。这意味着除了现有的 git 和 helm,现在多了一个 oci 源类型。

以下是配置的核心要点:



- 协议前缀:在配置仓库 URL 时,使用
oci://作为协议前缀,ArgoCD 就会自动进入 OCI 模式。 - 制品要求:开箱即用地支持构建为特定 OCI 镜像类型(如
application/vnd.oci.image.manifest.v1+json)的单层制品。也可以通过环境变量添加对自定义媒体类型的支持。 - Helm OCI 图表:原生支持 Helm OCI 图表,其处理方式有特殊逻辑。
- 路径与版本:
targetRevision对应 OCI 仓库中的标签。path取决于制品构建方式,通常是制品层中的目录路径。对于 Helm OCI 图表,路径固定为当前目录(.)。 - 凭证:OCI 仓库凭证的配置方式与其他源类型类似,支持 HTTPS 和 HTTP(不推荐)。

创建 OCI 制品的过程与使用 docker push 类似。你可以使用 oras 等工具,将包含清单文件的目录推送到兼容 OCI 的注册表(如 Docker Hub、GHCR、ACR 等),并可以添加作者、描述等 OCI 元数据。



总结
在本教程中,我们一起学习了 ArgoCD 原生集成 OCI 仓库的方方面面。
我们首先了解了 Repo Server 是实现此功能的核心,它通过解析版本、获取制品和提取内容三个步骤来处理 OCI 源。接着,我们探讨了使用 OCI 源的优势,包括突破 Git 环境限制、简化流程、增强安全性与元数据支持,并为部署提供了更多选项。然后,我们回顾了这个功能的 开发历程,看到了从提案到实现过程中,全球开源社区的紧密协作。我们也认识到 组织支持 对于完成此类大型开源功能至关重要。最后,我们介绍了如何在 ArgoCD 中 配置和使用 OCI 源,包括协议前缀、制品要求和凭证配置。

虽然现场演示因网络问题未能完美展示,但该功能已基本就绪,等待社区试用和反馈。这是一个通过社区协作克服挑战、扩展 ArgoCD 适用性的优秀范例。
023:自动扩缩与渐进式交付——天作之合

在本节课中,我们将要学习如何将 Argo Rollouts 与 Horizontal Pod Autoscaler (HPA) 结合使用,以实现既安全又经济的渐进式交付。我们将探讨成本挑战、解决方案以及两者协同工作的具体方式。
课程概述
大家好,我是 Cosmin,来自 Octopus Deploy 的开发者布道师,也是专注于 Argo Rollouts 和 Argo CD 的 Argo 团队成员。今天与我一同演讲的是 Anastasiia。
大家好,我是 Anastasiia Gubska,来自英国电信的 SRE/DevOps 工程师,也是 CNCF 大使。我们致力于推广 Argo Rollouts。
本次演讲将深入探讨在采用渐进式交付策略时,如何利用 Argo Rollouts 和 HPA 来应对成本挑战。
渐进式交付与 Argo Rollouts 基础
让我们从基础开始。Argo Rollouts 是一个用于实现渐进式交付的工具或解决方案。
渐进式交付 主要包含两种策略:蓝绿部署和金丝雀发布。
- 蓝绿部署:同时运行两个环境。蓝色环境运行应用的稳定版本,绿色环境运行新版本。当新版本在绿色环境就绪后,再将流量完全切换过去。
- 金丝雀发布:同样使用两个环境,但会逐步将流量从旧版本迁移到新版本。这让我们有机会在增加流量前验证应用运行状况,或在发现问题时快速回滚。
使用渐进式交付策略的好处在于,可以在零停机的情况下发布新版本,并能自动化处理回滚以解决问题。

Argo Rollouts 是 Kubernetes 原生的,它不依赖 Argo CD,两者可以独立工作。

安装 Argo Rollouts 后,你会获得一个新的 Kubernetes 资源类型:Rollout。这意味着你可以通过两种方式使用它:
- 为现有的
Deployment添加渐进式交付策略。 - 直接创建一个新的
Rollout资源。
以下是一个金丝雀策略的 Rollout 配置示例:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: example-rollout
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 10
- pause: {duration: 1h}
- setWeight: 20
# ... 更多步骤

如代码所示,你可以从 10% 的流量开始,暂停一小时后,再将流量提升至 20%。
Argo Rollouts 提供了仪表盘,可以实时查看部署状态。你能看到稳定的旧版本 Pod 和预览的新版本 Pod 的数量及流量分配情况。
Argo Rollouts 的一个强大特性是自动化监控。它会持续检查应用的性能和健康状态。如果发现问题,它会自动回滚并标记部署失败;如果一切顺利,则自动完成部署并标记成功。这意味着整个部署过程可以无需人工干预。

想象一下,你的团队可以在周五下午 5 点发起一个部署,然后安心下班,Argo Rollouts 会替你完成后续所有工作。

认识 Horizontal Pod Autoscaler (HPA)
接下来,我们谈谈自动扩缩。
本次讨论聚焦于 Horizontal Pod Autoscaler。HPA 会根据需求自动增加或减少 Pod 的数量。还有其他类型的扩缩器,如垂直扩缩、集群扩缩、基于自定义指标的扩缩以及 Kubernetes 事件驱动扩缩,你可以查阅官方文档了解更多。


HPA 监控 CPU 等指标,并在负载增加时(例如,黑色星期五促销或国际足球赛事期间流量激增)自动扩容。它使用 replicas 并设定阈值来决定何时扩缩。
公式: HPA 的核心是根据目标指标(如 CPU 使用率)动态调整 Pod 副本数,其行为可描述为:期望副本数 = ceil[当前副本数 * (当前指标值 / 目标指标值)]。
渐进式交付的成本挑战与基础优化
当你在云环境中采用渐进式交付策略时,成本可能成为一个显著问题。我们来看看如何降低相关成本影响。

在蓝绿部署示例中,两个环境各有 10 个 Pod,这可能会使部署成本翻倍。同样,在金丝雀发布中,当流量完全切换到新版本时,你也会暂时拥有双倍的 Pod 数量,导致成本增加。

有些人喜欢让测试运行数天甚至数周,但这并非使用 Argo Rollouts 最有效的方式。Argo Rollouts 更适合快速部署。不过,我们理解某些场景下确实需要长时间测试。
在直接使用 HPA 之前,让我们先看看 Argo Rollouts 本身提供的成本控制选项。
以下是无需 HPA 即可控制成本的方法。
有些人想直接使用 HPA,但我们可以先通过调整 Rollout 设置来管理成本。配置中高亮的属性可以帮助你管理成本,并固定部署期间使用的 Pod 数量。

我们建议你先了解这些选项,再尝试使用 HPA 策略。

- 蓝绿部署的成本控制:通过设置
previewReplicaCount字段,可以固定预览环境的 Pod 数量。例如,将其设为 5,意味着预览版本将只有 5 个 Pod,这能自动将部署成本降低 50%。 - 金丝雀部署的成本控制:在金丝雀发布中,你可能同时运行 20 个 Pod,导致成本翻倍。通过设置
dynamicStableScale: true属性,系统可以在增加新版本 Pod 时,自动减少稳定版本中的 Pod 数量,从而控制总资源消耗。
我们还有另一个解决方案可以讨论。
使用流量管理进行成本优化
在金丝雀发布中,除了控制 Pod 数量,我们还可以使用流量控制器来管理发送到每个 Pod 的流量比例。

左侧是没有流量管理的例子,每个 Pod 接收固定的流量比例(例如,一个 Pod 接收 10% 流量)。右侧是使用流量管理(本例使用 Linkerd)的例子,你可以将 80% 的流量导向一个 Pod。
这样,我们可以固定 Pod 数量(例如 5 个),但通过流量管理决定新版本接收多少流量(例如 50%)。这有助于通过减少稳定版本的 Pod 数量来管理成本。

配置中,我们添加了 maxTrafficPercentage: 50 等字段来限制发送到新版本的最大流量比例。
整合 HPA 与 Argo Rollouts
假设你不想使用 Anastasiia 提到的那些选项,而由于某些原因想使用 HPA。第一个问题是:HPA 能与 Argo Rollouts 一起工作吗?
答案是肯定的。你可能已经将 HPA 用于普通的 Deployment。本质上,HPA 可以与任何实现了 scale 子资源的对象一起工作。Argo Rollouts 实现了这个端点,因此两者可以协同。
scale 端点有三个属性:当前副本数、期望副本数和状态。由于 Argo Rollouts 已实现此端点,我可以创建一个 HPA 配置并将其指向 Rollout(而不是 Deployment),它就能正常工作。
在我们的示例中,我们创建了一个 HPA 配置,设置最小 1 个 Pod,最大 10 个 Pod,并基于内存使用率进行扩缩。代码库中还包含一个示例应用,每次调用会多占用 1MB 内存,你可以将其与 HPA 一起应用,观察 HPA 的实际工作方式。
当两者一起使用时会发生什么?在蓝绿部署中启用 HPA 后:
- 在内存使用较低时(左图),HPA 决定只需要 3 个 Pod,并将相同数量应用于预览 Pod 和稳定 Pod。
- 在内存使用较高时(右图),HPA 决定需要更多 Pod,并同时控制预览 Pod 和稳定 Pod 的数量。
- 结论:在蓝绿部署中,HPA 同时影响所有 Pod。
在金丝雀部署中也是如此。在流量 50% 导向新 Pod 的中间阶段,Argo Rollouts 通常规定预览 Pod 数量是稳定 Pod 的一半。HPA 会根据负载决定具体的 Pod 数量(例如,低负载时需要 4 个预览 Pod 和 8 个稳定 Pod;高负载时需要 5 个预览 Pod 和 10 个稳定 Pod)。这是开箱即用的工作方式。
冲突解决:当 Argo Rollouts 遇到 HPA


我知道你在想什么:如果同时使用 HPA 和 Anastasiia 提到的选项,会发生冲突吗?
正如之前剧透的,Argo Rollouts 会胜出。它将接管控制权。
例如,在同时使用 HPA 并设置了 previewReplicaCount: 3 的场景中,Argo Rollouts 将接管控制,预览 Pod 数量将始终为 3,无论 HPA 如何指示。在这种场景下,HPA 只控制稳定 Pod,不控制其他。
在金丝雀部署中也是如此。如果我指定将 50% 的流量发送给 3 个 Pod,这将被强制执行,并覆盖 HPA 的指示。HPA 将只影响稳定 Pod,预览 Pod 完全由 Argo Rollouts 控制。
总结与资源
谢谢 Cosmin。让我们来总结一下。
Argo Rollouts 使你的部署变得简单且安全。正如我们之前所示,在跳转到使用 HPA 之前,了解其他可用选项和一些有助于控制 Rollout 的属性非常重要。评估成本节约、业务需求和部署的灵活性也至关重要。
我们展示的选项应该能让你在不使用 HPA 的情况下使用 Argo Rollouts,从而简化事务。并且,正如 Cosmin 所说,在发生冲突时,Argo Rollouts 的规则将始终覆盖 HPA。
我们鼓励你查看官方文档。我们稍后会分享一些链接。
首先,我们想分享这张幻灯片,它总结了今天讨论的所有用例。标为橙色的单元格是人们经常混淆的例子,值得仔细研究并试验,看看哪种最适合你的业务场景。你可以拍下这张幻灯片,或者使用幻灯片底部的二维码链接查看。
最后,我们提供了一些有用的链接:
如果你有任何问题,可以通过 Slack 联系我们。也请反馈你对今天演讲的看法,告诉我们你喜欢的内容或未来希望听到更多的话题。

本节课中,我们一起学习了 Argo Rollouts 与 HPA 的集成,了解了渐进式交付的成本优化方法,以及两者协同工作时的优先级规则。希望这些知识能帮助你构建更高效、更经济的云原生交付流程。

浙公网安备 33010602011771号