在 Volterra,SRE 团队的工作是运营一个基于 SaaS 的全球边缘平台。 我们必须解决管理处于各种状态(即在线、离线、管理员关闭等)的大量应用集群的各种挑战,我们通过利用 Kubernetes 生态系统和使用 GitOps 的声明式拉动模型的工具来实现这一目标。
在这篇博客中,我们将描述:
使用 GitOps 有效地管理和监控大量基础设施(物理或云主机)和 K8s 集群
我们将深入探讨大规模(3000 个边缘站点)的经验教训,我在最近于圣地亚哥举行的 Cloud Native Rejekts 演讲中也谈到了这一点。
上面的架构图(图 1)显示了我们的 RE 和 CE 之间的逻辑连接,其中每个 CE 都与最近的 RE 建立冗余(IPSec 或 SSL VPN)连接。
大约两年前,当我们开始设计我们的平台时,我们的产品团队要求我们解决以下挑战:
考虑到我们运营高度分布式系统的要求和挑战,我们决定制定几个原则,让 SRE 团队遵循这些原则,以减少下游问题:
作为边缘站点生命周期管理的一部分,我们必须解决如何配置主机操作系统、进行基本配置(例如用户管理、证书颁发机构、大页面等)、启动 K8s、部署工作负载以及管理正在进行的配置更改。
我们考虑但最终拒绝的选项之一是使用 KubeSpray+Ansible(用于管理操作系统和部署 K8s)和 Helm/Spinnaker(用于部署工作负载)。 我们拒绝这个的原因是,这将要求我们管理 2-3 个开源工具,然后进行重大修改以满足我们的要求,随着我们添加更多功能(如边缘集群的自动扩展、对安全 TPM 模块的支持、差异升级等),我们的要求会不断增长。
由于我们的目标是保持简单并尽量减少直接在操作系统中(Kubernetes 之外)运行的组件数量,因此我们决定编写一个名为 Volterra Platform Manager(VPM)的轻量级 Golang 守护程序。 这是操作系统中唯一的 systemd Docker 容器,它就像一把瑞士军刀,具有多种功能:
VPM 负责管理主机操作系统的生命周期,包括安装、升级、修补、配置等。 需要配置的方面有很多(例如大页面分配、/etc/hosts 等)
管理为 Kubernetes 清单提供生命周期。 我们决定不使用 Helm,而是使用 K8s client-go 库,我们将其集成到 VPM 中并使用了该库的几个功能:
乐观= 创造资源而不是等待状态。 它与kubernetes apply命令非常相似,您不知道实际的 pod 是否成功启动。
悲观= 等待 Kubernetes 资源的状态。 例如,部署会等待所有 pod 准备就绪。 这类似于新的kubectl wait命令。
除了与 K8s 清单相关的配置之外,我们还需要通过其 API 配置各种 Volterra 服务。 一个例子是 IPsec/SSL VPN 配置——VPM 从我们的全局控制平面接收配置并在各个节点中对其进行编程。
此功能允许我们远程将盒子重置为原始状态并重新执行整个安装和注册过程。 对于恢复需要控制台/物理访问的站点来说,这是一项非常关键的功能。
尽管 K8s 生命周期管理对于很多人来说似乎是一个很大的讨论话题,但对于我们的团队来说,它可能只占整体工作量的 40-50%。
在任何位置(云、本地或游牧边缘)对边缘站点进行零接触配置都是至关重要的功能,因为我们不能期望访问单个站点,也不希望配备那么多 Kubernetes 专家来安装和管理单个站点。 它只是无法扩展到数千。
下图(图 2)显示了 VPM 如何参与注册新站点的过程:
如您所见,整个过程是完全自动化的,用户不需要了解任何详细配置或执行任何手动步骤。 让整个设备进入在线状态并准备好为客户应用和请求提供服务大约需要 5 分钟。
升级是我们必须解决的最复杂的问题之一。 让我们定义一下边缘站点正在升级的内容:
有两种已知方法可用于向边缘站点提供更新:
我们的升级目标是最大限度地提高简单性和可靠性——类似于标准手机升级。 此外,升级策略还必须满足其他考虑因素——升级环境可能仅限于站点运营商,或者设备可能由于连接问题等原因处于离线或不可用状态。 这些要求可以通过拉动方法更轻松地满足,因此我们决定采用它来满足我们的需求。
此外,我们选择 GitOps,因为它可以更轻松地为我们的 SRE 团队提供管理 Kubernetes 集群、工作流和审计变更的标准操作模型。
为了解决数千个站点的扩展问题,我们提出了图 3 所示的 SRE 架构:
首先,我想强调一下,我们使用 Git 不仅仅是为了存储状态或清单。 原因是我们的平台不仅要处理 K8s 清单,还要处理正在进行的 API 配置、K8s 版本等。 在我们的案例中,K8s 清单约占整个声明性配置的 60%。 为此,我们必须在其基础上提出自己的 DSL 抽象,并将其存储在 git 中。 此外,由于 git 不提供 API 或任何参数合并功能,我们必须为 SRE 开发额外的 Golang 守护程序: 配置 API、执行器和 VP 控制器。
让我们了解一下使用我们的 SaaS 平台在客户端发布新软件版本的工作流程:
您可以在此处观看整个工作流程的演示:
在前面的部分中,我们描述了如何使用我们的工具来部署和管理边缘站点的生命周期。 为了验证我们的设计,我们决定构建一个拥有三千个客户边缘站点的大型环境(如图 4 所示)
我们使用 Terraform 在 AWS、Azure、Google 和我们自己的本地裸机云上配置了 3000 台虚拟机来模拟规模。 所有这些虚拟机都是独立的 CE(客户边缘站点),它们建立了到我们的区域边缘站点(又名 PoP)的冗余隧道。
下面的屏幕截图来自我们的 SRE 仪表板,显示了圆圈大小所代表位置的边缘数量。 在截屏时,我们有大约 2711 个健康的边缘站点和 356 个不健康的边缘站点。
作为扩展的一部分,我们确实发现了配置和操作方面的一些问题,需要我们对软件守护进程进行修改。 此外,我们在与云提供商时遇到了很多问题,导致需要开具多张支持单 — 例如,API 响应延迟、无法在单个区域获取超过 500 台虚拟机等。
当我们扩展系统时,分布式系统的可观察性带来了更大的挑战。
最初,对于指标,我们从 Prometheus 联合开始 - 全局控制中的中央 Prometheus 在区域边缘(RE)中联合 Promethei,它从其连接的 CE 中抓取其服务指标并联合指标。 顶层的 Prometheus 评估警报并作为进一步分析的指标源。 我们很快达到了这种方法的极限(大约 1000 个 CE),并试图将 CE 数量不断增长的影响降至最低。 我们开始为直方图和其他高基数指标生成预先计算的系列。 这为我们节省了一两天的时间,然后我们必须使用白名单来衡量指标。 最后,我们能够将每个 CE 站点的时间序列指标数量从大约 60,000 个减少到 2000 个。
最终,在继续扩展到 3000 个以上 CE 站点并在生产中运行多日之后,很明显这是不可扩展的,我们不得不重新考虑我们的监控基础设施。 我们决定放弃顶层 Prometheus(全局控制),并将每个 RE 中的 Prometheus 分成两个独立的实例。 一个负责抓取本地服务指标,另一个负责联合 CE 指标。 两者都会生成警报并将指标推送到 Cortex 中的中央存储。 Cortex 用于分析和可视化源,而不是核心监控警报流程的一部分。 我们测试了几种集中式指标解决方案,即 Thanos 和 M3db,发现 Cortex 最适合我们的需求。
下面的截图(图 7)显示了在 3000 个端点时抓取 prometheus-cef 的内存消耗情况。 有趣的是它消耗了 29.7GB 的 RAM,但考虑到系统规模,这个数字实际上并没有那么多。 可以通过将抓取操作拆分为多个或将远程写入 Cortex 直接移动到边缘本身来进一步优化。
下一个屏幕截图(图 8)显示了在这种规模下,Cortex 摄取器(最大 19GB RAM)和分发器需要多少内存和 CPU 资源。 Cortex 最大的优势是水平扩展,与必须垂直扩展的 Prometheus 相比,它使我们能够添加更多副本。
对于 CE 和 RE 中的日志记录基础设施,我们每个节点使用 Fluentbit 服务来收集服务和系统日志事件并将其转发到连接的 RE 中的 Fluentd。 Fluentd 将数据转发到 RE 中的 ElasticSearch。 Elastalert 评估来自 ElasticSearch 的数据,并设置规则来创建 Alertmanager 警报。 我们正在使用从 Elastalert 到 Alertmananger 的自定义集成来生成与 Prometheus 生成的相同标签的警报。
我们的监测历程中的关键点:
- 最初,每个 CE 大约有 50,000 个时间序列,平均有 15 个标签
- 我们将其优化到平均每 CE 2000 个
指标名称的简单白名单和标签名称的黑名单
- 集中式 Prometheus 抓取了所有 RE 和 CE 的 Prometheus
- 公元 1000 年,管理指标数量已变得难以为继
- 目前,我们在每个 RE 上都有 Prometheus(与连接的 CE 的 Promethei 联合),并将 RW 连接到 Cortex
- 分散式日志架构
- Fluentbit 作为每个节点上的收集器,将日志转发到 RE 中的 Fluentd(聚合器)
- 每个 RE 中都部署了 ElasticSearch,使用远程集群搜索从单个 Kibana 实例查询日志
我希望本博客能让您深入了解管理全球部署的数千个边缘站点和集群需要考虑的所有事项。 尽管我们已经能够满足并验证大多数初始设计要求,但我们仍有许多改进空间……