Docker扩展.md

逻辑卷 Volume

数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷可以在容器之间共享和重用

  • 对数据卷的修改会立马生效

  • 对数据卷的更新,不会影响镜像

  • 数据卷默认会一直存在,即使容器被删除

*注意:数据卷的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的数据卷。

创建

Volume可以使用以下两种方式创建:

  • 在Dockerfile中指定VOLUME /some/dir

  • 执行docker run -v /some/dir命令来指定

无论哪种方式都是做了同样的事情。它们告诉Docker在主机上创建一个目录(默认情况下是在/var/lib/docker下),然后将其挂载到指定的路径(例子中是:/some/dir)。当删除使用该Volume的容器时,Volume本身不会受到影响,它可以一直存在下去。如果在容器中不存在指定的路径,那么该目录将会被自动创建。

命令行创建

创建一个容器,将容器内的/data 目录定义为volume:

# docker run -it --name test1 -v /data centos:6.8 /bin/bash

上面的例子中我们定义了容器内的data 目录是volume ,之后我们可以通过inspect 命令查看该容器所对应的主机目录:

# docker inspect test1
......
"Mounts": [
            {
                "Name": "a77ca832a4c4544a2036a37e31ff1e6f25a3b07da55acc7d82d733885f4c8f59",
                "Source": "/var/lib/docker/volumes/a77ca832a4c4544a2036a37e31ff1e6f25a3b07da55acc7d82d733885f4c8f59/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
......

通过上面可以看到volume的对应关系,之后我们在容器中的/data 文件创建文件进行测试:

[root@e408dd974f11 /]# echo "This is test file" >/data/test
# cat /var/lib/docker/volumes/a77ca832a4c4544a2036a37e31ff1e6f25a3b07da55acc7d82d733885f4c8f59/_data/test 
This is test file

通过上面的例子我们可以发现volume就是将主机与容器之间类是通过mount 的方式进行工作的。那么我们要是删除容器默认是不会删除volume的,除非在删除时指定了-v 选项。但是如果我们创建volume 中使用的是主机的目录则即使指定了-v选项也不会删除创建时与主机想关联的volume。

如果你想在容器中使用主机上的某个目录,你可以通过其它的参数来指定:

# ls /root/docker_test
Dockerfile  centos  nginx_1.10.0.tar  ubuntu.tar  ubuntu_test.tar
# docker run -it --name test2 -v /root/docker_test:/opt centos:6.8 /bin/bash
[root@dddf99818ca3 /]# ls /opt/
Dockerfile  centos  nginx_1.10.0.tar  ubuntu.tar  ubuntu_test.tar
[root@dddf99818ca3 /]# rm -f /opt/ubuntu_test.tar 
[root@dddf99818ca3 /]# ls /opt/
Dockerfile  centos  nginx_1.10.0.tar  ubuntu.tar
# ls /root/docker_test/
centos  Dockerfile  nginx_1.10.0.tar  ubuntu.tar

上面我们是将主机的/root/docker_test 关联至容器的/opt 目录中,如果我们在容器对该目录进行操作与主机中对其的操作效果相同。

创建volume时我们还可以指定volume的属性,例如下面我们创建的volume是以只读的形式创建,那么就不能删除volume中的内容:

# docker run -it --name test3 -v /root/docker_test:/opt:ro centos:6.8 /bin/bash
[root@5a23c1fd2872 /]# ls /opt/
Dockerfile  centos  nginx_1.10.0.tar  ubuntu.tar
[root@5a23c1fd2872 /]# rm -f /opt/ubuntu.tar 
rm: cannot remove `/opt/ubuntu.tar': Read-only file system

前面说创建容器时,volume 是指定为主机的目录那么在删除时即使是使用了-v选项也是不会删除主机的目录的:

# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
5a23c1fd2872        centos:6.8          "/bin/bash"         3 minutes ago       Up 3 minutes                            test3
dddf99818ca3        centos:6.8          "/bin/bash"         9 minutes ago       Up 21 seconds                           test2
# docker rm -vf test3
test3
# ls /root/docker_test/
centos  Dockerfile  ubuntu.tar

注意:即使是不会删除主机的目录,我们还是不要这么操作,删除文件前一定要慎重!

数据共享

如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。
创建一个名为 dbdata 的数据卷容器:

# docker  run -d -v /data --name dbdata centos:6.8
# docker inspect dbdata
......
 "Mounts": [
            {
                "Name": "17a47697a796cc31a15a0d817ff334484c37449795eb11252fea095e9e2eee78",
                "Source": "/var/lib/docker/volumes/17a47697a796cc31a15a0d817ff334484c37449795eb11252fea095e9e2eee78/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
......
# echo 'This is dbdata!' > /var/lib/docker/volumes/17a47697a796cc31a15a0d817ff334484c37449795eb11252fea095e9e2eee78/_data/test
# docker run -it -d --name db1 --volumes-from dbdata centos:6.8 /bin/bash
# docker run -it -d --name db2 --volumes-from dbdata centos:6.8 /bin/bash
# docker exec -it db1 bash
[root@344fe47548b3 /]# cat /data/test 
This is dbdata!

使用数据容器注意点:

  • 不要运行数据容器,这纯粹是在浪费资源。

  • 不要为了数据容器而使用“最小的镜像”,如busybox或scratch,只使用数据库镜像本身就可以了。你已经拥有该镜像,所以并不需要占用额外的空间。

  • 使用 --volumes-from 参数所挂载数据卷的容器自己并不需要保持在运行状态。

网络

bridge模式网络

在该模式(见下图)中,Docker守护进程创建了一个虚拟以太网桥docker0,附加在其上的任何网卡之间都能自动转发数据包。默认情况下,守护进程会创建一对对等接口,将其中一个接口设置为容器的eth0接口,另一个接口放置在宿主机的命名空间中,从而将宿主机上的所有容器都连接到这个内部网络上。同时,守护进程还会从网桥的私有地址空间中分配一个IP地址和子网给该容器。

# docker run -d --name test -P --net bridge nginx:1.10.0
# docker port test
443/tcp -> 0.0.0.0:32768
80/tcp -> 0.0.0.0:32769

因为bridge模式是Docker的默认设置,所以你也可以使用docker run -d -P nginx:1.9.1。如果你没有使用-P(发布该容器暴露的所有端口)或者-p
host_port:container_port(发布某个特定端口),IP数据包就不能从宿主机之外路由到容器中。

 


 

 

host模式网络

该模式将禁用Docker容器的网络隔离。因为容器共享了宿主机的网络命名空间,直接暴露在公共网络中。因此,你需要通过端口映射(port mapping)来进行协调。
在下图中,我们可以看到:当使用host模式网络时,容器实际上继承了宿主机的IP地址。该模式比bridge模式更快(因为没有路由开销),但是它将容器直接暴露在公共网络中,是有安全隐患的。

 


 

 

container模式网络

该模式会重用另一个容器的网络命名空间。通常来说,当你想要自定义网络栈时,该模式是很有用的。实际上,该模式也是Kubernetes使用的网络模式。

# docker ps 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
a4d57df60bf0        nginx:1.10.0        "nginx -g 'daemon off"   8 minutes ago       Up 8 minutes        0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp   romantic_snyder
# docker exec -it romantic_snyder ip addr show
......
223: eth0@if224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever
# docker run -it --net=container:romantic_snyder ubuntu:14.04 ip addr show
......
223: eth0@if224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever

结果(上面的例子)显示:第二个容器使用了--net=container参数,因此和第一个容器romantic_snyder具有相同的IP地址172.17.0.2。

none模式网络

该模式将容器放置在它自己的网络栈中,但是并不进行任何配置。实际上,该模式关闭了容器的网络功能,在以下两种情况下是有用的:容器并不需要网络(例如只需要写磁盘卷的批处理任务);

http://dockone.io/article/1261
https://opskumu.gitbooks.io/docker/content/chapter6.html

docker-compose

Docker Compose是一个用来定义和运行复杂应用的Docker工具。使用Compose,你可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作。

二进制包安装

官方定义编译好二进制包,供大家使用。这些发布的二进制包可以在 docker-compose 页面找到。
这些二进制文件,下载后直接放到执行路径下,并添加执行权限即可。
例如,在 Linux 平台上。

$ sudo curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
$ sudo chmod a+x /usr/local/bin/docker-compose

命令说明

对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服务都会受到命令影响。
执行 docker-compose [COMMAND] --help 或者 docker-compose help [COMMAND] 可以查看具体某个命令的使用格式。

Compose 命令的基本的使用格式是

docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]

命令选项

  • -f, --file FILE 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定。

  • -p, --project-name NAME 指定项目名称,默认将使用所在目录名称作为项目名。

  • --x-networking 使用 Docker 的可拔插网络后端特性(需要 Docker 1.9 及以后版本)。

  • --x-network-driver DRIVER 指定网络后端的驱动,默认为 bridge(需要 Docker 1.9 及以后版本)。

build

构建(重新构建)项目中的服务容器。
格式为 docker-compose build [options] [SERVICE...]
服务容器一旦构建后,将会带上一个标记名,例如对于 web 项目中的一个 db 容器,可能是 web_db。
可以随时在项目目录下运行 docker-compose build 来重新构建服务。
选项包括:

  • --force-rm 删除构建过程中的临时容器。

  • --no-cache 构建镜像过程中不使用 cache(这将加长构建过程)。

  • --pull 始终尝试通过 pull 来获取更新版本的镜像。

kill

通过发送 SIGKILL 信号来强制停止服务容器。
格式为 docker-compose kill [options] [SERVICE...]
支持通过 -s 参数来指定发送的信号,例如通过如下指令发送 SIGINT 信号。

logs

查看服务容器的输出。默认情况下,docker-compose 将对不同的服务输出使用不同的颜色来区分。可以通过 --no-color 来关闭颜色。
格式为 docker-compose logs [options] [SERVICE...]

pause

暂停一个服务容器。
格式为 docker-compose pause [SERVICE...]

port

打印某个容器端口所映射的公共端口。
格式为 docker-compose port [options] SERVICE PRIVATE_PORT
选项:

  • --protocol=proto 指定端口协议,tcp(默认值)或者 udp。

  • --index=index 如果同一服务存在多个容器,指定命令对象容器的序号(默认为 1)。

ps

列出项目中目前的所有容器。
格式为 docker-compose ps [options] [SERVICE...]
选项:

  • -q 只打印容器的 ID 信息。

pull

拉取服务依赖的镜像。
格式为 docker-compose pull [options] [SERVICE...]
选项:

  • --ignore-pull-failures 忽略拉取镜像过程中的错误。

restart

重启项目中的服务。
格式为 docker-compose restart [options] [SERVICE...]
选项:
-t, --timeout TIMEOUT 指定重启前停止容器的超时(默认为 10 秒)

rm

删除所有(停止状态的)服务容器。推荐先执行 docker-compose stop 命令来停止容器。
格式为 docker-compose rm [options] [SERVICE...]
选项:

  • -f, --force 强制直接删除,包括非停止状态的容器。一般尽量不要使用该选项。

  • -v 删除容器所挂载的数据卷。

run

在指定服务上执行一个命令。
格式为 docker-compose run [options] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...]
例如:

$ docker-compose run ubuntu ping docker.com

将会启动一个 ubuntu 服务容器,并执行 ping docker.com 命令。
默认情况下,如果存在关联,则所有关联的服务将会自动被启动,除非这些服务已经在运行中。
该命令类似启动容器后运行指定的命令,相关卷、链接等等都将会按照配置自动创建。

两个不同点:

  • 给定命令将会覆盖原有的自动运行命令;

  • 不会自动创建端口,以避免冲突。

如果不希望自动启动关联的容器,可以使用 --no-deps 选项,例如

$ docker-compose run --no-deps web python manage.py shell

将不会启动 web 容器所关联的其它容器。

选项:

  • -d 后台运行容器。

  • --name NAME 为容器指定一个名字。

  • --entrypoint CMD 覆盖默认的容器启动指令。

  • -e KEY=VAL 设置环境变量值,可多次使用选项来设置多个环境变量。

  • -u, --user="" 指定运行容器的用户名或者 uid。

  • --no-deps 不自动启动关联的服务容器。

  • --rm 运行命令后自动删除容器,d 模式下将忽略。

  • -p, --publish=[] 映射容器端口到本地主机。

  • --service-ports 配置服务端口并映射到本地主机。

  • -T 不分配伪 tty,意味着依赖 tty 的指令将无法运行。

scale

设置指定服务运行的容器个数。
格式为 docker-compose scale [options] [SERVICE=NUM...]
通过 service=num 的参数来设置数量。例如:

$ docker-compose scale web=3 db=2

将启动 3 个容器运行 web 服务,2 个容器运行 db 服务。

一般的,当指定数目多于该服务当前实际运行容器,将新创建并启动容器;反之,将停止容器。
选项:

  • -t, --timeout TIMEOUT 停止容器时候的超时(默认为 10 秒)。

start

启动已经存在的服务容器。
格式为 docker-compose start [SERVICE...]

stop

停止已经处于运行状态的容器,但不删除它。通过 docker-compose start 可以再次启动这些容器。
格式为 docker-compose stop [options] [SERVICE...]
选项:

  • -t, --timeout TIMEOUT 停止容器时候的超时(默认为 10 秒)。

unpause

恢复处于暂停状态中的服务。
格式为 docker-compose unpause [SERVICE...]

up

该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。链接的服务都将会被自动启动,除非已经处于运行状态。可以说,大部分时候都可以直接通过该命令来启动一个项目。
格式为 docker-compose up [options] [SERVICE...]
默认情况,docker-compose up 启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很方便进行调试。

当通过 Ctrl-C 停止命令时,所有容器将会停止。

如果使用 docker-compose up -d,将会在后台启动并运行所有的容器。一般推荐生产环境下使用该选项。

默认情况,如果服务容器已经存在,docker-compose up 将会尝试停止容器,然后重新创建(保持使用 volumes-from 挂载的卷),以保证新启动的服务匹配 docker-compose.yml 文件的最新内容。如果用户不希望容器被停止并重新创建,可以使用 docker-compose up --no-recreate。这样将只会启动处于停止状态的容器,而忽略已经运行的服务。如果用户只想重新部署某个服务,可以使用 docker-compose up --no-deps -d <SERVICE_NAME> 来重新创建服务并后台停止旧服务,启动新服务,并不会影响到其所依赖的服务。

选项:

  • -d 在后台运行服务容器。

  • --no-color 不使用颜色来区分不同的服务的控制台输出。

  • --no-deps 不启动服务所链接的容器。

  • --force-recreate 强制重新创建容器,不能与 --no-recreate 同时使用。

  • --no-recreate 如果容器已经存在了,则不重新创建,不能与 --force-recreate 同时使用。

  • --no-build 不自动构建缺失的服务镜像。

  • -t, --timeout TIMEOUT 停止容器时候的超时(默认为 10 秒)。

Compose 模板文件

详细参考

posted @ 2017-01-19 17:50  ProfiBus  阅读(349)  评论(0编辑  收藏  举报