Docker學習筆記(四)Docker數據持久化

一、容器與宿主機共享數據:

上面講到的兩種類型的數據卷(data volume)。他們均可實現在容器和宿主機之間共享數據,但方式有所區別:
對於bind mount,直接在啓動容器時將宿主機目錄掛載到容器指定的目錄。docker managed volume就要麻煩點,由於volume存在於宿主機中,在啓動容器時才生成,所以需要將數據複製到volume中。
除此之外,我們可以使用docker cp命令,將宿主機中的數據複製到容器中:
[root@docker ~]# docker cp index.html e19052f33d61:/usr/share/nginx/html/index2.html
[root@docker ~]# docker exec -it nginx bash
root@e19052f33d61:/# ls /usr/share/nginx/html/
50x.html index.html index2.html
root@e19052f33d61:/#
docker cp命令不可以覆蓋容器正在使用的文件。

二、容器與容器之間共享數據:

容器之間共享數據,第一種方法是使用bind mount方式,我們把數據放在bind mount的源目錄中,掛載到多個容器中。
以nginx容器爲例,我們啓動三個nginx容器,分別爲1,2和3,並且把index.html掛載到三個容器:

[root@docker ~]# docker run --name nginx1 -d -P \
-v ~/index.html:/usr/share/nginx/html/index.html docker.io/nginx
20a9c8db433a842efdc264e689788a049b9e0612709f134157887dbc8b5b0b6c
[root@docker ~]# docker run --name nginx2 -d -P \
-v ~/index.html:/usr/share/nginx/html/index.html docker.io/nginx
97173f107ac65631bb9572bb74000c39560b4d22a476fe07efc0f4fa11699340
[root@docker ~]# docker run --name nginx3 -d -P \
-v ~/index.html:/usr/share/nginx/html/index.html docker.io/nginx
e69772dc9ac23155c869f0d6d0048c11b95535f5adc4d552e8c246d901c03964

測試訪問容器:

[root@docker ~]# curl 127.0.0.1:32770
111111111111111111
[root@docker ~]# curl 127.0.0.1:32771
111111111111111111
[root@docker ~]# curl 127.0.0.1:32772
111111111111111111

更新本地的index.html後再訪問容器:

[root@docker ~]# echo "update for website" > index.html 
[root@docker ~]# cat index.html 
update for website
[root@docker ~]# curl 127.0.0.1:32772
update for website
[root@docker ~]# curl 127.0.0.1:32771
update for website
[root@docker ~]# curl 127.0.0.1:32770
update for website
[root@docker ~]#

另一種容器之間共享數據的方法是使用volume container。

三、volume container共享數據:

volume container是專門爲其他容器提供volume的容器,該容器不需要是運行狀態,他提供的卷可以是bind mount,也可以是docker managed volume。下面我們來創建一個volume container:

[root@docker data]#  docker create --name vc_data \
> -v /data/nginx/html:/usr/share/nginx/html \
> -v /other/useful/tools \
> docker.io/nginx
05cf0bbd2560b478e298008c370f9c60f45a7b2e97e2b218e1e3328397c3ba6b
[root@docker data]#

我們使用的是docker create命令,而不是docker run,是因爲我們上面提到volume container只提供數據,本身不需要運行。
上面的volume containermount了兩個volume:
bind mount,存放web server的靜態文件;
docker managed volume,存放工具。
通過docker inspect可以查看這兩個volume:

"Mounts": [
    {
        "Type": "bind",
        "Source": "/data/nginx/html",
        "Destination": "/usr/share/nginx/html",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    },
    {
        "Type": "volume",
        "Name": "db7000f42661413d5b4a151d99252475c3ab3a9271177d38f338e22dec040f28",
        "Source": "/var/lib/docker/volumes/db7000f42661413d5b4a151d99252475c3ab3a9271177d38f338e22dec040f28/_data",
        "Destination": "/other/useful/tools",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    }
],

其他容器可以使用 --volumes-from參數使用vc_data這個volume container:

[root@docker data]# docker run --name nginx1 -d -P --volumes-from vc_data docker.io/nginx
bf180a9b01f5e31ac2e87d92a44aeb156c84fa125b51521ff62b34e24d699f6b
[root@docker data]# docker run --name nginx2 -d -P --volumes-from vc_data docker.io/nginx
400ba04aa783322f7b06540000c6545fa0510751325171546842a78367eec865
[root@docker data]# docker run --name nginx3 -d -P --volumes-from vc_data docker.io/nginx
06898aad50d0e51f448feb32a0fb6517a06c34acf682d35a7b37ad060d59005f

測試訪問容器:

[root@docker data]# curl 127.0.0.1:32773
website in host
[root@docker data]# curl 127.0.0.1:32774
website in host
[root@docker data]# curl 127.0.0.1:32775
website in host

使用docker inspect查看容器有哪些volume:

"Mounts": [
    {
        "Source": "/data/nginx/html",
        "Destination": "/usr/share/nginx/html",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    },
    {
        "Name": "db7000f42661413d5b4a151d99252475c3ab3a9271177d38f338e22dec040f28",
        "Source": "/var/lib/docker/volumes/db7000f42661413d5b4a151d99252475c3ab3a9271177d38f338e22dec040f28/_data",
        "Destination": "/other/useful/tools",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    }
],

可以看出,mount的volume和vc_data配置的完全一致。
總結一下volume container的特點:
與bind mount相比,不必爲每一個容器指定源volume,所有path都愛volume container中定義好了,容器只需與volume container關聯。
使用 volume container的容器,其mount point是一樣的,有利於配置的規範化和標準化,但也有一定的侷限性,使用時需要綜合考慮。

四、data-packed volume container:

在上面的例子中,volume container的數據歸根結底還是在宿主機上,我們現在使用一種方法,將數據存放在容器中,這種方法叫data-packed volume container,原理是創建新的鏡像,把數據打包到新的鏡像中,然後通過docker managed volume 共享:
使用Dockerfile創建鏡像:

FROM busybox:latest
ADD htdocs /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs

ADD 是將宿主機的htdocs的數據複製到鏡像中;
VOLUME的作用與-v一樣,用來創建docker managed volume,mount point是/usr/local/apache2/htdocs,因爲這個目錄就是ADD的目錄,所以數據會直接複製到volume中。
構建鏡像:

[root@docker ~]# docker build -t datapacked .
Sending build context to Docker daemon 28.16 kB
Step 1/3 : FROM busybox:latest
 ---> db8ee88ad75f
Step 2/3 : ADD htdocs /usr/local/apache2/htdocs
 ---> 42c812fe1f9c
Removing intermediate container ab3ff59c6969
Step 3/3 : VOLUME /usr/local/apache2/htdocs
 ---> Running in 15ecb872d6ce
 ---> 0ae7b4f2bf51
Removing intermediate container 15ecb872d6ce
Successfully built 0ae7b4f2bf51

用新的鏡像創建data-packed volume container:

[root@docker ~]# docker create --name vc_data2 datapacked
7ba20b97445f65525b685fee5e5359e9670fe6936379656475e2dd71869068b4

啓動httpd容器,並使用data-packed volume container:

[root@docker ~]# docker run -d -P --volumes-from vc_data2 httpd
0318446eb961776b083831ce0241c9347b751a53f0eb863cf8be16531f932241

啓動後測試訪問httpd容器:

[root@docker ~]# curl 127.0.0.1:32776
datapacked

剛好是我們自定義的index.html。
使用docker inspect 命令查看mount point:

"Mounts": [
    {
        "Name": "3aa7883b8e786564e6cf797cdebcb2078ee830281c6c9910486d0e7c7d6b547d",
        "Source": "/var/lib/docker/volumes/3aa7883b8e786564e6cf797cdebcb2078ee830281c6c9910486d0e7c7d6b547d/_data",
        "Destination": "/usr/local/apache2/htdocs",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    }
],
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章