
# Kubeflow部署
#### Kubeflow的诞生背景
基于Kubernetes构建一个端到端的AI计算平台是非常复杂和繁琐的过程，它需要处理很多个环节。如[图1]所示，除了熟知的模型训练环节之外还包括数据收集、预处理、资源管理、特性提取、数据验证、模型的管理、模型发布、监控等环节。对于一个AI算法工程师来讲，如果要做模型训练，就不得不搭建一套AI计算平台，这个过程耗时费力，而且需要很多的知识积累。
图1模型训练环节   
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001695679897.png "点击放大")
Kubeflow诞生于2017年，Kubeflow项目是基于容器和Kubernetes构建，旨在为数据科学家、机器学习工程师、系统运维人员提供面向机器学习业务的敏捷部署、开发、训练、发布和管理平台。它利用了云原生技术的优势，让用户更快速、方便地部署、使用和管理当前最流行的机器学习软件。
目前Kubeflow 1.0版本已经发布，包含开发、构建、训练、部署四个环节，可全面支持企业用户的机器学习、深度学习完整使用过程。
如下图所示：
![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001647360212.png "点击放大")
通过Kubeflow 1.0，用户可以使用Jupyter开发模型，然后使用fairing（SDK）等工具构建容器，并创建Kubernetes资源训练其模型。模型训练完成后，用户还可以使用KFServing创建和部署用于推理的服务器。再结合pipeline（流水线）功能可实现端到端机器学习系统的自动化敏捷构建，实现AI领域的DevOps。
#### 前提条件
- 已在CCE创建一个集群clusterA，集群下有一个可用GPU节点，节点上的GPU卡数量大于等于2。
  ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
  由于安装Kubeflow需要从github下载文件，从gcr.io等下载镜像，建议在华为云国际站创建集群，否则容易碰到较多网络问题。
  
- 节点上绑定了EIP，并配置了kubectl命令行工具，详情请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)。
 
#### 安装Kustomize
[Kustomize](https://github.com/kubernetes-sigs/kustomize)是一个开源工具，用于管理Kubernetes应用程序的配置。它允许您将应用程序的配置从应用程序本身中分离出来，并根据需要进行修改。从Kubeflow 1.3开始，所有组件都应仅使用Kustomize进行部署。
1. 使用[官方脚本](https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh)安装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](https://github.com/kubeflow/manifests#connect-to-your-kubeflow-cluster)。
1. 安装[Kubeflow 1.7.0版本](https://github.com/kubeflow/manifests/archive/refs/tags/v1.7.0.zip)。
   
   ```
   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
   ```
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
   由于网络原因，官方镜像可能无法拉取，导致工作负载出现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负载会正常运行。
  
 
