本文已超过一年。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否仍然正确。
Kubernetes 遇见高性能计算
任何使用过 Docker 的人都能体会到容器在效率方面带来的巨大提升。虽然 Kubernetes 在容器编排方面表现出色,但高性能计算 (HPC) 应用在 Kubernetes 上部署可能很棘手。
在本文中,我将讨论在 Kubernetes 上运行 HPC 工作负载的一些挑战,解释目前组织如何应对这些挑战,并提出一种在共享 Kubernetes 集群上支持混合工作负载的方法。我们还将提供一份关于客户 IHME 的案例研究信息和链接,该案例展示了 Kubernetes 如何在保持 HPC 用户熟悉的扩展性和界面的同时,无缝地服务于他们的 HPC 工作负载。本案例研究
HPC 工作负载的独特挑战
在 Kubernetes 中,调度的基本单位是 Pod:一个或多个被调度到集群主机的 Docker 容器。Kubernetes 假定工作负载是容器。虽然 Kubernetes 中有运行至完成的 Cron Jobs 和 Jobs 的概念,但部署在 Kubernetes 上的应用通常是长期运行的服务,如 Web 服务器、负载均衡器或数据存储。尽管它们的 Pod 来了又去,高度动态,但它们与 HPC 应用模式有很大不同。
传统 HPC 应用通常表现出不同的特征
- 在金融或工程模拟中,一个作业可能由成千上万个短时运行的任务组成,需要低延迟、高吞吐量的调度,以便在可接受的时间内完成模拟。
- 计算流体动力学 (CFD) 问题可能使用消息传递库在数百甚至数千个节点上并行执行以同步状态。这需要专门的调度和作业管理功能来分配和启动此类作业,然后对其进行检查点、暂停/恢复或回填。
- 其他 HPC 工作负载可能需要专用资源,例如 GPU,或者需要访问受限的软件许可证。组织可能会针对哪些资源类型可以由谁使用来强制执行策略,以确保项目资源充足并按时完成。
HPC 工作负载调度器已演进到专门支持这些类型的工作负载。示例包括 Univa Grid Engine、IBM Spectrum LSF 和 Altair 的 PBS Professional。管理 HPC 工作负载的站点已开始依赖于阵列作业、可配置抢占、基于用户、组或项目的配额以及各种其他功能。
容器与 HPC 之间的界限正在模糊
HPC 用户与其他组织一样,相信容器具有价值。将逻辑打包到容器中,使其可移植、隔离于环境依赖,并易于与其他容器交换,这显然具有价值。然而,转向容器可能很困难。
HPC 工作负载通常在命令行级别集成。作业不是通过编写代码,而是通过命令行以二进制文件或作为包装器的简单 shell 脚本提交到队列。HPC 站点使用的工程、科学和分析应用有数百种,它们都采用这种方法,并与流行的工作负载调度器有成熟且经过认证的集成。
虽然将工作负载打包到 Docker 容器、将其发布到注册表以及提交工作负载的 YAML 描述对 Kubernetes 用户来说是第二天性,但这对于大多数 HPC 用户来说却是陌生的。在 R、MATLAB 或 Stata 中运行模型的分析师只想快速提交他们的模拟、监控其执行,并尽快获得结果。
现有方法
为了应对迁移到容器的挑战,运行容器和 HPC 工作负载的组织有几种选择
- 维护独立基础设施
对于在 HPC 上有沉没成本投入的站点,这可能是一个首选方法。与其中断现有环境,不如将新的容器化应用部署在独立的集群上,而让 HPC 环境保持不变。挑战在于这会导致集群孤立,增加基础设施和管理成本。
- 在现有 HPC 工作负载管理器下运行容器化工作负载
对于运行传统 HPC 工作负载的站点,另一种方法是使用现有的作业提交机制来启动作业,这些作业又会在一个或多个目标主机上实例化 Docker 容器。采用这种方法的站点可以在对环境影响最小的情况下引入容器化工作负载。领先的 HPC 工作负载管理器,如 Univa Grid Engine Container Edition 和 IBM Spectrum LSF 正在添加对 Docker 容器的原生支持。Shifter 和 Singularity 也是支持此类部署的重要开源工具。虽然这对于有简单需求并希望坚持使用其 HPC 调度器的站点来说是一个不错的解决方案,但他们将无法访问原生 Kubernetes 功能,这可能会限制在管理 Kubernetes 擅长的长期运行服务方面的灵活性。
- 使用 Kubernetes 中的原生作业调度功能
对现有 HPC 应用投入较少的站点可以使用 Kubernetes 中现有的调度设施来处理运行至完成的作业。虽然这是一个选项,但对于许多 HPC 用户来说可能不切实际。HPC 应用通常要么针对大规模吞吐量进行优化,要么针对大规模并行性进行优化。在这两种情况下,启动和拆除延迟都有显著影响。对于当今容器化微服务而言看似可以接受的延迟,将使得此类应用无法扩展到所需的水平。
所有这些解决方案都涉及权衡。第一种方案不允许资源共享(增加成本),而第二种和第三种方案要求客户选择单个调度器,限制了未来的灵活性。
Kubernetes 上的混合工作负载
一个更好的方法是在同一共享环境中原生支持 HPC 和容器工作负载。理想情况下,用户应该看到适合其工作负载或工作流类型的环境。
支持混合工作负载的一种方法是允许 Kubernetes 和 HPC 工作负载管理器在同一集群上共存,通过限制资源来避免冲突。虽然简单,但这意味著两个工作负载管理器都无法充分利用集群。
另一种方法是使用与 Kubernetes 调度器协作的对等调度器。Univa 的 Navops Command 是一种采用此第三种方法的解决方案,它增强了 Kubernetes 调度器的功能。Navops Command 提供自己的 Web 界面和 CLI,并允许在 Kubernetes 上启用额外的调度策略,而不会影响 Kubernetes 调度器和现有容器化应用的运行。Navops Command 通过 pod spec 中的 'schedulerName' 属性,作为工作负载可以选择使用的对等调度器(而不是 Kubernetes 自带调度器),接入 Kubernetes 架构,如下所示。
通过这种方法,Kubernetes 作为资源管理器,将资源提供给独立的 HPC 调度器。集群管理员可以使用可视化界面根据策略分配资源,或者简单地通过 Web UI 拖动滑块,将 Kubernetes 环境的不同比例资源分配给非容器 (HPC) 工作负载以及原生 Kubernetes 应用和服务。
从客户端角度来看,HPC 调度器作为部署在 Kubernetes pod 中的服务运行,其运行方式与在裸金属集群上完全相同。Navops Command 提供了额外的调度功能,包括资源预留、运行时配额、工作负载抢占等。这种环境在本地、云端或混合部署中同样适用。
在 IHME 部署混合工作负载
一个在混合工作负载方面取得成功的客户是健康指标与评估研究所 (IHME),它是华盛顿大学的一个独立健康研究中心。为了支持其全球知名的全球健康数据交换 (GHDx) 项目,IHME 运行了一个规模相当大的环境,包括 500 个节点和 20,000 个核心,在 Kubernetes 上运行混合的分析、HPC 和基于容器的应用。本案例研究描述了 IHME 使用 Navops Command 在共享 Kubernetes 集群上托管现有 HPC 工作负载的成功经验。
对于部署新集群、希望利用 Kubernetes 的丰富功能但又需要灵活运行非容器化工作负载的站点,这种方法值得考虑。它为站点提供了在 Kubernetes 和 HPC 工作负载之间共享基础设施的机会,而不会中断现有应用和业务流程。它还允许他们按照自己的进度将 HPC 工作负载迁移到使用 Docker 容器。