使用GPU-Docker-API管理GPU模型容器版本

前言

在之前的帖子中我用 Go 实现了一个简单的项目,它可以代替你创建 GPU 容器,Volume,以及方便地更新容器的 GPU 配置、Volume 的存储容量等(在不关闭 Docker 进程的情况下)。

如果你还不熟悉,可以查看Docker 二次开发 | NVIDIA Docker + Docker Client 调度 GPU 容器项目

项目一开始的名称叫 GPU-Docker-Demo,我想通过直接调用 Docker Client的方式来创建容器,并提供 HTTP 接口,更方便的使用 Docker。然后尝试如何实现更新一个已存在容器的 GPU 数量,已存在 Volume 的存储容量等,最终通过拷贝 Overlay2 下容器的 merged layer 到新创建的容器中来实现,这样要比将容器提交为镜像再启动快的多。

最初我想这个项目应该是面向熟悉 Golang 语言的开发者,仅仅只是为你提供一个思路,并不想写一个完整的项目。所以提供的接口大多都比较抽象,需要了解项目的原理后才能更好的使用。

后来发现有不少只会 Python 的小伙伴 star 了我的项目,并且给我提了一些 issues,他们往往不熟悉 Golang 语言,并且对构建项目、配置项目以及出错后的日志很陌生,并且对接口的使用也很迷茫,所以我更改了大部分代码,简化了操作。

比如你可以直接从 release 下载二进制文件然后直接运行,配置通过参数的形式传递;通过导入 json 到 apifox 或者直接通过我分享的在线网站来查看 api 的定义信息。

新的功能

通过和 iomgaa-ycz 讨论,我发现学习 AI 的研究生可能会有版本控制的需求,比如我先创建一个容器,调整一些参数,然后获取到最后的结果。如果结果不太理解,我可能需要再次调整一些参数,但是之前的容器我也不想删除,方便我再次启动这个容器用于对比。

之前的做法可能是,将旧容器提交为镜像,然后创建一个新容器,最后通过 docker cp 将代码拷贝进新容器,如果旧容器里安装了一些软件,例如 vim、python,那么只能在新容器里再安装一遍了,管理起来很繁琐。

所以我试着解决这个问题,并提供了一个回滚的接口,就像 K8s 的回滚到指定版本一样。同时提供了查询历史版本接口,更方便查看容器的创建信息(类似于 K8s 中关于资源描述的 Yaml)。

下面我为你简单的演示一下这个功能。

我们先通过 创建 ReplicaSet 接口生成了一个版本为 1 的 foo 容器并且使用了 3 张卡。(ReplicaSet只是一个抽象的概念,它并没有具体实现,只是代表了具有历史版本的、可回滚的容器而已。)

比如我们要在这个容器安装 Python3,然后写一些代码。

通过 GPU-Docker-API 创建或者更新后的容器,都会在环境变量 CONTAINER_VERSION 里保存当前版本号,方便使用。

python 复制代码
$ cat main.py 
import os  
print("CONTAINER_VERSION: ", os.environ['CONTAINER_VERSION'])  
$ python3 main.py 
CONTAINER_VERSION:  1

然后我们先在这个容器的基础上,直接复制一个容器出来,然后旧的容器停止。

所以我们调用 patch 接口更新它,只不过我们只想要复制,所以 Boyd 传递一个空即可。

可以看到 foo-2 容器被创建了。我们跳过实际使用它的步骤。

foo-1,foo-2 都是使用了 3 张 gpu,我们改变一下 gpu 数量,然后尝试回滚到最初的 foo-1 版本。

先调用获取 ReplicaSet 历史版本的接口,看看它都有哪些版本。

然后回滚到 foo-1 的版本,可以看到 foo-4 被创建了(这里规定了版本号是递增的)。在前面的操作中,foo-1,foo-2 是使用了 3 张卡的,foo-3 是使用了 1 张卡;并且 foo-1 里面还安装了 Python3,编写了 main.py

我们来验证一下。很酷😎,保存在非挂载目录的文件和安装的软件都在。我想这会让你炼丹的过程稍微轻松一点,不过浪费时间在提交镜像、拷贝数据上了。

shell 复制代码
$ docker exec -it foo-4 bash
$ ls -al | grep main.py
-rw-r--r--    1 root root    76 Jan 23 08:55 main.py
$ python3 main.py 
CONTAINER_VERSION:  4

项目地址

gpu-docker-api

更多的功能可以参考:github.com/mayooot/gpu...

写在最后

因为实现这些功能,代码数量会急剧增加,一个人维护也有点困难,所以可能会有一些 bug,欢迎你随时到 GitHub 上提交 issues。

如果对你有帮助,欢迎点一个 ⭐️,这对我很重要哦。

相关推荐
热金鼠几秒前
Ubuntu 22.04 Docker 完整使用手册(2)
docker
天才测试猿3 小时前
Jenkins+Docker自动化测试全攻略
自动化测试·软件测试·python·测试工具·docker·jenkins·测试用例
JAVA学习通3 小时前
《大营销平台系统设计实现》 - 营销服务 第8节:抽奖规则树模型结构设计
运维·决策树·docker·容器·责任链模式
明月_清风4 小时前
Go 没有 `class`,如何实现面向对象三要素?与传统 OOP 的深度对比
后端·go
审判长烧鸡5 小时前
【GO context 】上下文取消/超时的本质
go·context·上下文·ai问答
m0_502724958 小时前
Go 语言 defer 在命名返回值 和 匿名返回值 函数中的表现不一样
go
无相孤君9 小时前
我用 Docker + JunimoServer 搭了一个星露谷物语无头服,还顺手做了个本地管理面板
linux·游戏·docker·开源
爱吃龙利鱼9 小时前
ubuntu2026.04部署k8s1.36版本的傻瓜式教程(注:运行时为docker,网络插件为calico)
运维·网络·笔记·docker·云原生·kubernetes
会编程的土豆10 小时前
Docker 日常操作笔记(开发最常用命令)
笔记·docker·容器
java知路10 小时前
解决 Go 编译速度慢的问题
go