在Kubernetes上运行#
Mars 可以在由 Kubernetes 管理的集群中运行。您可以使用 mars.deploy.kubernetes 来设置一个 Mars 集群。
基本步骤#
Mars 默认使用镜像库 marsproject/mars。自 v0.3.0 起,每个发布的 Mars 版本都有其镜像。例如,版本 0.3.0 的镜像是 marsproject/mars:v0.3.0。如果您需要从源代码构建镜像,可以运行以下命令:
bin/kube-image-tool.sh build
将构建一个带有当前版本标签的Mars Docker镜像。
然后你需要通过运行来确保你有正确的Kubernetes客户端配置
kubectl get nodes
如果它报告错误,请查阅kubernetes文档或咨询您的集群维护者以获取更多信息。
由于Mars使用Python在Kubernetes上操作,您还需要在本地安装Kubernetes的Python客户端。可以使用pip或conda进行安装:
# install with pip
pip install kubernetes
# install with conda
conda install -c conda-forge python-kubernetes
经过所有这些步骤,我们可以使用kubernetes创建一个有一个主管和一个工作者的Mars集群,并在其上运行一些任务:
from kubernetes import config
from mars.deploy.kubernetes import new_cluster
import mars.tensor as mt
cluster = new_cluster(config.new_client_from_config())
# new cluster will start a session and set it as default one
# execute will then run in the local cluster
a = mt.random.rand(10, 10)
a.dot(a.T).execute()
# after all jobs executed, you can turn off the cluster
cluster.stop()
当你想在其他地方使用这个集群时,你可以从集群对象中获取 namespace 和 endpoint,并创建另一个 KubernetesClusterClient:
# obtain information from current cluster
namespace, endpoint = cluster.namespace, cluster.endpoint
# create a new cluster client
from kubernetes import config
from mars.deploy.kubernetes import KubernetesClusterClient
cluster = KubernetesClusterClient(
config.new_client_from_config(), namespace, endpoint)
自定义集群#
new_cluster 函数提供了多个关键字参数供用户定义集群。您可以使用参数 image 来指定所有 Mars pod 的镜像,或者使用参数 timeout 来指定集群创建的超时时间。 还提供了用于扩展集群的参数。
监督者的参数:
参数 |
描述 |
|---|---|
supervisor_num |
集群中的主管数量,默认为1 |
supervisor_cpu |
每个监督者的CPU数量 |
supervisor_mem |
集群中管理者的内存大小,单位为字节或像 |
supervisor_extra_env |
在监督者中设置的环境变量映射 |
工人的参数:
参数 |
描述 |
|---|---|
worker_num |
集群中的工作节点数量,默认为1 |
worker_cpu |
每个工作节点所需的CPU数量。 |
worker_mem |
集群中工作节点的内存大小,以字节或大小单位表示,如 |
worker_spill_paths |
主机上工作节点的溢出路径列表 |
worker_cache_mem |
每个工作进程共享内存的大小或比例。有关Mars工作进程内存管理的详细信息,请参阅内存调优部分。 |
min_worker_num |
返回的 |
worker_extra_env |
要在工作线程中设置的环境变量字典。 |
例如,如果您想创建一个Mars集群,包含1个监督节点和100个工作节点,每个工作节点有4个核心和16GB内存,并在95个工作节点准备好时停止等待,您可以使用以下代码:
from kubernetes import config
from mars.deploy.kubernetes import new_cluster
api_client = config.new_client_from_config()
cluster = new_cluster(api_client, supervisor_num=1, worker_num=100, worker_cpu=4,
worker_mem='16g', min_worker_num=95)
实施细节#
当 new_cluster 被调用时,它将为所有对象创建一个独立的 namespace
,包括角色、角色绑定、Pods 和服务。当用户销毁服务时,整个命名空间将被销毁。
主管和工人是通过 deployments 创建的。服务通过直接访问 Kubernetes API 来发现主管,使用默认的 service account。工人读取 pod 的地址和它们的就绪状态,以决定是否启动。与此同时,客户端读取所有 pod 的状态,并检查是否所有主管和至少 min_worker_num 名工人都已就绪。
Mars服务的准备情况由readiness probes决定,其结果可以通过Pod状态获得。对于主管和工作者,当服务启动时,服务中将开放一个额外的端口,Pod可以检测到它。
由于默认服务账户没有权限读取Kubernetes API中的pods,我们使用RBAC API创建具有读取和监视pods能力的roles,然后在创建副本控制器之前将它们绑定到命名空间内的默认服务账户。这使得Mars容器能够检测其他容器的状态。
Mars使用Kubernetes服务来暴露其服务。目前仅支持NodePort模式,Mars查找
监控者的Web端点作为其端点。LoadBalancer模式尚不支持。