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小結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM