前言

前面的文章已经说明了docker环境安装,以及nvidia gpu支持的环境准备,并下载了nvidia/cuda镜像作为基础版本,现在基于这个镜像做ffmpeg硬解码,当然也可以做深度学习相关

正文

思路如下:
1)基于镜像创建容器
2)在容器中添加其他环境
3)为了添加环境还得有个传文件进容器的渠道
4)搭建好环境
5)导出新的镜像

1 首先找个操作手册

https://www.runoob.com/docker/docker-tutorial.html

2 创建容器

2-1 查看本地镜像

$ 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

2-2 加载nvidia/cuda镜像创建容器

$ 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


2-3 查看所有容器

$ 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,退出后自动移除了

2-4 再次进入容器

$ sudo docker restart frosty_banzai
frosty_banzai
$ sudo docker attach frosty_banzai
root@bafb2a0a1b1a:/#

2-5 批量删除容器

我这多余的容器太多,移除掉,只留一个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

2-6 容器与宿主机文件互传

文件互传有两种方式:
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硬解码跟在外面搭的过程一样,编译好了就可以硬解码了

2-7 容器导出镜像

docker commit 容器名 镜像名

sudo docker commit test testImage:v1.0

等一会执行完毕后,会发现本地镜像中已经多出一个镜像testImage,标签为v1.0

2-8 部署web项目

#查看容器信息,信息太长了,这里不看了
$ 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

2-9 docker迁移

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

3 创建镜像

拉取python镜像环境

sudo docker pull python:3.8
创建容器后发现其实就是一个带python3.8的小型linux系统

/# ls -l
total 64
drwxr-xr-x   1 root root 4096 Sep 13 03:44 bin
drwxr-xr-x   2 root root 4096 Sep  3 12:10 boot
drwxr-xr-x   5 root root  360 Sep 22 09:28 dev
drwxr-xr-x   1 root root 4096 Sep 22 09:28 etc
drwxr-xr-x   2 root root 4096 Sep  3 12:10 home
drwxr-xr-x   1 root root 4096 Sep 13 03:44 lib
drwxr-xr-x   2 root root 4096 Sep 12 00:00 lib64
drwxr-xr-x   2 root root 4096 Sep 12 00:00 media
drwxr-xr-x   2 root root 4096 Sep 12 00:00 mnt
drwxr-xr-x   2 root root 4096 Sep 12 00:00 opt
dr-xr-xr-x 438 root root    0 Sep 22 09:28 proc
drwx------   1 root root 4096 Sep 13 15:00 root
drwxr-xr-x   3 root root 4096 Sep 12 00:00 run
drwxr-xr-x   1 root root 4096 Sep 13 03:43 sbin
drwxr-xr-x   2 root root 4096 Sep 12 00:00 srv
dr-xr-xr-x  13 root root    0 Sep 22 09:28 sys
drwxrwxrwt   1 root root 4096 Sep 13 15:04 tmp
drwxr-xr-x   1 root root 4096 Sep 12 00:00 usr
drwxr-xr-x   1 root root 4096 Sep 12 00:00 var

$ sudo docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
python       3.8       9fa000b720b7   8 days ago   913MB

编写dockerfile

# 基于某个镜像启动
FROM python:14.04
MAINTAINER Docker Newbee <newbee@docker.com>
RUN apt-get -qq update
RUN apt-get -qqy install ruby ruby-dev
RUN gem install sinatra
FROM python:3.7-alpine
ADD . /code
WORKDIR /code
EXPOSE 8078
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libsndfile1
RUN /usr/local/bin/python -m pip install --upgrade pip(可删)
RUN pip install -r requirements.txt -i https://pypi.doubanio.com/simple/
CMD python web_service2.py
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