ITPub博客

首页 > 人工智能 > 人工智能 > Amazon ECS 现可自动修复故障 GPU(图形处理器) 和实例。这对 SRE 为何重要。

Amazon ECS 现可自动修复故障 GPU(图形处理器) 和实例。这对 SRE 为何重要。

人工智能 作者:ITPUB社群 时间:1970-01-01 08:33:46 0 删除 编辑

在生产环境中运行应用程序意味着要在各种中断中保持“始终在线”的姿态。基础设施会故障;依赖项会变慢,网络会发生分区,这些并非罕见的例外,而是大规模运行时的常态。承受并从这些中断中恢复是一项核心要求,而非事后才考虑的事情。

在实践中,这一要求体现为你可能已经熟悉的一系列时刻。客户注意到服务中断,或者告警触发,而根本原因可能是多种多样:GPU 抛出硬件故障导致实例上的任务失败,可用区发生网络事件,或者你依赖的日志后端变慢并悄然拖累你的应用程序。这些都不罕见,也都不会等待一个方便的时间。重要的是接下来会发生什么,以及其中有多少需要你来处理。

“基础设施会故障;依赖项会变慢,网络会发生分区,这些并非罕见的例外,而是大规模运行时的常态。”

在 Amazon ECS 上,我们的目标是为你处理大部分此类问题。故障恢复是我们设计和构建 ECS 功能时的关键考量。这意味着你不需要为 ECS 自身能够处理的故障构建自己的检测循环和修复运行手册。对于更模糊的情况,即正确的响应取决于你的工作负载,我们暴露相同的控制能力,让你自行做出判断。

这建立在我们在《深入探讨 Amazon ECS 的韧性与可用性》中介绍的 ECS 韧性原则之上:跨可用区的静态稳定性、预扩容容量以及工作负载隔离。这里我们重点关注建立在这些原则之上的恢复机制,以及你对每一项机制所拥有的控制能力。

在 AWS 责任共担模型下,AWS 负责云本身的韧性,即你的工作负载所运行的基础设施,而你负责云中的韧性,即你的应用程序抵御故障并从故障中恢复的设计方式。我们在此描述的许多工作,是 ECS 从“云本身”一侧汲取经验和模式——我们依赖这些经验和模式来保持自身系统的健康——并将其应用到“云中”一侧,通常以合理的内置默认值形式提供,从而简化你系统的运维姿态。

ECS Managed Instances 就是一个例子:ECS 接管了你的任务所运行的实例基础设施的韧性责任。它会在不影响应用程序可用性的前提下应用操作系统、内核和 GPU 驱动补丁:它逐步分批推送更新,在此过程中监控故障,并在检测到问题时进行回滚。

AWS Fargate 遵循类似的模式:你同样不需要运维那里的实例,因此坏实例、糟糕的操作系统更新或驱动回归由我们负责检测和恢复,而不是你需要围绕其设计的故障模式。接下来,我们来看看 ECS 如何检测和恢复特定故障:不健康的实例、可用区事件、容器或任务故障,以及降级的依赖项。

当任务底层的实例出现问题时

一些最具破坏性的故障始于你的任务之下,即它们所运行的实例。当实例降级时,调度在其上的每个任务都面临风险,且它保持服务的时间越长,故障扩散得越广。因此,你需要尽快检测到受损实例并将其移出轮换,以控制影响范围。

例如,考虑在一个加速实例集群上运行的 GPU 推理工作负载。如果其中一个实例上的 GPU 开始抛出可纠正的 ECC 错误并升级为故障,那么该实例上的任务会变慢或失败。或者,如果实例因网络分区、热事件、Amazon EBS 卷降级等原因而受损,那么其上的任务会继续原地运行而背后没有编排支持,最终自身也会受损。自行处理此类损害意味着需要构建额外的自动化来检测受损实例、排空其工作负载并最终轮换它们,然后在大规模下可靠地维护和运维该自动化。ECS 现在为你自动完成这些工作。

“为了直接检测这些故障,ECS 集成了 NVIDIA 的数据中心 GPU 管理器(DCGM)……并监控指示真实硬件故障的错误类别。”

在托管实例上,GPU 健康监控和自动修复填补了一个容易被忽视的缺口。由于 GPU 是直通到实例的,其内部发生的大多数 GPU 故障对 Amazon EC2 实例状态检查不可见——这些检查能捕获普通硬件问题——因此这些故障只能以无法解释的任务失败或延迟的形式浮现。为了直接检测这些故障,ECS 在实例上与 NVIDIA 的数据中心 GPU 管理器(DCGM)集成,并监视那些表明真实硬件故障而非瞬态或非关键故障的错误类别。

ECS 还监控数据平面实例的更广泛健康状况。这包括 EC2 状态检查以及实例上的数据平面组件,例如 ECS 智能体和容器运行时。ECS 智能体管理实例上的任务,并保持它们与 ECS 控制平面连接。当智能体无法访问控制平面时,任务的本地状态可能会偏离控制平面中的期望状态,而这种偏离会以容易被忽视的方式影响这些任务。智能体无法再发布指标、日志或健康状态,因此实例变成了一个黑盒。而且 ECS 也无法再可靠地停止或替换其上的任务,因此对于一个服务来说,滞留在断开连接实例上的任务会占用其限制额度,并阻碍健康的替换任务。在 Fargate 以及托管实例上,ECS 会自动检测智能体连接的持续丢失,并将该实例视为受损;而自行恢复的短暂波动不会触发回收。

在这两种情况下,ECS 运行相同的持续监控与修复循环,如图 1 所示。

GPU 自动修复和智能体连接修复在支持它们的平台上默认开启,且不额外收费。你也可以自行跟踪实例健康状况:ECS 通过 DescribeContainerInstances API 暴露该信息,并向 Amazon EventBridge 发布 Instance Health Change 事件,适用于托管实例和 EC2 上的 ECS。当你使用自有容量在 EC2 上运行 ECS 时,该事件最为有用,你可以消费它来基于容器实例健康状况触发自己的 Auto Scaling 健康检查和实例替换工作流。

当某个可用区遭遇糟糕的一天

可用区在区域内提供故障隔离,但这种隔离只有在你的工作负载能够承受丢失一个可用区时才有价值。设想一个服务跨三个可用区运行,其中一个可用区受损。两件事往往会同时出错。你幸存的任务不再均匀分布,因此恢复会将负载堆积到错误的可用区。任务之间的流量也可能以扩大爆炸半径的方式跨越可用区边界。手动重新平衡任务并将流量引导回健康路径既缓慢又容易出错,而这恰恰是你最承受不起的时候。

ECS 在决定工作负载运行位置时会考虑可用区健康状况。当它检测到某个可用区出现问题的迹象时,例如任务或实例启动失败率升高,或其他 AWS 服务的健康事件,它会自动将新任务和实例的放置引导远离该可用区,直到其恢复,而不是向已经陷入困境的可用区增加工作。此外,当某个事件导致你的任务在各可用区之间分布不均时,可用区重新平衡会纠正它。

ECS 持续监控服务的任务在各可用区之间的分布情况,当分布变得不均匀时,它会在任务最少的可用区中启动任务,一旦这些任务健康并运行,就停止任务最多的可用区中的任务,直到分布再次均匀(图 2)。这对于符合条件的服务默认开启:即第一个放置策略为可用区分布的服务,或未设置放置策略的服务。

最后,如果你的服务使用 Service Connect,你可以启用区域感知路由,将每个调用路由到调用方自己可用区中的端点,这在正常运行时将流量保持在可用区内,并在可用区降级时减少跨可用区暴露。

对于 ECS 服务,ECS 默认将任务均匀分布在可用区之间,因此重新平衡可维持均匀分布。你可以通过预扩展来确保跨可用区有足够的容量余量以应对可用区中断:当任务分布在至少三个可用区时,丢失一个可用区会移除大约三分之一的容量而不是一半,因此请为幸存的可用区配置足够的容量来承载该负载。你可以参考 2023 年弹性和可用性深度探讨,了解这一点以及弹性 ECS 服务背后的其他设计原则。

容器崩溃不应让你失去整个任务

故障通常可以定位到原本健康任务中的单个容器。当这种情况发生时,你宁愿保持任务运行并就地修复,而不是将其拆除并重新调度。重新调度会丢弃大部分健康的工作,并将变动推给调度器和集群的其余部分,因此就地恢复是干扰更小的选择。

设想一个任务,它运行一个主应用容器以及几个边车容器,例如一个指标智能体和代理。如果某个边车容器崩溃,你不会希望整个任务丢失。借助容器重启策略,ECS 会就地重启失败的容器,而不会重新启动任务,因此任务在容器恢复期间持续提供服务,同时你避免了不必要的重新调度。

“重新调度会丢弃大部分健康的工作,并将波动推给调度器,因此就地恢复是干扰更小的选择。”

你可以选择哪些容器符合条件,并可以列出不应重试的退出码,这样因不可恢复原因而失败的容器会暴露出来,而不是陷入重启循环。这在容量已经承压时最为重要,例如在可用区事件期间:通过就地重启容器保持任务存活,可以避免放弃你之后不得不重建的容量。

