zoukankan      html  css  js  c++  java
  • docker容器互联,实现目录、服务共享

    一、需求

    docker使服务之间实现容器隔离,比如Javaweb项目前端、后端、数据库、数据库后台,分别把它们部署在不同的容器里面,实现隔离。但服务和服务之间也有互访的需求,这就涉及到容器网络和容器互联挂载访问机制的内容。

    容器是基于镜像创建的,最后的容器文件系统包括镜像的只读层+可写层,容器中的进程操作的数据持久化都是保存在容器的可写层上。一旦容器删除后,这些数据就没了,除非我们人工备份下来(或者基于容器创建新的镜像)。能否可以让容器进程持久化的数据保存在主机上呢?这样即使容器删除了,数据还在。

    docker本身提供了一种机制,可以将主机上的某个目录与容器的某个目录(称为挂载点、或者叫卷)关联起来,容器上的挂载点下的内容就是主机的这个目录下的内容,这类似linux系统下mount的机制。 这样的话,我们修改主机上该目录的内容时,不需要同步容器,对容器来说是立即生效的。挂载点可以让多个容器共享。

    二、通过docker run命令

     1、运行命令:

     # docker run --name node1 -h nodex -v /home/upload/:/data -d -i -t centos /bin/bash

    其中的 -v 标记 在容器中设置了一个挂载点 /data(就是容器中的一个目录),并将主机上的 /home/upload/ 目录中的内容关联到 /data下。

    这样在容器中对/data目录下的操作,还是在主机上对/home/upload/的操作,都是完全实时同步的,因为这两个目录实际都是指向主机目录。

    通过docker inspect 命令查看目录对应关系

    # docker inspect node1

    [
        {
            "Id": "d1c5d9eb3838c724b597db428ce26e72cfc667fbefb0ed712dbbaef5f374070f",
    .............................
     "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/home/upload",
                    "Destination": "/data",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                }
            ],
    ...........................

    2、运行命令:

    # docker run --name node2 -h nodex -v /data -d -i -t centos /bin/bash

    上面-v的标记只设置了容器的挂载点,并没有指定关联的主机目录。这时docker会自动绑定主机上的一个目录。通过docker inspect 命令可以查看到。

    # docker inspect node2

    [
        {
            "Id": "d1c5d9eb3838c724b597db428ce26e72cfc667fbefb0ed712dbbaef5f374070f",
    .............................
    "Mounts": [
                {
                    "Type": "volume",
                    "Name": "d04353ed38845a54a2bd5909b82c470fe644391626f877644e9580aba22a3a12",
                    "Source": "/var/lib/docker/volumes/d04353ed38845a54a2bd5909b82c470fe644391626f877644e9580aba22a3a12/_data",
                    "Destination": "/data",
                    "Driver": "local",
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                }
            ],
    ...........................

    上面 Mounts下的每条信息记录了容器上一个挂载点的信息,"Destination" 值是容器的挂载点,"Source"值是对应的主机目录。

    可以看出这种方式对应的主机目录是自动创建的,其目的不是让在主机上修改,而是让多个容器共享。

    三、通过dockerfile创建挂载点

    上面介绍的通过docker run命令的-v标识创建的挂载点只能对创建的容器有效。

    通过dockerfile的 VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点。

    还有一个区别是,通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。

    # cat Dockerfile

    下面的dockfile文件通过VOLUME指令指定了两个挂载点 /data1 和 /data2

    #test
    FROM centos
    MAINTAINER djl
    VOLUME ["/data1","/data2"]

    # docker build -t test .

    [root@localhost ~]# docker build -t test .
    Sending build context to Docker daemon 28.77 MB
    Step 1/3 : FROM centos
     ---> 9f38484d220f
    Step 2/3 : MAINTAINER djl
     ---> Running in d14672dadf87
     ---> 602a4b8e796d
    Removing intermediate container d14672dadf87
    Step 3/3 : VOLUME /data1 /data2
     ---> Running in 30b586d5aaf4
     ---> f51b774e7869
    Removing intermediate container 30b586d5aaf4
    Successfully built f51b774e7869

    查看构建的镜像

    # docker images

    [root@localhost ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    test                latest              f51b774e7869        2 minutes ago       202 MB
    centos              latest              9f38484d220f        4 months ago        202 MB

    运行一个容器

    # docker run --name node3 -h nodex -d -i -t test /bin/bash

    [root@localhost ~]# docker run --name node3 -h nodex -d -i -t test /bin/bash
    6fb05f94a368e05dd96e2f42432f1e4c0dcad1bd6b726079c69fba0625783c38
    [root@localhost ~]#
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    6fb05f94a368        test                "/bin/bash"         8 seconds ago       Up 7 seconds                            node3
    f2bf65a82acc        centos              "/bin/bash"         About an hour ago   Up About an hour                        node1
    d1c5d9eb3838        centos              "/bin/bash"         2 hours ago         Up 2 hours                              node2

    我们通过docker inspect 查看通过该dockerfile创建的镜像生成的容器,可以看到如下信息

    # docker inspect node3

    [
        {
            "Id": "d1c5d9eb3838c724b597db428ce26e72cfc667fbefb0ed712dbbaef5f374070f",
    .............................
    "Mounts": [
                {
                    "Type": "volume",
                    "Name": "cc2fcaccae2dca5021d82d4d581e1f500816a96745237527d4fa7925a2061e04",
                    "Source": "/var/lib/docker/volumes/cc2fcaccae2dca5021d82d4d581e1f500816a96745237527d4fa7925a2061e04/_data",
                    "Destination": "/data1",
                    "Driver": "local",
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                },
                {
                    "Type": "volume",
                    "Name": "2f7419b960ae0a3f7be58875f5021312b181fdad72e2c7390b2bb7aab7d06b24",
                    "Source": "/var/lib/docker/volumes/2f7419b960ae0a3f7be58875f5021312b181fdad72e2c7390b2bb7aab7d06b24/_data",
                    "Destination": "/data2",
                    "Driver": "local",
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                }
            ],
    ...........................

    可以看到两个挂载点的信息。

    四、容器共享卷(挂载点)

     下面我们创建另一个容器可以和node3共享 /data1 和 /data2卷 ,这是在 docker run中使用 --volumes-from标记,如:

    1、可以是来源不同镜像,如:

    # docker run --name node4 -itd --volumes-from node3 centos /bin/bash

    [root@localhost ~]# docker run --name node4 -itd --volumes-from node3 centos /bin/bash
    ced022f71608c81fd2d689861809b033996351e4dc23c210eaeda675ff28a31b
    [root@localhost ~]#
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    ced022f71608        centos              "/bin/bash"         3 seconds ago       Up 2 seconds                            node4
    6fb05f94a368        test                "/bin/bash"         12 minutes ago      Up 12 minutes                           node3
    f2bf65a82acc        centos              "/bin/bash"         2 hours ago         Up 2 hours                              node1
    d1c5d9eb3838        centos              "/bin/bash"         2 hours ago         Up 2 hours                              node2

    验证:

    [root@localhost ~]# docker exec node3 ls /
    anaconda-post.log
    bin
    data1
    data2
    dev
    etc
    home
    lib
    lib64
    media
    mnt
    opt
    proc
    root
    run
    sbin
    srv
    sys
    tmp
    usr
    var
    [root@localhost ~]# docker exec node4 ls /
    anaconda-post.log
    bin
    data1
    data2
    dev
    etc
    home
    lib
    lib64
    media
    mnt
    opt
    proc
    root
    run
    sbin
    srv
    sys
    tmp
    usr
    var

    2、也可以是同一镜像,如:

    # docker run --name node5 -itd --volumes-from node3 test /bin/bash

    [root@localhost ~]# docker run --name node5 -itd --volumes-from node3 test /bin/bash
    e6a2584eab2cce5b678f432d8eb48a762e5b1b2d57bcd76ee48f121c51ff282d
    [root@localhost ~]#
    [root@localhost ~]# docker exec node5 ls /
    anaconda-post.log
    bin
    data1
    data2
    dev
    etc
    home
    lib
    lib64
    media
    mnt
    opt
    proc
    root
    run
    sbin
    srv
    sys
    tmp
    usr
    var

    五、最佳实践:数据容器

    如果多个容器需要共享数据(如持久化数据库、配置文件或者数据文件等),可以考虑创建一个特定的数据容器,该容器有1个或多个卷。

    其它容器通过--volumes-from 来共享这个数据容器的卷。

    因为容器的卷本质上对应主机上的目录,所以这个数据容器也不需要启动。

    # docker run --name dbdata test echo "data container"

    [root@localhost ~]# docker run --name dbdata test echo "data container"
    data container
    [root@localhost ~]#
    [root@localhost ~]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
    ac04a4f5d1ab        test                "echo 'data contai..."   9 seconds ago       Exited (0) 9 seconds ago                       dbdata
    e6a2584eab2c        test                "/bin/bash"              8 minutes ago       Up 8 minutes                                   node5
    ced022f71608        centos              "/bin/bash"              16 minutes ago      Up 16 minutes                                  node4
    6fb05f94a368        test                "/bin/bash"              28 minutes ago      Up 28 minutes                                  node3
    f2bf65a82acc        centos              "/bin/bash"              2 hours ago         Up 2 hours                                     node1
    d1c5d9eb3838        centos              "/bin/bash"              3 hours ago         Up 3 hours                                     node2
    [root@localhost ~]# docker start dbdata
    dbdata
    [root@localhost ~]#
    [root@localhost ~]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
    ac04a4f5d1ab        test                "echo 'data contai..."   58 seconds ago      Exited (0) 4 seconds ago                       dbdata
    e6a2584eab2c        test                "/bin/bash"              9 minutes ago       Up 9 minutes                                   node5
    ced022f71608        centos              "/bin/bash"              16 minutes ago      Up 16 minutes                                  node4
    6fb05f94a368        test                "/bin/bash"              29 minutes ago      Up 29 minutes                                  node3
    f2bf65a82acc        centos              "/bin/bash"              2 hours ago         Up 2 hours                                     node1
    d1c5d9eb3838        centos              "/bin/bash"              3 hours ago         Up 3 hours                                     node2

    说明:有个卷,容器之间的数据共享比较方便,但也有很多问题需要解决,如权限控制、数据的备份、卷的删除等。

    参考博客:

    docker学习笔记18:Dockerfile 指令 VOLUME 介绍

    Docker容器数据卷-Volume小结

  • 相关阅读:
    只打开一次浏览器,生成html测试报告<小紧张中......>
    hadoop学习第四天-Writable和WritableComparable序列化接口的使用&&MapReduce中传递javaBean的简单例子
    hadoop学习第三天-MapReduce介绍&&WordCount示例&&倒排索引示例
    hadoop学习第二天-了解HDFS的基本概念&&分布式集群的搭建&&HDFS基本命令的使用
    hadoop学习第一天-hadoop初步环境搭建&伪分布式计算配置(详细)
    大三了,写写博客
    方向问题
    第一天注册博客
    jquery跨域请求事例
    ECharts学习记录
  • 原文地址:https://www.cnblogs.com/djlsunshine/p/11284463.html
Copyright © 2011-2022 走看看