Docker部署模型训练+Jenkins自动运维
使用Docker容器进行模型训练的方式可以不依赖与服务器的软件环境,方便迁移,并且线上服务可以结束swarm集群进行高可用。
Jenkins是配合git实现自动运维的工具,开发人员可以在不登录服务器实现代码和服务更新,提高系统的安全性。
这里分为两部分,一是训练,二是预测。
首先模型训练部分,基本的步骤:
1.安装docker
2.模型训练的整个流程本地测试通过
3.选择或者制作一个基础镜像,这里建议把所有软件都安装好(一般来说系统上线以后都会隔绝外网,所以要提前考虑好未来可能用到的软件)
4.编写Dockerfile
5.编写build镜像和docker run的运行脚本,配合Jenkins的话一般是build.sh和update_service.sh两个脚本,在build里边要把基于dockerfile制作的镜像push的镜像仓库。
这里有个困难点是配合测试,因为一般来说模型训练阶段制作的离线特征数据和模型文件要被线上预测服务使用。但是基于docker的方式部署,训练和预测是两个独立的容器。
解决这个问题可以采用:
在编写训练的update_service的时候,使用docker run -v的方式,把本地的一个目录挂载到训练容器里,这样数据和模型文件就可以传出来了。
然后配合在线上预测的Jenkins项目配置里通过shell传:用scp的方式把本地的文件传到线上服务器上,然后再启动update_service。(配置时要使用sshpass免密)
由于模型要定时训练,基于这种方式,在Jenkins里模型训练和预测的两个项目都要配置定时build。
训练部分不使用Jenkins也行,只要本地或者测试机上可以把镜像推送到线上服务器就行,本地改完代码重新打包好镜像推送上去就行。
然后模型预测部分
基本步骤和训练是差不多的,如果是服务接口的方式,update_service里是用docker service的方式。
以上是一种思路,像是dockerfile的编写、基础镜像的制作、docker service的命令、Jenkins使用都可以从网上找到教程。
补充:
预测服务的部分因为要每日拉取最新的模型和文件,所以要每日更新服务,这里适合用docker service update命令,配合update_delay参数和服务副本,可以让服务没有停止时间。
再配合docker create可以防止由于某些原因服务没了,需要重新创建的情况。
另外镜像的tag要绑定每日日期,可以参考:
1 container_id=`docker service inspect service_name` 2 echo 'current service info :' 3 echo ${#container_id} 4 dd=`date +%Y-%m-%d` 5 echo ${dd} 6 7 modelname="service_name" 8 version=`date +%Y-%m-%d` 9 image_name=docker_images_url/${modelname}:${version} 10 if [ ${#container_id} == 2 ];then 11 echo 'docker create------------------' 12 docker service rm service_name 13 docker service create --name service_name --with-registry-auth --replicas 2 --placement-pref 'spread=node.labels.Inference' --publish published=9079,target=80 ${image_name} 14 else 15 echo 'docker update-------------------' 16 docker service update --update-failure-action=rollback --update-parallelism 1 --with-registry-auth --update-delay 30s --image ${image_name} service_name 17 fi