五、容器数据管理,链接容器,构建私有库
① 容器数据管理
docker管理数据的方式有两种:
- 数据卷
- 数据卷容器
1. 数据卷
数据卷是一个或多个容器专门指定绕过Union File System的目录,为持续性或共享数据提供一些有用的功能:
- 数据卷可以在容器间共享和重用
- 数据卷数据改变是直接修改的
- 数据卷数据改变不会被包括在容器中
- 数据卷是持续性的,直到没有容器使用它们
添加一个数据卷
你可以使用-v选项添加一个数据卷,或者可以使用多次-v选项为一个 docker 容器运行挂载多个数据卷。
$ sudo docker run --name data -v /data -t -i ubuntu:14.04 /bin/bash # 创建数据卷绑定到到新建容器,新建容器中会创建 /data 数据卷
bash-4.1# ls -ld /data/ drwxr-xr-x 2 root root 4096 Jul 23 06:59 /data/ bash-4.1# df -Th Filesystem Type Size Used Avail Use% Mounted on ... ... ext4 91G 4.6G 82G 6% /data
创建的数据卷可以通过docker inspect获取宿主机对应路径
$ sudo docker inspect data ... ... "Volumes": { "/data": "/var/lib/docker/vfs/dir/151de401d268226f96d824fdf444e77a4500aed74c495de5980c807a2ffb7ea9" }, # 可以看到创建的数据卷宿主机路径 ... ...
或者直接指定获取
$ sudo docker inspect --format="{{ .Volumes }}" data map[/data: /var/lib/docker/vfs/dir/151de401d268226f96d824fdf444e77a4500aed74c495de5980c807a2ffb7ea9]
挂载宿主机目录为一个数据卷
-v选项除了可以创建卷,也可以挂载当前主机的一个目录到容器中。
$ sudo docker run --name web -v /source/:/web -t -i ubuntu:14.04 /bin/bash bash-4.1# ls -ld /web/ drwxr-xr-x 2 root root 4096 Jul 23 06:59 /web/ bash-4.1# df -Th ... ... ext4 91G 4.6G 82G 6% /web bash-4.1# exit
默认挂载卷是可读写的,可以在挂载时指定只读
$ sudo docker run --rm --name test -v /source/:/test:ro -t -i ubuntu:14.04 /bin/bash
2.创建和挂载一个数据卷容器
如果你有一些持久性的数据并且想在容器间共享,或者想用在非持久性的容器上,最好的方法是创建一个数据卷容器,然后从此容器上挂载数据。
创建数据卷容器
$ sudo docker run -t -i -d -v /test --name test ubuntu:14.04 echo hello
使用--volumes-from选项在另一个容器中挂载 /test 卷。不管 test 容器是否运行,其它容器都可以挂载该容器数据卷,当然如果只是单独的数据卷是没必要运行容器的。
$ sudo docker run -t -i -d --volumes-from test --name test1 ubuntu:14.04 /bin/bash
添加另一个容器
$ sudo docker run -t -i -d --volumes-from test --name test2 ubuntu:14.04 /bin/bash
也可以继承其它挂载有 /test 卷的容器
$ sudo docker run -t -i -d --volumes-from test1 --name test3 ubuntu:14.04 /bin/bash
3. 备份、恢复或迁移数据卷
备份
$ sudo docker run --rm --volumes-from test -v $(pwd):/backup ubuntu:14.04 tar cvf /backup/test.tar /test tar: Removing leading `/' from member names /test/ /test/b /test/d /test/c /test/a
启动一个新的容器并且从test容器中挂载卷,然后挂载当前目录到容器中为 backup,并备份 test 卷中所有的数据为 test.tar,执行完成之后删除容器--rm,此时备份就在当前的目录下,名为test.tar。
$ ls # 宿主机当前目录下产生了 test 卷的备份文件 test.tar test.tar
恢复
你可以恢复给同一个容器或者另外的容器,新建容器并解压备份文件到新的容器数据卷
$ sudo docker run -t -i -d -v /test --name test4 ubuntu:14.04 /bin/bash $ sudo docker run --rm --volumes-from test4 -v $(pwd):/backup ubuntu:14.04 tar xvf /backup/test.tar -C /
# 恢复之前的文件到新建卷中,执行完后自动删除容器 test/ test/b test/d test/c test/a
4.删除 Volumes
Volume 只有在下列情况下才能被删除:
- docker rm -v删除容器时添加了-v选项
- docker run --rm运行容器时添加了--rm选项
否则,会在/var/lib/docker/vfs/dir目录中遗留很多不明目录。
参考文档:
② 链接容器
docker 允许把多个容器连接在一起,相互交互信息。docker 链接会创建一种容器父子级别的关系,其中父容器可以看到其子容器提供的信息。
1. 容器命名
在创建容器时,如果不指定容器的名字,则默认会自动创建一个名字,这里推荐给容器命名:
- 1、给容器命名方便记忆,如命名运行 web 应用的容器为 web
- 2、为 docker 容器提供一个参考,允许方便其他容器调用,如把容器 web 链接到容器 db
可以通过--name选项给容器自定义命名:
$ sudo docker run -d -t -i --name test ubuntu:14.04 bash $ sudo docker inspect --format="{{ .Nmae }}" test /test
注:容器名称必须唯一,即你只能命名一个叫test的容器。如果你想复用容器名,则必须在创建新的容器前通过docker rm删除旧的容器或者创建容器时添加--rm选项。
2 链接容器
链接允许容器间安全通信,使用--link选项创建链接。
$ sudo docker run -d --name db training/postgres
基于 training/postgres 镜像创建一个名为 db 的容器,然后下面创建一个叫做 web 的容器,并且将它与 db 相互连接在一起
$ sudo docker run -d -P --name web --link db:db training/webapp python app.py
--link <name or id>:alias选项指定链接到的容器。
查看 web 容器的链接关系:
$ sudo docker inspect -f "{{ .HostConfig.Links }}" web [/db:/web/db]
可以看到 web 容器被链接到 db 容器为/web/db,这允许 web 容器访问 db 容器的信息。
容器之间的链接实际做了什么?一个链接允许一个源容器提供信息访问给一个接收容器。在本例中,web 容器作为一个接收者,允许访问源容器 db 的相关服务信息。Docker 创建了一个安全隧道而不需要对外公开任何端口给外部容器,因此不需要在创建容器的时候添加-p或-P指定对外公开的端口,这也是链接容器的最大好处,本例为 PostgreSQL 数据库。
Docker 主要通过以下两个方式提供连接信息给接收容器:
- 环境变量
- 更新/etc/hosts文件
环境变量
当两个容器链接,Docker 会在目标容器上设置一些环境变量,以获取源容器的相关信息。
首先,Docker 会在每个通过--link选项指定别名的目标容器上设置一个<alias>_NAME环境变量。如果一个名为 web 的容器通过--link db:webdb被链接到一个名为 db 的数据库容器,那么 web 容器上会设置一个环境变量为WEBDB_NAME=/web/webdb.
以之前的为例,Docker 还会设置端口变量:
$ sudo docker run --rm --name web2 --link db:db training/webapp env . . . DB_NAME=/web2/db DB_PORT=tcp://172.17.0.5:5432 DB_PORT_5432_TCP=tcp://172.17.0.5:5432 # <name>_PORT_<port>_<protocol> 协议可以是 TCP 或 UDP DB_PORT_5432_TCP_PROTO=tcp DB_PORT_5432_TCP_PORT=5432 DB_PORT_5432_TCP_ADDR=172.17.0.5 . . .
注:这些环境变量只设置给容器中的第一个进程,类似一些守护进程 (如 sshd ) 当他们派生 shells 时会清除这些变量
更新/etc/hosts文件
除了环境变量,Docker 会在目标容器上添加相关主机条目到/etc/hosts中,上例中就是 web 容器。
$ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash root@aed84ee21bde:/opt/webapp# cat /etc/hosts 172.17.0.7 aed84ee21bde . . . 172.17.0.5 db
/etc/host文件在源容器被重启之后会自动更新 IP 地址,而环境变量中的 IP 地址则不会自动更新的。
③ 构建私有库
Docker 官方提供了 docker registry 的构建方法 docker-registry
1. 快速构建
快速构建 docker registry 通过以下两步:
- 安装 docker
- 运行 registry:docker run -p 5000:5000 registry
这种方法通过 Docker hub 使用官方镜像 official image from the Docker hub
2.不使用容器构建 registry
安装必要的软件
$ sudo apt-get install build-essential python-dev libevent-dev python-pip liblzma-dev
配置 docker-registry
sudo pip install docker-registry
或者 使用 github clone 手动安装
$ git clone https://github.com/dotcloud/docker-registry.git $ cd docker-registry/ $ cp config/config_sample.yml config/config.yml $ mkdir /data/registry -p $ pip install .
运行
docker-registry
高级启动方式 [不推荐]
使用gunicorn控制:
gunicorn -c contrib/gunicorn_config.py docker_registry.wsgi:application
或者对外监听开放
gunicorn --access-logfile - --error-logfile - -k gevent -b 0.0.0.0:5000 -w 4 --max-requests 100 docker_registry.wsgi:application
3. 提交指定容器到私有库
$ docker tag ubuntu:12.04 私有库IP:5000/ubuntu:12.04 $ docker push 私有库IP:5000/ubuntu
更多的配置选项推荐阅读官方文档: