存储和依赖的最佳实践#
本文档包含在 Kubernetes 上部署 Ray 时,有关设置存储和处理应用程序依赖项的建议。
当您在 Kubernetes 上设置 Ray 时,KubeRay 文档 概述了如何配置运算符以执行和管理 Ray 集群的生命周期。然而,作为管理员,您可能仍然对实际的用户工作流程有疑问。例如:
如何将代码分发到 Ray 集群或在其中运行?
应为工件设置哪种类型的存储系统?
如何处理应用程序的包依赖项?
这些问题的答案因开发和生产环境而异。下表总结了每种情况下的推荐设置:
交互式开发 |
生产 |
|
|---|---|---|
集群配置 |
KubeRay YAML |
KubeRay YAML |
代码 |
在主节点上运行驱动程序或 Jupyter notebook |
将代码烘焙到 Docker 镜像中 |
工件存储 |
设置 EFS |
设置 EFS |
包依赖项 |
安装到 NFS |
烘焙到 Docker 镜像中 |
表 1:开发和生产环境推荐设置的对比表。
交互式开发#
为了提供数据科学家和 ML 从业者的交互式开发环境,我们建议以一种减少开发人员上下文切换并缩短迭代时间的方式来设置代码、存储和依赖项。
存储#
根据您的用例,在开发过程中使用以下两种标准解决方案之一来存储工件和日志:
符合 POSIX 标准的网络文件存储,如网络文件系统 (NFS) 和弹性文件服务 (EFS):当您希望不同节点能够低延迟地访问工件或依赖项时,此方法很有用。例如,在不同的 Ray 任务上训练的不同模型的实验日志。
云存储,如 AWS 简单存储服务 (S3) 或 GCP Google 存储 (GS):当您需要高吞吐量访问大型工件或数据集时,此方法很有用。
Ray 的 AI 库,如 Ray Data、Ray Train 和 Ray Tune,都具备直接读写云存储和本地或网络存储的功能。
驱动程序脚本#
在集群的主节点上运行主脚本或驱动程序脚本。Ray Core 和库程序通常假定驱动程序位于主节点上,并利用本地存储。例如,Ray Tune 默认在主节点上生成日志文件。
典型的用户流程可能如下所示:
在主节点上启动 Jupyter 服务器
SSH 到主节点并在那里运行驱动程序脚本或应用程序
使用 Ray 作业提交客户端将代码从本地计算机提交到集群
依赖项#
对于本地依赖项(例如,如果您在单体仓库中工作)或外部依赖项(例如 pip 包),请使用以下选项之一:
将代码和已安装的包放在 NFS 上。这样做的好处是,您可以快速地与代码库的其余部分和依赖项进行交互,而无需每次都将其分发到集群。
将 运行时环境 与 Ray 作业提交客户端 一起使用,它可以从 S3 下载代码或将代码从您的本地工作目录分发到远程集群。
将远程和本地依赖项烘焙到已发布的 Docker 镜像中,供所有节点使用。请参阅 自定义 Docker 镜像。此方法是将应用程序部署到 Kubernetes 的最常用方法,但也是摩擦最大的选项。
生产#
生产环境的建议与标准的 Kubernetes 最佳实践一致。请参阅下图中的配置。
存储#
存储系统的选择在开发和生产环境中保持不变。
代码和依赖项#
将您的代码、远程和本地依赖项烘焙到已发布的 Docker 镜像中,供集群中的所有节点使用。此方法是将应用程序部署到 Kubernetes 的最常用方法。请参阅 自定义 Docker 镜像。
使用云存储和 运行时环境 是不太推荐的方法,因为它可能不如容器路径可重现,但仍然可行。在这种情况下,除了指定运行应用程序所需的 pip 包外,还可以使用运行时环境选项从云存储下载包含代码和其他私有模块的 zip 文件。