Time Machine

Docker是个好东西,或者说容器是个好东西。
毕竟回忆里的昨天,我再也回不去。
但容器可以。

Docker存储方式

还是先说一下Docker容器的储存结构,容器镜像采用的是分层存储的方式,下面是一个Ubuntu16.04的镜像结构。


docker

也可以在命令行观察,在拉取的时候也可以看到结果:

1
2
3
4
5
6
7
8
9
$ ▶ docker pull ubuntu:16.04
16.04: Pulling from library/ubuntu
3b37166ec614: Already exists
504facff238f: Already exists
ebbcacd28e10: Already exists
c7fb3351ecad: Already exists
2e3debadcbf7: Already exists
Digest: sha256:45ddfa61744947b0b8f7f20b8de70cbcdd441a6a0532f791fd4c09f5e491a8eb
Status: Downloaded newer image for ubuntu:16.04

其中,每层表示的是与上一层的差异,而不是直接操作底层镜像,这样,当使用其他基于此镜像制作的镜像时,就不必整个拉取或者复制过来,因为它们很多的底层镜像是一样的。Docker镜像采用的是共享存储方式,当拉取一个镜像时,会首先获取所有层的信息,如果该镜像层本地已经有了,就不用下载,只需要下载所需要的镜像层。


docker

在使用镜像建立容器时候,会在最上面一层镜像上建立一个可写层,即容器层。当在容器中所有的操作都会被保存在这个可写层,如果直接删除容器,则可写层就会被删除,即使利用相同镜像重新建立容器,之前的所有操作也不会被保存。镜像层都是只读的,基于此安全性,所有的容器都可以访问底层镜像,所以一次可以利用同一镜像建立多个容器。最后完成修改封装成新的容器的时候,也只是在原来的镜像层之上又加了一层而已。镜像的这种共享存储方式可以极大地提高资源利用效率,而差异存储也是文件管理的主流之选。

说到这个,想起来目前有个PWD(Play with Docker)的网站,可以直接在里面体验docker,地址在这。进去就可以创建一个Docker playground。

docker

利用Docker运行CUDA和TensorFlow

在电脑上配置CUDA或者TensorFlow啥的,经常因为各种版本不同导致一大堆问题,于是就想看看可不可以利用Docker去解决这个问题,每次直接打开封装好的镜像就行了,让Docker里的环境去使用GPU,不用去配环境,也不用在电脑上装啥别的软件。然后发现NVIDIA也在Docker上稍微封装了一下,弄了个Nvidia-docker命令,基本命令与docker命令一样,唯一的区别是普通的Docker无法使用GPU,所以Nvidia-docker等效于命令docker --runtime=nvidia

要使用GPU,首先也要安装好显卡驱动,怎么安装这里不做赘述,通常安装成功是可以看到的。



当然,Docker肯定要先装好。

Nvidia Docker

然后就是安装Nvidia封装的Docker来调用GPU了,具体可以参照NVIDIA/nvidia-docker页面。



如果之前有安装1.0版本的Nvidia-docker的,需要先卸载:

1
2
3
# If you have nvidia-docker 1.0 installed: we need to remove it and all existing GPU containers
docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
sudo apt-get purge -y nvidia-docker

没有的话可以直接略过。然后添加仓库地址重定向到镜像源文件中,再更新软件源。

1
2
3
4
5
6
7
# Add the package repositories
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update

然后直接安装即可。

1
2
3
# Install nvidia-docker2 and reload the Docker daemon configuration
sudo apt-get install -y nvidia-docker2
sudo pkill -SIGHUP dockerd

CUDA测试

首先运行一个cuda的镜像,进入bash中,

1
2
3
docker run --runtime=nvidia -it --name cuda --rm nvidia/cuda:9.0-base /bin/bash
root@c1d523d61051:/#
root@c1d523d61051:/#

这里将容器命名为cuda方便操作,需要选择runtime为nvidia,或者直接使用nvidia-docker命令。然后输入nvidia-smi就可以看到是否成功调用显卡了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@c1d523d61051:/# nvidia-smi
Thu Oct 11 07:51:19 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.130 Driver Version: 384.130 |
|-------------------------------+----------------------+----------------------+
| 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 1080 Off | 00000000:01:00.0 On | N/A |
| 0% 44C P8 14W / 200W | 867MiB / 8110MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+

TensorFlow测试

刚刚也说了,如果要使用GPU,需要在docker命令中加上–runtime=nvidia或者直接使用nvidia-docker命令。这里就直接使用nvidia-docker命令了,

1
2
$ ▶ nvidia-docker run -it -d --name tensor -p 8888:8888 tensorflow/tensorflow
9c7db93b36788acf61a20f52cb187f32e0d6018f7e8da031a30fa135252a4896

查看容器内信息,

