本文回顾总结近一段时间网易云音乐机器学习平台(GoblinLab)在容器化实践的一些尝试。截止今日,音乐机器学习平台(GoblinLab)在容器化方面的尝试,已开展了一段时间,并且已经有了阶段性的成果。

布景

曩昔音乐算法的模型训练使命,是在物理机上进行开发、调试以及守时调度。每个算法团队运用归于自己的独立物理机,这种现状会形成一些问题。比方物理机的散布零星,缺少一致的办理,首要依赖于doc文档的表格记载机器的运用与归属;各事务间机器资源的分配,有时需求机器在不同机房的搬家,耗时耗力。别的,因为存在多人共用、开发与调度使命共用等状况,会形成环境的彼此影响,以及资源的抢夺。针对当时的状况,总结问题如下:

  • 资源运用率低:部分机器资源运用率偏低;无法依据各个事务的不同阶段,在大局内快速、动态的完结扩缩容,以到达资源的合理装备,进步资源全体运用率;
  • 环境彼此影响:存在多人共用、测验与调度混用同一开发机,未做任何的阻隔,形成或许的环境、同享资源的彼此影响与抢夺;
  • 监控报警缺失:物理机形式,使命监控报警功用缺失,导致使命无法运维,或许功率低。

资源没有大局一致的合理分配,会呈现负载不均衡,资源不能最大化的运用。

Kubernetes的测验

在快速的扩缩容、环境阻隔、资源监控等方面,Kubernetes及其相关扩展,能够很好的处理问题。现将物理机会集起来,并构建成一个Kubernetes集群。经过剖析算法搭档以往的工作方法,机器学习渠道(GoblinLab)决议测验根据Kubernetes供给在线的开发调试容器环境以及使命的容器化调度两种计划,其别离针对使命开发和使命调度两种场景。

使命开发

为最大化的削减算法搭档由物理机迁移到容器化环境的学习本钱,GoblinLab体系中根本将Kubernetes的容器作为云主机运用。容器的镜像以各版别Tensoflow镜像为根底(底层是Ubuntu),集成了大数据开发环境(Hadoop、Hive、Spark等Client),安装了常用的软件。别的,为了方便运用,容器环境供给了Jupyter Lab、SSH登录、Code Server(VSCode)三种运用方法。

在GoblinLab中新建容器化开发环境比较简单,只需挑选镜像,填写所需的资源,以及需求挂载的外部存储即可(使命开发的环境下文简称开发实例)。

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第1张

新建环境装备后,点击发动实例,容器初始化时,会主动发动Jupyter lab、SSH以及CodeServer。

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第2张

Jupyter Lab:

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第3张

Code Server:

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第4张

SSH登录:

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第5张

算法能够挑选以上恣意一种方法进行使命的开发,或许调试。因为供给了Code Server(VSCode),所以能够获得更好的体会。

使命开发所用的容器化环境,在底层Kubernetes上是经过StatefulSet类型完结,对应资源编列文件如下(已精简细节):

  1. kind:StatefulSet
  2. apiVersion:apps/v1
  3. metadata:
  4. name:${name}
  5. namespace:"${namespace}"
  6. spec:
  7. replicas:1
  8. selector:
  9. matchLabels:
  10. statefulset:${name}
  11. system/app:${name}
  12. template:
  13. spec:
  14. <#if(gpu>0)>
  15. tolerations:
  16. -effect:NoSchedule
  17. key:nvidia.com/gpu
  18. value:"true"
  19. </#if>
  20. <#ifusePrivateRepository=="true">
  21. imagePullSecrets:
  22. -name:registrykey-myhub
  23. </#if>
  24. volumes:
  25. -name:localtime
  26. hostPath:
  27. path:/etc/localtime
  28. <#ifMountPVCs??&&(MountPVCs?size>0)>
  29. <#listMountPVCs?keysaskey>
  30. -name:"${key}"
  31. persistentVolumeClaim:
  32. claimName:"${key}"
  33. </#list>
  34. containers:
  35. -name:notebook
  36. image:${image}
  37. imagePullPolicy:IfNotPresent
  38. volumeMounts:
  39. -name:localtime
  40. mountPath:/etc/localtime
  41. <#ifreadMountPVCs??&&(readMountPVCs?size>0)>
  42. <#listreadMountPVCs?keysaskey>
  43. -name:"${key}"
  44. mountPath:"${readMountPVCs[key]}"
  45. readOnly:true
  46. </#list>
  47. </#if>
  48. <#ifwriteMountPVCs??&&(writeMountPVCs?size>0)>
  49. <#listwriteMountPVCs?keysaskey>
  50. -name:"${key}"
  51. mountPath:"${writeMountPVCs[key]}"
  52. </#list>
  53. </#if>
  54. env:
  55. -name:NOTEBOOK_TAG
  56. value:"${name}"
  57. -name:HADOOP_USER
  58. value:"${hadoopUser}"
  59. -name:PASSWORD
  60. value:"${password}"
  61. resources:
  62. requests:
  63. cpu:${cpu}
  64. memory:${memory}Gi
  65. <#if(gpu>0)>
  66. nvidia.com/gpu:${gpu}
  67. </#if>
  68. limits:
  69. cpu:${cpu}
  70. memory:${memory}Gi
  71. <#if(gpu>0)>
  72. nvidia.com/gpu:${gpu}
  73. </#if>

