镜像解耦工程化-实现服务低耦合
当前遇到问题:
当前notebook的方案中,用户可以直接访问的业务容器是以root用户启动的,启动脚本在容器中,以root用户执行一些初始化操作后,然后以ma-user启动http服务,然后以http的方式供用户访问,用户连接http服务的时候,可以以ma-user执行操作。这种方案在启动镜像保存和自定义镜像的弊端有:
1、启动脚本在build镜像的ENTRYPOINT指定,用户自定义镜像启动脚本不可控,以root方式启动,不符合业务容器安全规范
2、如果自定义镜像中设置了VOLUME,docker会默认为每一个VOLUME项挂载宿主机的一个目录,且该目录属性可以在自定义镜像的Dockerfile中设定,这样,用户的代码便可以向该目录注入大量数据,侵占宿主机磁盘,导致宿主机docker空间占满,影响宿主机正常工作
3、用户自定义的训练镜像或者已经在训练系统中可以运行镜像,如果需要调试,无法在开发环境中直接启动,有一定镜像改造工作;同时改造后的镜像,在开发环境中启动,如果因为改造镜像的问题而导致notebook启动失败,无法看到错误日志
4、开发环境中的一些更新(更新频率高),比如启动脚本以及jupyterlab插件的更新,不能在已经保存的镜像和用户自定义镜像对应的notebook中更新
5、以开发环境的镜像提交成训练作业时,开发环境的镜像大(jupyterlab相关的文件在训练中使用不到的),影响任务启动速度,占用额外磁盘空间
6、开发环境中的一些热更新操作,由于镜像中的版本很大概率不是最新版本,容器启动的时候,需要下载/安装更新(经常会因为网络等原因有失败的情况);安装更新期间如果用户在使用相关内容(比如modelarts sdk),会触发异常
解决思路:
将开发环境的启动脚本以及启动相关的release内容从镜像中解耦出来:
1、启动业务容器时,必须通过securityContext明确指定runAsUser:1000 (modelarts统一镜像的ma-user的user id为1000),且allowPrivilegeEscalation: false(防止自定义镜像中给1000用户设置setuid提权为root),解决自定义镜像的安全问题
2、开发环境的release包(启动脚本以及相关包,比如notebook、jupyterlab插件等)从业务容器剥离出来,单独release到宿主机,业务容器通过readOnly的方式挂载到运行容器中,启动notebook;
3、需要对业务容器做一些只有root用户才能做的初始化工作(比如确保/home/ma-user/work的ownership为ma-user:ma-group),通过initContainer完成
4、无需更新release,可支持启动脚本支持可扩展(ModelArts官方脚本扩展和用户自定义扩展)
5、热更新包操作在agent中执行,部署到当前节点的notebook容器挂载使用即可,一次更新,全量生效
6、agent检测notebook启动的容器是否生成了docker volume,如果有,则将对应的宿主机上的目录设置成root:root属主以及000文件mode,防止用户代码注入大量数据,影响节点的正常工作
组件分布:
release内容:
- 点赞
- 收藏
- 关注作者
评论(0)