Kubeflow:一个交互式开发解决方案#

致谢:本宣言大量参考了Google Cloud的工程博客“在Google Kubernetes Engine上使用Kubeflow和Ray构建机器学习平台”

The Kubeflow 项目致力于使机器学习 (ML) 工作流在 Kubernetes 上的部署变得简单、便携和可扩展。

要求#

  • 依赖项

    • kustomize: v3.2.0 (Kubeflow 清单对 kustomize 版本敏感。)

    • Kubernetes: v1.23

  • 计算资源:

    • 16GB 内存

    • 8 个 CPU

示例:使用 Kubeflow 提供一个交互式开发环境#

图像

步骤 1:使用 Kind 创建一个 Kubernetes 集群。#

# Kubeflow is sensitive to Kubernetes version and Kustomize version.
kind create cluster --image=kindest/node:v1.26.0
kustomize version --short
# 3.2.0

步骤 2:安装 Kubeflow v1.6-branch#

  • 此示例使用 v1.6-branch 安装 Kubeflow。

  • 使用 一条命令 安装所有 Kubeflow 官方组件和所有常见服务。

    • 如果你不想安装所有组件,你可以注释掉 KNativeKatibTensorboards ControllerTensorboard Web AppTraining OperatorKServeexample/kustomization.yaml

步骤 3:安装 KubeRay 操作员#

  • 按照 此文档 通过 Helm 仓库安装最新稳定版本的 KubeRay 操作员。

步骤 4:安装 RayCluster#

# Create a RayCluster CR, and the KubeRay operator will reconcile a Ray cluster
# with 1 head Pod and 1 worker Pod.
helm install raycluster kuberay/ray-cluster --version 1.0.0 --set image.tag=2.2.0-py38-cpu

# Check RayCluster
kubectl get pod -l ray.io/cluster=raycluster-kuberay
# NAME                                          READY   STATUS    RESTARTS   AGE
# raycluster-kuberay-head-bz77b                 1/1     Running   0          64s
# raycluster-kuberay-worker-workergroup-8gr5q   1/1     Running   0          63s
  • 此步骤使用 rayproject/ray:2.2.0-py38-cpu 作为其镜像。Ray 对服务器(RayCluster)和客户端(JupyterLab)之间的 Python 版本和 Ray 版本非常敏感。此镜像使用:

    • Python 3.8.13

    • Ray 2.2.0

步骤 5:转发 Istio 的 Ingress-Gateway 端口#

  • 按照 说明 转发 Istio 的 Ingress-Gateway 端口并登录到 Kubeflow 中央仪表盘。

步骤6:通过 Kubeflow 中央仪表盘创建 JupyterLab#

  • 点击左侧面板中的“Notebooks”图标。

  • 点击“新建笔记本”

  • 选择 kubeflownotebookswg/jupyter-scipy:v1.6.1 作为 OCI 镜像。

  • 点击“启动”

  • 点击“连接”以连接到 JupyterLab 实例。

步骤 7:在 JupyterLab 中使用 Ray 客户端连接到 RayCluster#

警告:Ray 客户端有一些已知的 限制 并且没有积极维护。我们建议使用 Ray 作业提交 代替。

  • 如步骤4所述,Ray对服务器(RayCluster)和客户端(JupyterLab)之间的Python版本和Ray版本非常敏感。在JupyterLab中打开一个终端:

    # Check Python version. The version's MAJOR and MINOR should match with RayCluster (i.e. Python 3.8)
    python --version
    # Python 3.8.10
    
    # Install Ray 2.2.0
    pip install -U ray[default]==2.2.0
    
  • 通过 Ray 客户端连接到 RayCluster。

    # Open a new .ipynb page.
    
    import ray
    # ray://${RAYCLUSTER_HEAD_SVC}.${NAMESPACE}.svc.cluster.local:${RAY_CLIENT_PORT}
    ray.init(address="ray://raycluster-kuberay-head-svc.default.svc.cluster.local:10001")
    print(ray.cluster_resources())
    # {'node:10.244.0.41': 1.0, 'memory': 3000000000.0, 'node:10.244.0.40': 1.0, 'object_store_memory': 805386239.0, 'CPU': 2.0}
    
    # Try Ray task
    @ray.remote
    def f(x):
        return x * x
    
    futures = [f.remote(i) for i in range(4)]
    print(ray.get(futures)) # [0, 1, 4, 9]
    
    # Try Ray actor
    @ray.remote
    class Counter(object):
        def __init__(self):
            self.n = 0
    
        def increment(self):
            self.n += 1
    
        def read(self):
            return self.n
    
    counters = [Counter.remote() for i in range(4)]
    [c.increment.remote() for c in counters]
    futures = [c.read.remote() for c in counters]
    print(ray.get(futures)) # [1, 1, 1, 1]