cube开源一站式云原生机器学习平台-架构(一)

全栈工程师开发手册 (作者:栾鹏)
一站式云原生机器学习平台


前言:cube是开源的云原生机器学习平台,目前包含特征平台,支持在/离线特征;数据源管理,支持结构数据和媒体标注数据管理;在线开发,在线的vscode/jupyter代码开发;在线镜像调试,支持免dockerfile,增量构建;任务流编排,在线拖拉拽;开放的模板框架,支持tf/pytorch/spark/ray/horovod/kaldi等分布式训练任务;task的单节点debug,分布式任务的批量优先级调度,聚合日志;任务运行资源监控,报警;定时调度,支持补录,忽略,重试,依赖,并发限制,定时任务算力的智能修正;nni,katib,ray的超参搜索;多集群多资源组,算力统筹,联邦调度;tf/pytorch/onnx模型的推理服务,serverless流量管控,tensorrt gpu推理加速,依据gpu利用率/qps等指标的 hpa能力,虚拟化gpu,虚拟显存等服务化能力。 目前开源到github:https://github.com/tencentmusic/cube-studio

介绍

传统机器学习方法过程
cube开源一站式云原生机器学习平台-架构(一)_第1张图片

TME机器学习平台基于kubeflow做开源改造和产品化,先来看看技术层面kubeflow对机器学习的各个技术环节的附能

cube开源一站式云原生机器学习平台-架构(一)_第2张图片

先简单介绍一下各组件的功能。下面以大项目背景为例简介的,可以在下面的部署中了解更细致的组件内容。

  • jupyter:jupyter 创建和管理多用户交互式Jupyter notebooks。
  • istio:提供微服务的管理,服务网格,网关,里面包含更多的内容
  • knative:serverless的框架,谷歌开源
  • kfserving:模型的在线部署,支持版本控制及无需停止线上服务,切换模型等功能
  • seldon:Seldon提供在Kubernetes上对机器学习模型的部署
  • pipeline: Kubeflow 社区新近开源的端到端的 ML/DL 工作流系统。
  • katib:Katib是一个超参数训练系统。
  • xx-operator:支持tf分布式训练系统。例如:spark-operator,tfjob-operator,pytorch-operator
  • tensorboard:tf训练效果跟踪
  • profiles:多用户
  • centraldashbaord:kubeflow官方的统一ui

架构分层

cube机器学习平台的目前架构

cube开源一站式云原生机器学习平台-架构(一)_第3张图片

机器配置

机器环境:

机器的配置没有强制要求,只要安装上docker即可,但是在k8s部署后,kubelet启动时会依据机器的dns和host配置将解析带入k8s,所以需要在启动前初始化好集群业务需要用到的dns/host配置。另外大量功能依赖分布式存储,我们需要在开机时配置自动挂载。可以手动添加个开机自启动脚本,这样就不怕重启机器带来的机器差异问题。

分布式存储:

Ceph: ceph目前测试写入50M-60M/s,读取100M,多用户读写相互干扰

Cfs:cfs/nfs速度均在100M,稍强于ceph,不过同样存在多用户相互干扰的情况,

Cos:cos无法直接以路径请示挂载到自建k8s中,需要wget一步,则与先从ceph拉取到容器中无异。

目前,我们部署在idc环境自建的k8s集群中,目前选择ceph。

docker环境

建议部署docker 19.03以上的版本,部署docker,我们要修改docker的配置,主要包括docker的数据挂载目录(因为默认安装目录在/var/lib/docker/一般磁盘比较小,公司的外挂盘一般在/data/home下面)和私有仓库(公司的docker.oa.com:8080需要添加私有屏蔽,csighub.tencentyun.com 需要 添加host 9.149.109.34)。

echo "9.149.109.34 csighub.tencentyun.com" >> /etc/hosts
cat /usr/lib/systemd/system/docker.service
...
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --graph /data/home/docker
...

gpu环境

首先需要找运维同学安装机器gpu卡对应的驱动,然后需要让你的docker能识别并应用gpu驱动。

如果你的docker是19.03以后的版本,并且只在docker中使用而不在k8s中使用,可以只安装nvidia-container-runtime 或者 只安装nvidia-container-toolkit,然后重启docker,就可以在docker run时通过添加参数–gpus 来应用gpu卡了。

如果你的docker是19.03以前的版本,或者19.03以后的版本并需要在k8s中使用gpu,那需要安装nvidia docker2,因为k8s还没有支持docker的–gpu参数。安装nvidia docker2以后,修改docker 默认runtime。重启docker,这样就能在docker或者k8s中使用gpu了。