在任务启动时也能看到同样的原则。在 Managed Instances 上,ECS 仍会尝试拉取每个镜像,以便获取标签的任何更新,但如果拉取失败,而该镜像已从先前的任务缓存到实例上,它会回退到缓存副本并照常启动任务,而不是因为临时的注册表或网络问题而让任务失败。在 ECS on EC2 上,你可以通过 ECS_IMAGE_PULL_BEHAVIOR 智能体设置选择类似行为。无论哪种方式,你无法控制的依赖项出现临时故障——注册表被限流或网络抖动——都不会让你损失一个本可以从实例上已有副本启动的任务。

更安全的默认值,为你而选

本文大部分内容是关于 ECS 从基础设施故障中恢复。当应用所依赖的某个东西发生故障时,应用自身的行为通常属于共享责任模型中你的那一侧:云中的韧性。但在少数情况下,我们多次看到某个默认值对客户不利,以至于 ECS 代表你更改了它,将更安全的选择移入平台,让你继承它,而不必自己去发现和配置。

日志记录是最明显的例子。ECS 最初只支持阻塞式日志投递:当日志后端缓慢、被限流或不可用时,对 stdout 和 stderr 的写入会阻塞,如果应用记录日志的速度快于投递速度,这种背压可能导致应用停滞或崩溃。日志目标的大规模故障可能会连带拖垮应用的可用性,即使日志记录并不在应用的关键路径上。我们后来添加了非阻塞投递来避免这一点,丢弃无法投递的日志而不是阻塞容器,但它仍然是可选项,大多数客户从未启用它。

因此 ECS 谨慎地更改了默认值。由于少数工作负载确实依赖阻塞模式,我们分阶段进行切换,而不是一夜之间完成:我们首先发布了账户设置,以便任何需要阻塞的人可以选择启用它,在更改之前提前通知,然后才更改默认值,这样需要保证投递的客户有时间保留它。

“实际上,工作负载现在在其日志依赖降级时故障开放:它继续提供服务并丢弃无法投递的日志,而不是故障关闭。”

非阻塞现在是默认的日志驱动模式,适用于现有和新服务,无需任何操作,因此日志故障默认不再使你的应用停滞。实际上,工作负载现在在其日志依赖降级时故障开放:它继续提供服务并丢弃无法投递的日志,而不是通过阻塞直到后端恢复来故障关闭。

这是一个真实的持久性与可用性之间的权衡,默认值现在偏向可用性,这对大多数工作负载来说是正确选择。出于计费、审计或监管原因必须保证投递的客户,仍然可以通过日志驱动账户设置或按任务定义选择阻塞模式。

这并非日志记录独有。默认将服务任务分散到多个可用区、在排空和部署期间先启动替换任务再停止现有任务,以及在滚动部署期间从失败任务已属的版本而不是可能仍在启动失败的新版本来替换失败任务,背后都是同样的推理。在更好的默认值能帮助大多数客户而又不剥夺控制权的地方,我们将其设为默认值,并保留你覆盖它的选项。

自行测试

ECS 与 AWS Fault Injection Service (FIS) 集成,让你可以测试应用程序在面对各种故障条件时的弹性。其 ECS 任务操作允许你对正在运行的任务执行受控的故障实验,从停止任务到注入资源和网络故障,这样你就可以在真实事件考验之前,了解你的工作负载和恢复设置是否经得起考验。

特别是对于网络故障,我们在 ECS 启动类型(包括 AWS Fargate)中启用了网络故障注入。你可以向任务中注入延迟、丢包或黑洞,并确认当依赖项变慢或不可达时,你的超时、重试和回退行为是否符合预期。在 ECS Fargate 上使用 FIS 项目的示例网络故障是一个很好的起点。

本文中每一种故障的处理方式都是相同的,无论是实例故障、可用区受损、容器崩溃还是依赖项降级:ECS 承担了检测和恢复这些无差别的繁重工作,而在正确响应取决于你的工作负载时,它把决定权留给你。你继承安全的默认值,同时保留覆盖的能力。

ECS 旨在让你更轻松地面向故障进行设计。通过处理恢复中常规的、机械性的部分,它释放你的精力去关注应用程序特有的弹性,而其与 FIS 的集成让你可以检验这种弹性。将本文中的默认值和控制项视为起点,根据你的工作负载实际需要进行调整,并告诉我们哪些默认值应该更智能。

关于这些机制背后的原则,请参阅 2023 年弹性和可用性深度解析。要告诉我们接下来构建什么,请参阅 GitHub 上的 AWS Containers Roadmap。


转载声明:本文为转载整理,原文版权归原作者及原站点所有。

原文来源:The New Stack

原创地址:https://thenewstack.io/amazon-ecs-auto-repair/

原文作者:Anirudh Aithal;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2022-11-21

  • 博文量
    1148
  • 访问量
    548606