现在GolbinLab已供给根据Tensoflow各版别的CPU与GPU通用镜像11个,以及多个定制化镜像。

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第6张

使命调度

算法搭档在运用容器化环境之前,使命的开发调度都是在GPU物理机器上完结,调度一般都是经过守时器或crontab指令调度使命,使命无失利、超时等报警,以及也没有重试等机制,根本无相关的使命运维东西。

在介绍容器中开发的使命怎么上线调度之前,先扼要介绍一下GoblinLab的体系架构。

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第7张

上图为GoblinLab简化的体系架构,其间首要分为四层,由上到下别离为:

  • Application-应用层:供给直接面向用户的机器学习开发渠道(GoblinLab)
  • Middle-中间层: 中间层,首要是接入了一致的调度、报警、以及装备等服务
  • Wizard-履行服务: 其供给一致的履行服务,供给包括Kubernetes、Spark、Jar等各类使命的提交履行。插件式,支撑快速扩展
  • Infrastructure-根底设施: 底层的根底设施,首要包括Kubernetes集群、Spark集群以及一般服务器等

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第8张

GolbinLab为了保证调度使命的稳定性,将使命的开发与调度拆分,改动之前算法直接在物理机上开发完使命后,经过守时器或许crontab调度使命的方法。如上图所示,在开发完结后,使命的调度是经过使命流中的容器化使命调度组件完结,用户需填组件的相关参数(代码地点PVC及途径,装备镜像等),再经过使命流的调度功用完结使命调度。与使命开发不同,每个调度使命履行在独立的容器中,保证使命间彼此阻隔,一起经过后续介绍的资源阻隔计划,能够优先保证线上调度使命所需资源。

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第9张

使命调度履行的一般流程如下:

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第10张

使命调度履行时在Kubernetes上资源编列文件(已精简细节):

  1. apiVersion:batch/v1
  2. kind:Job
  3. metadata:
  4. name:${name}
  5. namespace:${namespace}
  6. spec:
  7. template:
  8. spec:
  9. containers:
  10. -name:jupyter-job
  11. image:${image}
  12. env:
  13. -name:ENV_TEST
  14. value:${envTest}
  15. command:["/bin/bash","-ic","cd${workDir}&&\
  16. ${execCommand}/root/${entryPath}${runArgs}"]
  17. volumeMounts:
  18. -mountPath:"/root"
  19. name:"root-dir"
  20. resources:
  21. requests:
  22. cpu:${cpu}
  23. memory:${memory}Gi
  24. <#if(gpu>0)>
  25. nvidia.com/gpu:${gpu}
  26. </#if>
  27. limits:
  28. cpu:${cpu}
  29. memory:${memory}Gi
  30. <#if(gpu>0)>
  31. nvidia.com/gpu:${gpu}
  32. </#if>
  33. volumes:
  34. -name:"root-dir"
  35. persistentVolumeClaim:
  36. claimName:"${pvc}"
  37. backoffLimit:0

权限操控

容器化开发环境装备发动后,用户能够经过SSH登录、CodeServer或JupyterLab等其间一种方法运用。为了防止容器化开发环境被其他人运用,GoblinLab给每种方法都设置了一致的密钥,而密钥在每次发动时随机生成。

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第11张

1、随机生成暗码

2、设置账号暗码(SSH登录暗码)

  1. echo"root:${password}"|chpasswd

3、设置Code Server暗码 (VSCode)

  1. #设置环境变量PASSWORD即可
  2. env:
  3. -name:PASSWORD
  4. value:"${password}"

