zoukankan      html  css  js  c++  java
  • 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 模板文件

    详细参考

  • 相关阅读:
    Dora.Interception,为.NET Core度身打造的AOP框架 [3]:多样化拦截器应用方式
    Dora.Interception,为.NET Core度身打造的AOP框架 [2]:以约定的方式定义拦截器
    Dora.Interception,为.NET Core度身打造的AOP框架 [1]:更加简练的编程体验
    TechEmpower最新一轮的性能测试出炉,ASP.NET Core依旧表现不俗
    [文章汇总]ASP.NET Core框架揭秘[最近更新:2018/10/31]
    依赖注入[8]: .NET Core DI框架[服务消费]
    依赖注入[7]: .NET Core DI框架[服务注册]
    依赖注入[6]: .NET Core DI框架[编程体验]
    依赖注入[5]: 创建一个简易版的DI框架[下篇]
    依赖注入[4]: 创建一个简易版的DI框架[上篇]
  • 原文地址:https://www.cnblogs.com/cuchadanfan/p/6307615.html
Copyright © 2011-2022 走看看