cat /etc/docker/daemon.json

{
    "insecure-registries":["docker.oa.com:8080","9.134.36.249:80"],
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

rancher/kubernetes

Kubeflow利用Kubernetes的优势:

  • 原生的资源隔离
  • 集群化自动化管理
  • 计算资源(CPU/GPU)自动调度
  • 对多种分布式存储的支持
  • 集成较为成熟的监控,告警( Prometheus+grafana , tracing+Jaeger+zipkin )

机器环境配置好以后,我们就可以来部署k8s机器了。下面是k8s的一个架构。

cube开源一站式云原生机器学习平台-架构(一)_第4张图片

需要特别注意的是,我们需要做一些专门的处理,

1、我们需要pod和service的网段,服务公司安全规范

2、修改node port范围,因为公司能开放的端口有限,所以做好把node port范围放大一些。

3、修改api-server的启动参数,因为我们会启动数字优先级调度,所以需要修改。如果无此需求可以不修改

4、controller的集群网段和service网段需要错开,所以有可能我们需要自己做网段分割,需要服务公司的ip安全策略

5、kubelet 的 cluster_dns_server 的地址要写死,而且要符合上面的网段范围。

6、修改kubelet的自动回收策略,根据自己的机器的磁盘容器来修改,这样就 不会随意进行镜像回收。因为我们在内网部署,可能有些镜像是无法自动拉取的。所以有时需要减少没必要的镜像清理,进而减少手动拉取镜像并tag的操作。

7、修改kubelet的主机目录绑定,因为rancher是容器化部署,在k8s中使用挂载子目录的时候,实际是挂载到kubelet所在环境下,如果这个目录没有通过kubelet挂载到主机上,那么主机pv的子目录就没办法使用了。

我们需要修改的api-server、controller、kubelet的启动参数如下

kube-api:
    service_node_port_range: 10-32767
    service_cluster_ip_range: 172.16.0.0/17
    extra_args:     
      enable-admission-plugins: "NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,NodeRestriction,TaintNodesByCondition,PersistentVolumeClaimResize"
kube-controller:
    cluster_cidr: 172.16.128.0/17
    service_cluster_ip_range: 172.16.0.0/17
kubelet:
    cluster_dns_server: 172.16.0.10
    extra_args:
      image-gc-high-threshold: 90
      image-gc-low-threshold: 85
      extra_binds:
      - '/data/home:/data/home'
      - '/data/k8s:/data/k8s'
      - '/mnt/ceph_fuse:/mnt/ceph_fuse'

CRD

除了需要了解k8s官方资源,例如pod,service,sa,rbac,sts,deployment外,另外我们需要特别了解k8s的自定义资源CustomResourceDefinition。简称CRD。这个在机器学习平台中使用非常频繁,下面列举用到的常用的部分crd。

Kubeflow自定义资源类型 是否命名空间内 kind 说明
experiments kubeflow.org TRUE Experiment pipline中的实验
notebooks kubeflow.org TRUE Notebook jupyterhub项目组
poddefaults kubeflow.org TRUE PodDefault
profiles kubeflow.org FALSE Profile 多用户
pytorchjobs kubeflow.org TRUE PyTorchJob pytorch分布式训练
scheduledworkflows kubeflow.org TRUE ScheduledWorkflow pipline中的定时调度
suggestions kubeflow.org TRUE Suggestion katib的建议器
tfjobs kubeflow.org TRUE TFJob tf分布式训练
trials kubeflow.org TRUE Trial katib每个参数的运行
viewers kubeflow.org TRUE Viewer Viewer

Argo自定义资源类型: 是否命名空间内 kind 说明
clusterworkflowtemplates argoproj.io FALSE ClusterWorkflowTemplate argo的定时调度模板
cronworkflows argoproj.io TRUE CronWorkflow argo的定时调度
workflows argoproj.io TRUE Workflow argo的workflow
workflowtemplates argoproj.io TRUE WorkflowTemplate argo的模板

knative自定义资源 是否命名空间内 kind 说明
podautoscalers autoscaling.internal.knative.dev TRUE PodAutoscaler 弹性伸缩
images caching.internal.knative.dev TRUE Image 指定时间戳创建时间的指定镜像
ingresses networking.internal.knative.dev TRUE Ingress k8s ingress网关
serverlessservices networking.internal.knative.dev TRUE ServerlessService server less的服务
configurations serving.knative.dev TRUE Configuration 版本和流量代理配置
revisions serving.knative.dev TRUE Revision 业务版本管理
routes serving.knative.dev TRUE Route 业务流量路由
services serving.knative.dev TRUE Service 业务对外服务

此外还有istio、knative、prometheus项目组的各种自定义资源。

部署升级

kubeflow机器学习平台组部署方案已经同步到https://github.com/tencentmusic/cube-studio。

git上部署方案总体是基于kubeflow1.2版本的。在idc部署kubeflow,以及周边项目,可能会遇到下面的这些问题。

离线镜像

在idc网络我们可以使用csighub的仓库,但是前提是镜像名要包含csighub的服务器地址。部分镜像不知道在哪里去改配置,所以我们整理了一个脚本镜像清单和拉取tag脚本pull_image.sh。包含了rancher的组件,kubeflow的组件,rfk的组件,prometheus的组件,链路跟踪的组件。因为这些都是开源项目,往往不太方便去修改镜像名。在初始化机器时,都会被执行这样的脚本,满足开源项目的基本镜像环境。

对于我们自定义的镜像,都可以使用csig的仓库,配置上仓库地址和拉取策略就可以。

离线镜像的拉取策略

在项目中部分离线镜像的拉取策略是Always,但是镜像本身我们是通过上面的方式离线拉取的,在线拉取是无法访问远程仓库的,所以git项目中,已经将这部分修改为IfNotPresent。对于自定义的可以拉取的镜像,自己随意配置。

镜像签名

我们知道镜像名由名称和tag构成,但是可以重复的推送同一个tag的镜像,这样仓库中的镜像就会被覆盖。但是每次推送到 镜像都会有一个唯一的sha256的编码。docker本身提供通过指定镜像的指定sha256来进行拉取,这样push覆盖也不会拉取覆盖,但是这总方式必须要Always拉取。git中将这部分镜像tag成新的镜像版本,并且修改拉取处的镜像名,使用新tag版本。然后再用上面的方法使用本地已存在的镜像。

私有仓库拉取权限

部分组件中需要具有拉取镜像的功能,csighub的访问需要域名解析。也已经在需要的部署中添加了对应的host配置。

全局部署

kubeflow官方开源的部署方案是使用kustomize来完成。并且封装了组件kfctl,来实现一键部署。

包含的组件比较多。
cube开源一站式云原生机器学习平台-架构(一)_第5张图片

kubeflow开源框架的架构如下图所示

cube开源一站式云原生机器学习平台-架构(一)_第6张图片

各组件的功能已经在上面做了介绍,全部组件可以参考:https://www.kubeflow.org/docs/guides/components/components/

但是在kubeflow 1.2的版本中集成的各个组件可能并不是最新的。部分组件没有相互依赖关系,可以独立升级。

局部升级pipeline

在上面的全局部署中屏蔽了pipeline的部署,因为kubeflow部署方案中携带的pipeline版本太低。pipeline独立部署升级也已经同步到git的“升级pipeline”文件夹中。

局部升级katib

同样kubeflow全部部署中的katib版本也较低,在全局部署中已经屏蔽了katib的部署,可以单独部署和升级katib。已经同步到git的“升级katib”文件夹中

部署xgb-operator

在官方的kubeflow部署方案中并没有集成xgbjob的部署,在git中“升级xgboost-operator”文件夹中包含了xgb分布式job的支持。

命名空间隔离

官方开源的各个项目中,kubeflow组件的命名空间都在kubeflow,组件创建的业务容器也在kubeflow命名空间,非常不方便管理。git中已经对这些进行了拆分,kubeflow的控制容器保留在kubeflow命名空间,业务的pipeline和训练容器保留在pipeline命名空间,业务的超参搜索容器在katib命名空间,业务的notebook容器在jupyter命名空间,相关的配置文件,需要新增的部署脚本也都已经添加到git中

监控组件部署

kubeflow下的istio本身支持对接多种监控系统,并没有固定使用哪一种,我们这里提供下我们使用的监控系统。

指标监控,使用prometheus框架。部署开源到github.com/tencentmusic/cube-studio

日志监控,使用EFK框架。部署开源到github.com/tencentmusic/cube-studio

链路监控,使用zipkin框架。部署开源到github.com/tencentmusic/cube-studio

你可能感兴趣的:(云原生/微服务架构/运维,系列课程,python,机器学习,后端,爬虫,系列课程,云原生,机器学习,一站式,架构,开源)