前面的文章已经说明了docker环境安装,以及nvidia gpu支持的环境准备,并下载了nvidia/cuda镜像作为基础版本,现在基于这个镜像做ffmpeg硬解码,当然也可以做深度学习相关
思路如下:
1)基于镜像创建容器
2)在容器中添加其他环境
3)为了添加环境还得有个传文件进容器的渠道
4)搭建好环境
5)导出新的镜像
https://www.runoob.com/docker/docker-tutorial.html
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nvidia/cuda 10.1-devel 9e47e9dfcb9a 3 months ago 2.83GB
hello-world latest fce289e99eb9 14 months ago 1.84kB
$ sudo docker run -it --runtime=nvidia --rm nvidia/cuda:10.1-devel /bin/bash
#或者使用imageid创建
$ sudo docker run -it --runtime=nvidia --rm 9e47e9dfcb9a /bin/bash
参数说明:
-i: 交互式操作。
-t: 终端。
–runtime 运行时
–rm退出容器以后,这个容器就被删除了,方便在临时测试使用。
/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
root@f02418d05817:/#
ps:进入了容器,可以像正常的ubuntu系统一样操作
root@f02418d05817:/#nvidia-smi
Wed Mar 18 04:51:51 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 430.26 Driver Version: 430.26 CUDA Version: 10.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 166... Off | 00000000:01:00.0 Off | N/A |
| 0% 39C P8 1W / 130W | 347MiB / 5944MiB | 7% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+
#exit退出容器
root@e63be2c8f3fc:/# exit
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be605310afd7 nvidia/cuda:10.1-devel "/bin/bash" 19 minutes ago Exited (0) 16 minutes ago frosty_banzai
f3ee4ae9995d nvidia/cuda "/bin/bash" 20 minutes ago Created charming_easley
602df5b680b7 hello-world "/hello" 56 minutes ago Exited (0) 56 minutes ago goofy_golick
5fd42694310e hello-world "/hello" 2 hours ago Exited (0) 2 hours ago determined_williams
ps:可以看到,并没有e63be2c8f3fc这个容器id, 因为创建的时候加了–rm,退出后自动移除了
我这多余的容器太多,移除掉,只留一个hello-world
$ sudo docker rm -f be605310afd7 f3ee4ae9995d 602df5b680b7
be605310afd7
f3ee4ae9995d
602df5b680b7
#再次查看
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5fd42694310e hello-world "/hello" 2 hours ago Exited (0) 2 hours ago determined_williams
文件互传有两种方式:
1)直接拷贝文件
容器->宿主机
docker cp 容器名:要拷贝的文件在容器里面的路径 要拷贝到宿主机的相应路径
宿主机->容器
docker cp 要拷贝到宿主机的相应路径 容器名:要拷贝的文件在容器里面的路径
试试:
#创建名为test的容器
$ sudo docker run -it --name test --runtime=nvidia 9e47e9dfcb9a /bin/bash
#找一个文件夹,比如/home,现在里面是空的
root@4e51876b3914:/# cd home
root@4e51876b3914:/home# ls
root@4e51876b3914:/home#
#退出容器test
root@4e51876b3914:/home# exit
exit
#查看所有容器,刚创建的容器在这里 name = test container_id = 4e51876b3914
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4e51876b3914 nvidia/cuda:10.1-devel "/bin/bash" 52 seconds ago Exited (0) 21 seconds ago test
5fd42694310e hello-world "/hello" 2 hours ago Exited (0) 2 hours ago determined_williams
#拷贝宿主机的文件到 test:/home/test.txt ,注意此时是在容器停止的时候拷贝的,容器打开的时候拷贝也ok
$ sudo docker cp '/home/zhutao/Desktop/文本.txt' test:/home/test.txt
#重启容器,可以根据name,也可以根据container_id
$ sudo docker restart test
test
#上面的重启无法进入容器内部命令行,attach一下
$ sudo docker attach test
#进入 /home查看,可以看到test.txt已存在
root@4e51876b3914:/# cd /home
root@4e51876b3914:/home# ls
test.txt
2)共享文件夹
目前,仅发现在创建容器的时候挂载宿主机的目录
docker run -it -v 宿主机目录:容器目录 镜像 /bin/bash
#创建带挂载目录的容器
$ sudo docker run -it --name test --runtime=nvidia -v '/home/zhutao/Desktop/docker_share':/home/share 9e47e9dfcb9a /bin/bash
#查看/home/share是否存在
root@fa9108538078:/# cd home
root@fa9108538078:/home# ls
share
#宿主机拷贝一个文件到/home/zhutao/Desktop/docker_share,比如123.txt , 查看容器/home/share目录中文件已存在
root@fa9108538078:/home# cd share
root@fa9108538078:/home/share# ls -a
. .. 123.txt
ffmpeg硬解码跟在外面搭的过程一样,编译好了就可以硬解码了
docker commit 容器名 镜像名
sudo docker commit test testImage:v1.0
等一会执行完毕后,会发现本地镜像中已经多出一个镜像testImage,标签为v1.0
#查看容器信息,信息太长了,这里不看了
$ sudo docker inspect test
...
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "183f454b08234b0e88a088871cea69135625d15078a4ab99eff5e91de7d71d26",
"EndpointID": "bae1f3e88d8917e1b12c6fe9ece0b395536c5a23f070090a23197f9787981b97",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
ps:可以看到在容器中,认为宿主机的ip是172.17.0.1,容器ip为172.17.0.2,已经是同一网段.网络互通,再做个端口映射就好了,这个要在创建容器的时候映射,需要的东西差不多了,创建一个正式版的容器
使用 -p 宿主机port:容器port 多个端口映射,例如-p 8080:8080 -p 80:80
sudo docker run -it --name switch_server_1.0.0 --runtime=nvidia -v '/home/zhutao/Desktop/docker_share':/home/share -p 8000:8000 9e47e9dfcb9a /bin/bash
这时候在里面部署web项目,这个部署就不提了,原来怎么部署,还怎么部署,然后访问宿主机的ip:port就好了
ps: 这里有两点发现:
1)第一次创建容器后,直接在宿主机上执行docker ps -a 是看不到容器的端口的,只有执行了容器中程序监听了端口后才能看到
2)用-p开放的端口都是tcp端口,如果需要开通udp,则像这样指定
-p 9300:9300/udp
1.把指定容器保存成镜像
sudo docker commit test switch_server:v1.0
2.镜像打包并存放到指定目录
sudo docker save switch_server:v1.0 > /tmp/switch_server_1.0.tar
3.将.tar迁移到另一台机器上重新导入
sudo docker load < /tmp/switch_server_1.0.tar