4、设置Jupyter Lab暗码

  1. jupyternotebook--generate-config,~/.jupyter目录下生成jupyter_notebook_config.py,并增加代码
  2. importos
  3. fromIPython.libimportpasswd
  4. c=c#pylint:disable=undefined-variable
  5. c.NotebookApp.ip='0.0.0.0'#https://github.com/jupyter/notebook/issues/3946c.NotebookApp.port=int(os.getenv('PORT',8888))c.NotebookApp.open_browser=False
  6. setsapasswordifPASSWORDissetintheenvironment
  7. if'PASSWORD'inos.environ:
  8. password=os.environ['PASSWORD']
  9. ifpassword:
  10. c.NotebookApp.password=passwd(password)
  11. else:
  12. c.NotebookApp.password=''
  13. c.NotebookApp.token=''
  14. delos.environ['PASSWORD']

数据耐久化

在Kubernetes容器中,如无特别装备,容器中的数据是没有进行耐久化,这意味着跟着容器的删去或许重启,数据就会丢掉。对应的处理方法比较简单,只需给需求耐久化的目录,挂载外部存储即可。在GoblinLab中,会给每个用户主动创立一个默许的外部存储PVC,并挂载到容器的/root目录。别的,用户也能够自定义外部存储的挂载。

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第12张

除了主动创立的PVC外,用户也能够自己创立PVC,并支撑将创立的PVC只读或许读写同享给其他人。

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第13张

别的,在Goblinlab上也能够对PVC里的数据进行办理。

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第14张

服务露出

Kubernetes集群中创立的服务,在集群外无法直接拜访,GoblinLab运用Nginx Ingress + Gateway拜访,将集群内的服务露出到外部。

 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践) 机器学习 Kubernetes 开发 第15张

容器化开发环境的Service资源编列文件如下(已精简细节):

  1. apiVersion:v1
  2. kind:Service
  3. metadata:
  4. name:${name}
  5. namespace:${namespace}
  6. spec:
  7. clusterIP:None
  8. ports:
  9. -name:port-notebook
  10. port:8888
  11. protocol:TCP
  12. targetPort:8888
  13. -name:port-sshd
  14. port:22
  15. protocol:TCP
  16. targetPort:22
  17. -name:port-vscode
  18. port:8080
  19. protocol:TCP
  20. targetPort:8080
  21. -name:port-tensofboard
  22. port:6006
  23. protocol:TCP
  24. targetPort:6006
  25. <#ifports??&&(ports?size>0)>
  26. <#listportsasport>
  27. -name:port-${port}
  28. port:${port}
  29. targetPort:${port}
  30. </#list>
  31. </#if>
  32. selector:
  33. statefulset:${name}
  34. type:ClusterIP

每逢用户发动一个容器化开发环境,GoblinLab将经过接口主动修正Nginx Ingress装备,将服务露出出来,以供用户运用,Ingress转发装备如下:

  1. apiVersion:v1
  2. kind:ConfigMap
  3. metadata:
  4. name:tcp-services
  5. namespace:kube-system
  6. data:
  7. "20000":ns/notebook-test:8888
  8. "20001":ns/notebook-test:8080
  9. "20002":ns/notebook-test:22

资源管控

为进步资源的运用率,GoblinLab底层Kubernetes中的资源,根本都是以同享的方法运用,并进行必定份额的超售。可是当多个团队同享一个资源总量固定的集群时,为了保证每个团队公正的同享资源,此刻需求对资源进行办理和操控。在Kubernetes中,资源配额便是处理此问题的东西。现在GoblinLab需求管控的资源首要为CPU、内存、GPU以及存储等。渠道在考虑各个团队的实践需求后,将资源划分为多个行列(Kubernetes中的概念为namespace),供给给各个团队运用。

  1. apiVersion:v1
  2. kind:ResourceQuota
  3. metadata:
  4. name:skiff-quota
  5. namespace:test
  6. spec:
  7. hard:
  8. limits.cpu:"2"
  9. limits.memory:5Gi
  10. requests.cpu:"2"
  11. requests.memory:5Gi
  12. requests.nvidia.com/gpu:"1"
  13. requests.storage:10Gi

在集群中,最常见的资源为CPU与内存,因为能够超售(overcommit),所以存在limits与requests两个配额约束。除此以外,其他资源为扩展类型,因为不允许overcommit,所以只要requests配额约束。参数阐明:

  • limits.cpu:Across all pods in a non-terminal state, the sum of CPU limits cannot exceed this value.
  • limits.memory: Across all pods in a non-terminal state, the sum of memory limits cannot exceed this value.
  • requests.cpu:Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value.
  • requests.memory:Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value.
  • http://requests.nvidia.com/gpu:Across all pods in a non-terminal state, the sum of gpu requests cannot exceed this value.
  • requests.storage:Across all persistent volume claims, the sum of storage requests cannot exceed this value.
转载请说明出处
知优网 » 机器学习渠道在Kubernetes上的实践(kubernetes最佳实践)

发表评论

您需要后才能发表评论