-
实现效果(笔者看中且本文介绍的功能)
- docker swarm 自带的负载均衡
- 更加底层的并行运行 GPU 程序
- 节点伸缩用 docker 接口管理
- 更多优点请参考 https://docs.docker.com/engine/swarm/ 和 NVIDIA MIG 的介绍
-
具体方法
-
创建 swarm 集群(所创建集群的服务器默认为管理节点,管理节点默认也是工作节点)
docker swarm init Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Note❗ : 如果你的 Docker 主机有多个网卡,拥有多个 IP,必须使用
--advertise-addr
指定 IP。[1] -
配置 docker GPU 资源以让 docker swarm 的服务的任务能够用上 GPU[2]
-
切分出多个 GPU 实例[4]
-
kill cuda 相关的进程、
docker stop
相关的容器(比如dcgm-exporter
)或相关的 GPU 应用 -
开启 MIG mode (之后都需要 root 权限)
-
nvidia-smi -i 0 -mig 1
如果提示如下说没有开启持续模式
persistence mode
,输入nvidia-smi -pm 1
开启,说明参见[7][guido@centos7-gpu ~]# sudo nvidia-smi -i 0 -mig 1 Enabled MIG Mode for GPU 00000000:00:07.0 Warning: persistence mode is disabled on device 00000000:00:07.0. See the Known Issues section of the nvidia-smi(1) man page for more information. Run with [--help | -h] switch to get more information on how to enable persistence mode. All done.
开启后会降低使用 GPU 程序的加载延迟,重启后
persistence mode
失效,需重新开启,仅 Linux 支持 -
nvidia-smi -i 0 --query-gpu=pci.bus_id,mig.mode.current --format=csv
-
-
查看 GPU 支持切分的配置
nvidia-smi mig -lgip
-
(可选,步骤 3 也有)查看可切分的程度的各配置的 ID
nvidia-smi mig -lgipp
-
创建 4 个配置方式是 ID 为 14 所映射的配置的 A30 MIG 实例
sudo nvidia-smi mig -cgi 14,14,14,14 -C
-C
选项说明:创建 GI 的时候自动创建对应的 CI原文:Once the GPU instances are created, one needs to create the corresponding Compute Instances (CI). By using the
-C
option, nvidia-smi creates these instances. -
此时已经切分好 GPU 计算卡了,可跳转至 2.2 小节,此节后续是笔者对 GI 和 CI 的关系的探讨。
正如管网所说,GI 可以进一步切分出多个 CI,但笔者所用的服务器是一块 A30,只有 4 个 CI,故切分出 4 个 GI 后而不能再细分出 CI。
-
nvidia-smi --gpu-reset
后,可重新配置 MIG -
进一步细分 CI 的时候,也会有对应映射的设备 UUID
-
列出支持进一步细分的 CI
nvidia-smi mig -lcip [-gi <gi_id>]
-
CI 映射的设备 UUID
[root@gpu-test-centos7 client]# nvidia-smi mig -cci 0,0 -gi <gi_id> [root@gpu-test-centos7 client]# nvidia-smi -L GPU 0: NVIDIA A30 (UUID: GPU-bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb) MIG 1c.2g.12gb Device 0: (UUID: MIG-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) MIG 1c.2g.12gb Device 1: (UUID: MIG-yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy) MIG 1c.2g.12gb Device 2: (UUID: MIG-zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz) MIG 1c.2g.12gb Device 3: (UUID: MIG-aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa)
-
-
-
-
复制
nvidia-smi -L
输出的 MIG 的 UUIDNote ❗: 实际的 MIG UUID 应是形如
MIG-a1b33b37c-dcd4-5676-8918-1a4fce9ee04e
的 uuid,本处已隐去。因为笔者发现关闭再重新切分后的 UUID 是不变的。[guido@centos7-gpu ~]# nvidia-smi -L GPU 0: NVIDIA A30 (UUID: GPU-bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb) MIG 1g.6gb Device 0: (UUID: MIG-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) MIG 1g.6gb Device 1: (UUID: MIG-yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy) MIG 1g.6gb Device 2: (UUID: MIG-zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz) MIG 1g.6gb Device 3: (UUID: MIG-aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa)
-
将 UUID 通过形如
vim /etc/docker/daemon.json
添加到daemon.json
里的node-generic-resources
中Note❗:节点通用资源
node-generic-resources
中的键名是可自由指定的,笔者之后的示例都以gpu
呈现[5]。P.S. 🧐:参考链接中的说明非常生动形象。
{ "runtimes": { "nvidia": { "path": "/usr/bin/nvidia-container-runtime", "runtimeArgs": [] } }, "default-runtime": "nvidia", "node-generic-resources": [ "gpu=<指令 nvidia-smi -L 输出的完整的 GPU 实例(GI)的 UUID>" ] }
-
例如
{ "insecure-registries": [ "xxx.xxx.xxx.xxx:xxxx", ], "registry-mirrors": [ "http://xxx.xxx.xxx.xxx:xxxx", ], "runtimes": { "nvidia": { "args": [], "path": "nvidia-container-runtime" } }, "default-runtime": "nvidia", "node-generic-resources": [ "gpu=MIG-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "gpu=MIG-yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy", "gpu=MIG-zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz", "gpu=MIG-aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" ] }
-
-
vim /etc/nvidia-container-runtime/config.toml
取消注释或添加swarm-resource = "DOCKER_RESOURCE_GPU"
-
重启 docker 服务
sudo systemctl restart docker.service
-
-
在管理节点上创建服务
-
(可选)子节点以工作节点或管理节点的身份加入docker swarm[11]
-
连接要做工作节点的服务器
-
输入 docker swarm init 后,终端打印的提示的命令
docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377
-
忘记如何以工作节点加入则
docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ 192.168.99.100:2377
-
要以管理节点加入则
docker swarm join-token manager To add a manager to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-61ztec5kyafptydic6jfc1i33t37flcl4nuipzcusor96k7kby-5vy9t8u35tuqm7vh67lrz9xp6 \ 192.168.99.100:2377
-
-
准备调用 GPU 的程序并写好
Dockerfile
。比如基于 FastAPI 或 Flask 的 python 程序[9],不是本文的重点故省略。 -
准备
docker stack
的.yml
配置文件,比如叫swarm_compose.yml
。下列示例中没有说明的配置字段用法,请参看官网。
Note❗:
docker compose
的有些字段在后续用docker stack
部署到swarm
里不兼容services: api: image: Your-Registry-IP/Your-Repository/Your-Docker-Image build: context: . dockerfile: Dockerfile ports: - '6666:8000' deploy: resources: reservations: generic_resources: - discrete_resource_spec: # kind 对应 node-generic-resources 里配置的键名即配置用什么资源 kind: "gpu" # value 表示要用多少个 kind 对应的资源 value: 1 mode: replicated replicas: 2
-
启动服务
docker stack deploy -c swarm_compose.yml my_inference_server
然后 docker 会用
swarm_compose.yml
里 services 字段里服务的名字加个后缀,如my_inference_server_api
Note❗:子节点如果找不到配置文件中的镜像时,子节点里的任务会启动失败。故建议如配置文件中的部署私有的docker镜像仓库。读者可以参看
Harbor Registry
或 docker 官方提供的工具docker-registry
,点击跳转url。 -
任务伸缩
-
此处笔者在两个服务器上实验,工作节点的 A30 分了 4 个 GI,管理节点的 A30 没有应用 MIG,故最大并行服务的任务只能拉到 5 个
[guido@centos7-gpu ~]# docker service scale my_inference_server_api=5 my_inference_server_api scaled to 5 overall progress: 5 out of 5 tasks 1/5: running [==================================================>] 2/5: running [==================================================>] 3/5: running [==================================================>] 4/5: running [==================================================>] 5/5: running [==================================================>] verify: Service converged
-
否则,docker swarm 会如下一直寻找符合资源配置的服务器创建任务。
可以用
docker service ps --no-trunc my_inference_server_api
查看节点未启动的原因,比如第 6 个任务除了会说"no suitable node (insufficient resources on 2 nodes)"
还有更多详细信息[guido@centos7-gpu ~]# docker service scale my_inference_server_api=6 my_inference_server_api scaled to 6 overall progress: 5 out of 6 tasks 1/6: running [==================================================>] 2/6: running [==================================================>] 3/6: running [==================================================>] 4/6: running [==================================================>] 5/6: running [==================================================>] 6/6: no suitable node (insufficient resources on 2 nodes) ^cOperation continuing in background. Use `docker service ps my_inference_server_api` to check progress. [guido@centos7-gpu ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS ijrdszbvp6ro my_inference_server_api replicated 5/6 xxx/xxx/object_detect:latest *:6666->8000/tcp
-
-
-
监控运行日志
docker service logs -f my_inference_server_api
此时会看到如下各节点,
my_inference_server
服务的各任务[8]的运行情况my_inference_server_api.2.j804048caq63@centos7-gpu | [07.20.2024 16:45:55] xxx my_inference_server_api.2.j804048caq63@centos7-gpu | [07.20.2024 16:45:55] xxx my_inference_server_api.3.jt5euhhxi1i7@centos7-gpu | xxx my_inference_server_api.3.jt5euhhxi1i7@centos7-gpu | xxx
-
删除 docker swarm 服务和退出 MIG 模式
-
docker stack rm my_inference_server
等待 docker 清理完毕后再执行后续命令
-
sudo nvidia-smi mig -dci && sudo nvidia-smi mig -dgi
-
nvidia-smi -mig 0
-
-
-
参考链接
- https://yeasy.gitbook.io/docker_practice/swarm_mode/create
- https://gist.github.com/tomlankhorst/33da3c4b9edbde5c83fc1244f010815c
- https://docs.docker.com/engine/swarm/swarm-tutorial/
- https://docs.nvidia.com/datacenter/tesla/mig-user-guide/index.html#running-with-mig
- https://gabrieldemarmiesse.github.io/python-on-whales/user_guide/generic_resources/
- https://docs.docker.com/engine/swarm/stack-deploy/?highlight=docker&highlight=stack&highlight=deploy#set-up-a-docker-registry
- https://developer.download.nvidia.com/compute/DCGM/docs/nvidia-smi-367.38.pdf
- https://docs.docker.com/engine/swarm/key-concepts/
- https://docs.docker.com/engine/swarm/stack-deploy/#create-the-example-application
- https://docs.docker.com/engine/swarm/
- https://docs.docker.com/engine/swarm/join-nodes/
基于 docker swarm 和 NVIDIA MIG 并行部署 AI 推理服务
于 2024-07-20 18:17:21 首次发布