Kubeflow = Kubernetes Machine Learing Flow
1 Overview
Kubeflow 是在 K8S 集群上跑机器学习任务的工具集,提供了 Tensorflow, Pytorch 等等机器/深度学习的计算框架,同时构建容器工作流 Argo 的集成,称为 Pipeline。关于其部署,最新版本的本地部署有很多问题,Github 上的 issue 大多数都是与部署有关的,所以如果不是在 GCP 上部署,会可能碰到各种各样的问题。
之所以对 GCP 支持这么好,是因为 Kubeflow 是 Google 内部机器学习工作流的开源版本,但是投入的核心开发者不多,版本更新和问题修复只有几个人在做。
部署之前,请先了解几个关于 ksonnet 的概念。
- registry: ksonnet 的模板仓库,可以是离线也可以是线上,只要能访问即可
- env: registry 注册在 env 下,通过 env 切换部署模板的仓库
- pkg: registry 里放着的是模板,里面包含了 protoypes 和 library
- prototype: 本文统一叫组件,可以配置不同的 param
- library: 包含了 k8s 的 Api 信息,不同版本的 k8s 的 Api 不同
- param: 用于填充模板的参数
- componet: 填充了参数的模板,本文统一叫组件
2 Deploy
Kubeflow 的官方文档提供了各种平台的部署方案。
https://www.kubeflow.org/docs/started/
部署方面,Kubeflow 利用了 Ksonnet,他是一个方便管理 K8S yaml 的工具。
https://ksonnet.io/
因为光用 Kubeflow 提供的部署脚本,遇到问题,还是得用 ks
命令看看的,所以有必要熟悉一下(后面会结合例子稍微讲下)。
2.1 本地部署
首先需要搞清楚,利用脚本一键部署的组件有哪些,需要花点时间去了解各个组件,否则排错的时候,根本无从下手。
代码语言:javascript复制# ks component list
COMPONENT TYPE 我补充的信息,未必准确
========= ==== ========== ==== ====
ambassador jsonnet Kubeflow 的认证统一网关和路由
application jsonnet 组件太多了,这个是做集成的 CRD
argo jsonnet 容器任务调度
centraldashboard jsonnet Kubeflow 的入口 UI
jupyter jsonnet jupyter
jupyter-web-app jsonnet jupyter hub
katib jsonnet 用于深度学习调参的组件
metacontroller jsonnet 也是一个内部的 CRD
notebook-controller jsonnet hub 里可以增加多个 notebook,也是一个 CRD
notebooks jsonnet jupyter nootbook
openvino jsonnet
pipeline jsonnet pipeline 集成
profiles jsonnet 用户权限和认证方面的组件
pytorch-operator jsonnet 一个深度学习的框架
spartakus jsonnet
tensorboard jsonnet
tf-job-operator jsonnet tensorflow 任务的 CRD
这么多组件部署起来是非常麻烦的,官方给力一个脚本,但是光有脚本不够用的,出问题,还是得看看脚本内容,简单说一下结构。
必须确保版本下载正确,否则排错又是一推问题…
下载完就有三个文件夹。重点看看脚本文件夹。部署关键在两个脚本,kfctl.sh/util.sh。
因为脚本实在太长了,而且 gcp/aws/minkube 所有平台都混合一起的,重点还是要看关于 ks
的部分,因为部署的核心是用到的是 kssonet。
关于 ksonset,上图是非常经典的,模板是一个缺了一些部分的圆柱,比如 yaml 中的 image,meta.name 之类的参数,第二部分是这几个参数的抽象化,通过 kssonet 就把最终的圆柱补齐了,最后结合成一个完成的 yaml 文件,可以用 kubectl apply -f xxx.yaml
,或者用 kssonet 的命令 ks apply -c <组件>
。
通过 grep
把关键的 ks
相关的命令抓出来。
# 运行这个命令,找到 ks 相关的命令 cat util.sh| grep "ks"
# All deployments should call this function to create a common ksonnet app.
# Create the ksonnet app
# 初始化 ks 项目的目录,注意 ${KS_INIT_EXTRA_ARGS} 后面还会提到
eval ks init $(basename "${KUBEFLOW_KS_DIR}") --skip-default-registries ${KS_INIT_EXTRA_ARGS}
# 也是非常重要的,先删除默认的环境,这里 default 代理了 ks 的 registry
ks env rm default
# 注册 registry,后面的部分会跟前面几条一起描述
ks registry add kubeflow "${KUBEFLOW_REPO}/kubeflow"
# 从这里开始是安装各种 ks 组件模板,还没多大用处,必须 generate
ks pkg install kubeflow/argo
ks pkg install kubeflow/pipeline
ks pkg install kubeflow/common
ks pkg install kubeflow/examples
ks pkg install kubeflow/jupyter
ks pkg install kubeflow/katib
ks pkg install kubeflow/mpi-job
ks pkg install kubeflow/pytorch-job
ks pkg install kubeflow/seldon
ks pkg install kubeflow/tf-serving
ks pkg install kubeflow/openvino
ks pkg install kubeflow/tensorboard
ks pkg install kubeflow/tf-training
ks pkg install kubeflow/metacontroller
ks pkg install kubeflow/profiles
ks pkg install kubeflow/application
ks pkg install kubeflow/modeldb
# generate 命令是用来把参数填充到模板里的,构成前面说的完成的 yaml
# 注意这些组件不能一一对应前面的模板的,因为有些组件里包含了几个模板的参数
ks generate pytorch-operator pytorch-operator
ks generate ambassador ambassador
ks generate openvino openvino
ks generate jupyter jupyter
ks generate notebook-controller notebook-controller
ks generate jupyter-web-app jupyter-web-app
ks generate centraldashboard centraldashboard
ks generate tf-job-operator tf-job-operator
ks generate tensorboard tensorboard
ks generate metacontroller metacontroller
ks generate profiles profiles
ks generate notebooks notebooks
ks generate argo argo
ks generate pipeline pipeline
ks generate katib katib
# cd ks_app
# ks component rm spartakus
# generate 命令还可以带参数的
ks generate spartakus spartakus --usageId=${usageId} --reportUsage=true
ks generate application application
真正通过 yaml 来创建 K8S 的资源的是在 kfctl.sh 脚本中,先通过同样的方法找出 ks
相关的命令。
# 运行命令 cat kfctl.sh| grep "ks"
# 这里指定 application 需要包括的组件
# 上面提到了 applicaiton 是一个 crd,因为 kubeflow
# 的组件太多了,所以要有个工具统一管理
ks param set application components '['$KUBEFLOW_COMPONENTS']'
#
#
#
# 下面是脚本里最后关键的步骤,请注意!!
#
#
#
# ks show 可以结合组件生成 yaml 文件
ks show default -c metacontroller -c application > default.yaml
# 然后可以看到,即使是这么复杂的 Kubeflow,依然是通过 kubectl apply 来构建
# 所以有需要的话,一定要看看 default.yaml 文件
# default 文件内容非常多,不同版本,应该在5000~9000行
kubectl apply --validate=false -f default.yaml
P.S.
ks
命令没有全部列出,如需要 debug 来需要仔细看看脚本
2.2 init 过程
通过脚本 init
。
./kfctl.sh init myapp
init
完之后,还要 check 版本的问题。
2.2 generate 过程
代码语言:javascript复制# 注意目录
cd myapp
../kfctl.sh generate all
generate
之后,也同样 Check 版本信息。
2.3 apply 过程
代码语言:javascript复制# 注意目录
../kfctl.sh apply all
2.4 部署成功
查看 pod 情况。
查看 svc 情况。
访问 UI。
代码语言:javascript复制kubectl port-forward svc/ambassador 8003:80 -n kubeflow
查看 Pipeline。
运行一个 Pipeline 的 DAG。
查看 tf-job-dashboard。
提交一个 tf-job。通过官方提供的组件 example,里面有几个例子。可以通过以下方法安装这几个组件。
代码语言:javascript复制# 注意需要目录在前面生成的 ks_app
ks generate tf-job-simple-v1beta2 tf-job-simple-v1beta2
ks apply default -c tf-job-simple-v1beta2
这样就提交了几个任务了,本质上也是通过 ks
生成 yaml,然后 ks apply
就相当于 kubectl apply
了。
2.5 删除
代码语言:javascript复制# 注意目录
../kfctl.sh delete all
3 必须要注意的问题
- 一定要确认下载/安装 Kubeflow 的过程中,Kubeflow 的版本问题,因为其版本前后有比较大的差别!
- 生成模板的时候,需要注意 K8S 的版本!可以在脚本中指定,见附录。
如果不打算部署整套 Kubeflow,可以只部署 Jupyter,tf-operator 等等。
4 部署失败的原因
- 如果需要完整部署,需要创建多个 K8S 资源,需要较多的资源,本地不一定能部署起来,GCP 建议需要 16 核
- 版本问题,包括 K8S 版本,ksonnet 版本,镜像版本等等
- 离线问题,原则上,只要部署好 K8S 脚本,image 都在本地,部署脚本已经获取,是不需要联网部署的
常见问题包括 Github 无法访问,需要下载 K8S 的 swagger.json 文件等等。
完整部署一套 Kubeflow 代价太大,一是官方文档整理的逻辑不够清晰,更新不及时,二是包含太多组件了,如果对某些组件不熟悉,出问题了是很不好排查的。部署的话,最好是通过各云厂商的来部署,相对而言,Kubeflow 对各厂商的部署脚本的问题,处理起来比本地用户会更积极一些。当然了,在 GCP 上,体验应该是最好的。
附录
代码语言:javascript复制# ks 需要读取到 .kube/config 文件
# init 需要确定 ks registry,离线安装需要 k8s 的 swagger.json
eval ks init $(basename "${KUBEFLOW_KS_DIR}") --skip-default-registries --api-spec=file:/tmp/swagger.json
#
# 可以指定 server,确定 k8s 的版本
ks env add default --server=https://shmix1.k8s.so.db --api-spec=file:/tmp/swagger.json
#
# 注意每次运行脚本的信息
ks env describe default
O='name: default
kubernetesversion: v1.14.3
path: default
destination:
server: https://kubernetes.docker.internal:6443
namespace: kubeflow
targets: []
libraries: {}'
#
#
# 完整部署脚本
#
#
export KUBEFLOW_VERSION=v0.5.0
curl https://raw.githubusercontent.com/kubeflow/kubeflow/${KUBEFLOW_VERSION}/scripts/download.sh | sh
cd scripts
./kfctl.sh init myapp
cd myapp
../kfctl.sh generate all
../kfctl.sh apply all