1
2
3
4
5
6
7
8
9
10
11
docker logs tensor
[I 08:01:55.452 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret
[I 08:01:55.465 NotebookApp] Serving notebooks from local directory: /notebooks
[I 08:01:55.465 NotebookApp] The Jupyter Notebook is running at:
[I 08:01:55.465 NotebookApp] http://(9c7db93b3678 or 127.0.0.1):8888/?token=64e73aaba8febd5539fae22201c7b7cea1b8578cc1413850
[I 08:01:55.465 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 08:01:55.466 NotebookApp]
Copy/paste this URL into your browser when you connect for the first time,
to login with a token:
http://(9c7db93b3678 or 127.0.0.1):8888/?token=64e73aaba8febd5539fae22201c7b7cea1b8578cc1413850

打开浏览器窗口,输入localhost:8888/?token=64e73aaba8febd5539fae22201c7b7cea1b8578cc1413850,可以看到一个Jupyter的界面。
jupyter

在里面可以编辑及运行python程序,或者使用终端操作:

1
2
3
4
5
6
7
8
9
10
$ ▶ docker exec -it tensor /bin/bash
root@9c7db93b3678:/notebooks# ls
1_hello_tensorflow.ipynb 2_getting_started.ipynb 3_mnist_from_scratch.ipynb BUILD LICENSE
root@9c7db93b3678:/notebooks# python
python python2 python2.7 python3 python3.5m
python-config python2-config python2.7-config python3.5 python3m
root@9c7db93b3678:/notebooks# python
Python 2.7.12 (default, Dec 4 2017, 14:50:18)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.

关于Docker的Runtime

一个容器运行需要制定规范、Runtime、管理和定义工具、镜像仓库、运行OS等环节。容器的Runtime是容器运行时的一些规范,主要任务是和操作系统的kernel协作来提供容器的运行环境,由OCI(Open Container Initiative,由Google,Docker、CoreOS、IBM、微软、红帽等于2015年联合发起的组织)维护。主要包括容器的文件系统包(Filesystem Bundle),容器的运行和生存周期Runtime and Lifecycle),容器配置文件(Container Configuration file),以及Linux的运行和配置文件(Linux Runtime, Linux Container Configuration)等。目前Linux上最原始的容器Runtime是LXC,即Linux Container,最初Docker也是用LXC作为Runtime,后来Docker基于libcontainer开发了自己的Runtime,即runC。谷歌也基于Docker的Runtime发布了Kubernetes,后来CoreOS开发了独立的rkt作为运行容器的Runtime。
而与容器相对的就是虚拟机了,目前虚拟机的Runtime如runV,看名字就知道是要与runC分庭抗礼的。此外Intel也弄了一个Clear containers的Runtime,也可以对接容器。基于Hyper runV和Clear containers,Openstack又新起了一个Kata Containers,目前已经可以在snap商店看到了,才出来没多久,地址在这

利用Docker搭建私有云盘

安装

这里使用的是一个开源的云存储方案OwnCloud来搭建私有云盘。
首先可以搜一下Dockerhub中的镜像,docker search owncloud可以看到结果:

owncloud

其中第一个就是官方的镜像了,直接docker pull owncloud:8.1拉取就行。或者也可以直接docker run,本地没有它会去Dockerhub下载。

1
docker run -d -p 80:80 owncloud:8.1

其中,-d表示后台运行,-p用来映射端口。也可以直接用-it前台打开tty直接操作。
这时候可以在浏览器中看到了,输入localhost就可以看到登陆界面,大致是下面的样子:
owncloud

运行配置

其中数据保存在/var/www/html/data目录中,默认是使用SQLite用于数据存储,但对于较大的或者使用桌面客户端同步文件时,并不推荐SQLite,可以考虑最流行的MySQL。其他数据库需要外部安装。
在运行时可以使用-v选项来将本地磁盘挂载到容器中数据保存的位置,即/var/www/html/中。

1
-v /<mydatalocation>:/var/www/html

分的更细一点,可以添加三项,设置命令:

1
2
3
-v /<mydatalocation>/apps:/var/www/html/apps installed / modified apps
-v /<mydatalocation>/config:/var/www/html/config local configuration
-v /<mydatalocation>/data:/var/www/html/data the actual data of your ownCloud

数据库配置

外部数据库配置有几种方法,第一个是使用Owncloud自己提供的OCC工具(OwnCloud Console)来配置,使用docker exec执行:

1
docker exec -u www-data some-owncloud php occ status

另外的就是用Docker的工具了,Docker Stack或者Docker Compose来配置。首先需要编辑一个yml配置文件,如stack.ymlcompose.yml,名字随便起,然后加入数据库配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ownCloud with MariaDB/MySQL
#
# Access via "http://localhost:8080" (or "http://$(docker-machine ip):8080" if using docker-machine)
#
# During initial ownCloud setup, select "Storage & database" --> "Configure the database" --> "MySQL/MariaDB"
# Database user: root
# Database password: example
# Database name: pick any name
# Database host: replace "localhost" with "mysql"
version: '3.1'
services:
owncloud:
image: owncloud:8.1
restart: always
ports:
- 8080:80
volumes:
- "/home/newdee/Downloads/owncloud/:/var/www/html/"
mysql:
image: mysql:5.6
restart: always
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: owncloud
MYSQL_USER: first
MYSQL_PASSWORD: 123456

最后运行docker stack deploy -c stack.yml owncloud (or docker-compose -f compose.yml up)即可。
此时可以发现有两个容器正在运行:

1
2
3
4
$ ▶ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8499dc015bc8 owncloud:8.1 "/entrypoint.sh apac…" 15 minutes ago Up 12 minutes 0.0.0.0:8080->80/tcp owncloud_owncloud_1
6e145ebcca20 mysql:5.6 "docker-entrypoint.s…" 15 minutes ago Up 12 minutes 3306/tcp owncloud_mysql_1

然后在浏览器输入http://localhost:8080可以看到登陆界面,登录信息填yml文件中的信息就行。
owncloud

登陆成功就可以看到登陆界面了。然后就可以网页上传下载了,还可以生成分享链接。上传下载地址位于挂载的目录中。没有机子也可以去试试VPS,自己搭一个私有云盘用来平时备份下载。

owncloud

孤芳自赏,不必捧场。
分享