Kubeflow部署
Kubeflow的诞生背景
基于Kubernetes构建一个端到端的AI计算平台是非常复杂和繁琐的过程,它需要处理很多个环节。如图1所示,除了熟知的模型训练环节之外还包括数据收集、预处理、资源管理、特性提取、数据验证、模型的管理、模型发布、监控等环节。对于一个AI算法工程师来讲,如果要做模型训练,就不得不搭建一套AI计算平台,这个过程耗时费力,而且需要很多的知识积累。
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进行部署。
- 安装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
- 将kustomize移到/bin目录,以便在全局使用kustomize命令。
cp kustomize /bin/
安装Kubeflow
您可以参考以下步骤安装所有Kubeflow官方组件。成功安装所有内容后,您可以访问Kubeflow中央仪表板,详情请参见连接Kubeflow。
- 安装Kubeflow 1.7.0版本。
wget https://github.com/kubeflow/manifests/archive/refs/tags/v1.7.0.zip unzip v1.7.0.zip
- 使用Kustomize创建用于部署Kubeflow的YAML文件。
cd ./manifests-1.7.0/ kustomize build example -o example.yaml
- 配置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
- 创建Kubeflow相关资源。
kubectl apply -f example.yaml
由于网络原因,官方镜像可能无法拉取,导致工作负载出现ImagePullBackOff或FailedPullImage错误,请您自行添加合适的镜像代理。
- 查看所有命名空间下的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负载会正常运行。