更新时间:2024-12-23 GMT+08:00
分享

Kubeflow部署

Kubeflow的诞生背景

基于Kubernetes构建一个端到端的AI计算平台是非常复杂和繁琐的过程,它需要处理很多个环节。如图1所示,除了熟知的模型训练环节之外还包括数据收集、预处理、资源管理、特性提取、数据验证、模型的管理、模型发布、监控等环节。对于一个AI算法工程师来讲,如果要做模型训练,就不得不搭建一套AI计算平台,这个过程耗时费力,而且需要很多的知识积累。

图1 模型训练环节

Kubeflow诞生于2017年,Kubeflow项目是基于容器和Kubernetes构建,旨在为数据科学家、机器学习工程师、系统运维人员提供面向机器学习业务的敏捷部署、开发、训练、发布和管理平台。它利用了云原生技术的优势,让用户更快速、方便地部署、使用和管理当前最流行的机器学习软件。

目前Kubeflow 1.0版本已经发布,包含开发、构建、训练、部署四个环节,可全面支持企业用户的机器学习、深度学习完整使用过程。

如下图所示:

通过Kubeflow 1.0,用户可以使用Jupyter开发模型,然后使用fairing(SDK)等工具构建容器,并创建Kubernetes资源训练其模型。模型训练完成后,用户还可以使用KFServing创建和部署用于推理的服务器。再结合pipeline(流水线)功能可实现端到端机器学习系统的自动化敏捷构建,实现AI领域的DevOps。

前提条件

  • 已在CCE创建一个集群clusterA,集群下有一个可用GPU节点,节点上的GPU卡数量大于等于2。

    由于安装Kubeflow需要从github下载文件,从gcr.io等下载镜像,建议在华为云国际站创建集群,否则容易碰到较多网络问题。

  • 节点上绑定了EIP,并配置了kubectl命令行工具,详情请参见通过kubectl连接集群

安装Kustomize

Kustomize是一个开源工具,用于管理Kubernetes应用程序的配置。它允许您将应用程序的配置从应用程序本身中分离出来,并根据需要进行修改。从Kubeflow 1.3开始,所有组件都应仅使用Kustomize进行部署。

  1. 安装Kustomize。由于Kubeflow与Kustomize的早期版本不兼容,仅支持Kustomize 5及更高版本,本文中使用5.1.0版本。

    curl -o install_kustomize.sh "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
    sh install_kustomize.sh 5.1.0 .
    安装过程可能需要等待3-5分钟,回显如下:
    v5.1.0
    kustomize installed to /root/kubeflow/./kustomize

  2. 将kustomize移到/bin目录,以便在全局使用kustomize命令。

    cp kustomize /bin/

安装Kubeflow

您可以参考以下步骤安装所有Kubeflow官方组件。成功安装所有内容后,您可以访问Kubeflow中央仪表板,详情请参见连接Kubeflow

  1. 安装Kubeflow 1.7.0版本。

    wget https://github.com/kubeflow/manifests/archive/refs/tags/v1.7.0.zip
    unzip v1.7.0.zip

  2. 使用Kustomize创建用于部署Kubeflow的YAML文件。

    cd ./manifests-1.7.0/
    kustomize build example -o example.yaml

  3. 配置Kubeflow所需存储资源。

    • katib-mysql
    • mysql-pv-claim
    • minio-pv-claim
    • authservice-pvc

    由于Kubeflow在创建时需要配置一些存储资源,官方示例中的存储配置无法在CCE中生效,导致上述PVC无法创建。因此需要在集群中提前创建同名的PVC,本文中均以云硬盘类型为例,您可以按需替换云存储类型。

    创建pvc.yaml文件,YAML示例如下。

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: katib-mysql
      namespace: kubeflow
      annotations:
        everest.io/disk-volume-type: SAS    # 云硬盘的类型
      labels:
        failure-domain.beta.kubernetes.io/region: <your_region>   # 替换为您待部署应用的节点所在的区域
        failure-domain.beta.kubernetes.io/zone: <your_zone>       # 替换为您待部署应用的节点所在的可用区
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi
      storageClassName: csi-disk
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mysql-pv-claim
      namespace: kubeflow
      annotations:
        everest.io/disk-volume-type: SAS    # 云硬盘的类型
      labels:
        failure-domain.beta.kubernetes.io/region: <your_region>   # 替换为您待部署应用的节点所在的区域
        failure-domain.beta.kubernetes.io/zone: <your_zone>       # 替换为您待部署应用的节点所在的可用区
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 20Gi
      storageClassName: csi-disk
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: minio-pvc
      namespace: kubeflow
      annotations:
        everest.io/disk-volume-type: SAS    # 云硬盘的类型
      labels:
        failure-domain.beta.kubernetes.io/region: <your_region>   # 替换为您待部署应用的节点所在的区域
        failure-domain.beta.kubernetes.io/zone: <your_zone>       # 替换为您待部署应用的节点所在的可用区
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 20Gi
      storageClassName: csi-disk
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: authservice-pvc
      namespace: istio-system
      annotations:
        everest.io/disk-volume-type: SAS    # 云硬盘的类型
      labels:
        failure-domain.beta.kubernetes.io/region: <your_region>   # 替换为您待部署应用的节点所在的区域
        failure-domain.beta.kubernetes.io/zone: <your_zone>       # 替换为您待部署应用的节点所在的可用区
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi
      storageClassName: csi-disk

    创建PVC。

    kubectl apply -f pvc.yaml 

  4. 创建Kubeflow相关资源。

    kubectl apply -f example.yaml 

    由于网络原因,官方镜像可能无法拉取,导致工作负载出现ImagePullBackOff或FailedPullImage错误,请您自行添加合适的镜像代理。

  5. 查看所有命名空间下的Pod是否都处于运行状态。

    kubectl get pod -A

    如果创建资源时出现非预期问题,请参见常见问题进行处理。

常见问题

  • 遇到一些CRD资源不存在的场景,报错如下:
    error: resource mapping not found for name: "<RESOURCE_NAME>" namespace: "<SOME_NAMESPACE>" from "STDIN": no matches for kind "<CRD_NAME>" in version "<CRD_FULL_NAME>"
    ensure CRDs are installed first

    解决方案

    这是因为kustomization创建CRD和CR速度较快,可能会出现CRD尚未创建就创建CR的情况。如果您遇到此错误,建议您重新创建资源。

  • 工作负载创建时,遇到节点Pod过多的错误,报错如下:
    0/x nodes are available: x Too many pods.

    解决方案

    该错误说明节点上调度的Pod超过节点最大实例数,建议扩容节点数。

  • training-operator负载不能正常运行,日志中报的错误如下:
    Waited for 1.039518449s due to client-side throttling, not priority and fairness, request: GET:https://10.247.0.1:443/apis/xxx/xx?timeout=32s

    解决方案

    需要排除集群中不可用的APIService,执行以下命令查看集群中的APIService状态:

    kubectl get apiservice

    如果没有FALSE状态的APIService,等一到两分钟training-operator负载会正常运行。

相关文档