容器 - 數據存儲(7)

一. 基本說明

    是時候瞭解Docker如何管理數據了。本節主要說明持久化和非持久化,着重持久化html

    數據存儲分爲兩類,持久化和非持久化。
nginx

        ● 持久化數據是須要保存的數據,例如客戶的信息、財務、審計日誌等docker

        ● 非持久化數據是不須要保存的數據緩存

    每一個Docker容器都有本身的非持久化存儲,非持久化存儲自動建立,從屬於容器,生命週期與容器相同。這意味着刪除容器也會刪除所有非持久化數據。簡要說服務應用刪除、重啓後數據丟失,通常在內存緩存中的數據在服務重啓後會丟失bash

    若是須要本身的容器數據保留下來,則須要將數據存儲在捲上。卷與容器是解耦的,從而能夠獨立的建立並管理卷,而且卷並未與任何容器生命週期綁定。簡要說就是把服務應用刪除、中止、重啓後歷史的數據還會存在,以文件形式存儲在磁盤上app

        ● 非持久化數據是在容器內部應用的緩存中,與容器生命週期爲一體
curl

        ● 非持久化數據與容器是相互隔離狀態,不隨容器狀態的改變而改變tcp

二. 數據持久化實現方式

    ● volumeide

        docker自身管理的一種數據持久化方式
測試

    ● mount bind

        數據由人爲自定義管理的一種方式

    下面將對2鍾持久化作一個演示

三. 演示鏡像模板

FROM nginx

MAINTAINER wangtianciEXPOSE 80
# 建立測試鏡像
docker build -f /root/nginx_dockerfile -t nginx:v1 .

四. volume持久化

    1. 如何去查看容器的存儲路徑

        Docker自身提供了"docker volume ls"的指令查看數據卷

[root@doc03 Docker]# docker volume ls
DRIVER              VOLUME NAME
local               2f68c77fb5b576bdb94857f113e7e5d12be7faaecd752a1ce31317655d809028
local               50d1bb27a79fd743b3b69f4be90d21f4a717b34ff5a3b2017493bbf0abeddd2b
local               58441bc7713392eb3c6895ba2aae7e26b03f325ff366a1bde3ee51b0b6f45d1c

        第二列"VOLUME NAME"爲數據存儲目錄名稱,第一眼看很懵,數據存儲對應的是那個容器?若是數據量太小可使用"find"指令去查到關鍵文件從而得到容器數據存儲路徑,當數據量過大時使用"find"不太現實

    2. 如何去自定義容器的存儲路徑

        Docker提供了"-v"參數來自定義容器卷名稱,示範以下

[root@doc03 ~]# docker run -d --name nginx-volume-test1 -p 8888:80 -v test-volume:/usr/share/nginx/html nginx:v1
961213c2f96cca344afabf01c7579184e9edaff9a7d36b667e86a722da49eee2
[root@doc03 Docker]# docker volume ls
DRIVER              VOLUME NAME
local               2f68c77fb5b576bdb94857f113e7e5d12be7faaecd752a1ce31317655d809028
local               50d1bb27a79fd743b3b69f4be90d21f4a717b34ff5a3b2017493bbf0abeddd2b
local               58441bc7713392eb3c6895ba2aae7e26b03f325ff366a1bde3ee51b0b6f45d1c
local               test-volume
[root@doc03 ~]# tree /opt/app/Docker/volumes/test-volume
/opt/app/Docker/volumes/test-volume
└── _data
    ├── 50x.html
    └── index.html

1 directory, 2 files

        能夠看到,在"volumes"目錄下,docker自身建立了"test_volume/_data"目錄,而且nginx主頁文件"index.html"、"50x.html"也在這個目錄下。說明容器內的文件會自動遷移到主機數據存儲目錄中

        -v:host_dirname:container_dirname

            注意:host_dirname 不須要寫絕對路徑,只需指明單獨一個目錄便可,會將數據統一存儲在docker自身的數據管理目錄下

        這裏數據存儲路徑命名得有規範性,如果隨意命名有可能致使環境混亂,筆者建議按照服務的名稱或者是提供業務去命名

    3. 數據卷共享

        建立一個實例"nginx-volume-test1"

[root@doc03 ~]# docker run -d --name nginx-volume-test2 -p 9999:80 -v test-volume:/usr/share/nginx/html nginx:v1
3febe889c87382f1718ef3990d86cd61b59668493f9f5e8d91d6cdba26695691
[root@doc03 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
3febe889c873        nginx:v1            "/docker-entrypoint.…"   6 seconds ago       Up 5 seconds        0.0.0.0:9999->80/tcp   nginx-volume-test2
961213c2f96c        nginx:v1            "/docker-entrypoint.…"   17 seconds ago      Up 17 seconds       0.0.0.0:8888->80/tcp   nginx-volume-test1

          在本地建立一個"test.html"的文件並訪問

echo "nginx data volume test" > test.html && chmod 644 test.html

# 本地請求
[root@doc03 _data]# curl 10.125.7.74:9999/test.html
nginx data volume test
[root@doc03 _data]# curl 10.125.7.74:8888/test.html
nginx data volume test

        注意:這裏得注意文件權限644

    4. 數據卷持久化

        刪除實例"nginx-volume-test2"

[root@doc03 ~]# docker stop nginx-volume-test2
nginx-volume-test2
[root@doc03 ~]# docker rm nginx-volume-test2
nginx-volume-test3
[root@doc03 ~]# tree /opt/app/Docker/volumes/test-volume
/opt/app/Docker/volumes/test-volume
└── _data
    ├── 50x.html
    └── index.html
    └── test.html

        查看"test-volume"數據目錄,文件並未被刪除

        注意:這裏得說明下"/opt/app/Docker/volumes/metadata.db"這個文件,metadata.db,存儲路徑的元數據並非動態更新修改,當目錄已經建立並關聯的容器刪除時,其餘新建的容器沒法使用已經建立過的這個目錄,須要手動刪除歷史使用過的目錄,可以使用"docker volume --help"查看具體使用方式

五. mount bind持久化

    與"volume"不一樣的是,此方式用戶能夠自定義數據掛載路徑

    docker run -d -v host_path:container_path ······

    1. 自定義數據存儲路徑

[root@doc03 Docker]# pwd
/opt/app/Docker
[root@doc03 Docker]# tree Container_data/
Container_data/
0 directories, 0 files

    2. 實例化一個容器    

[root@doc03 Docker]# docker run -d --name nginx-volume-test10 -p 33333:80 -v //opt/app/Docker/Container_data/nginx-volume-test10:/usr/share/nginx/html nginx:v1
2b2a7e4b05b4d0bdefa9f4b6ad32c40a7beadbcbca216bac42103518b97b427b
[root@doc03 Docker]# tree Container_data/
Container_data/
└── nginx-volume-test10

1 directory, 0 files
[root@doc03 Docker]# tree Container_data/nginx-volume-test10/
Container_data/nginx-volume-test10/

        "nginx-volume-test10"數據存儲目錄自動建立,且目錄下不存在nginx主頁文件"50x.html"、"index.html"

    3. 多容器數據卷共享

        建立一個nginx-volume-test11的實例,共享"nginx-volume-test10"文件系統

        在這裏可使用"inspect"去核查2個容器之間數據目錄是否共享

[root@doc03 Docker]# pwd
/opt/app/Docker
# "nginx-volume-test11"使用了"ro"只讀模式
[root@doc03 Docker]# docker run -d --name nginx-volume-test11 -p 44444:80 -v /opt/app/Docker/Container_data/nginx-volume-test10:/usr/share/nginx/html:ro nginx:v1
ca310b2e5076a7340aaa43e1a7737306ce53ffb7dd8d14f90114b3156e467106

        在宿主機上建立訪問主頁

[root@doc03 Docker]# echo "volume shard test" > Container_data/nginx-volume-test10/index.html
[root@doc03 Docker]# chmod 644 Container_data/nginx-volume-test10/index.html

        進入"nginx-volume-test10"並追加"test10"內容,經過"nginx-volume-test10"、"nginx-volume-test11"訪問主頁

[root@doc03 Docker]# docker exec -it nginx-volume-test10 /bin/bash
root@2b2a7e4b05b4:/# cd /usr/share/nginx/html/
root@2b2a7e4b05b4:/usr/share/nginx/html# ls
index.html
root@2b2a7e4b05b4:/usr/share/nginx/html# echo "test10 add content" >> index.html 
root@2b2a7e4b05b4:/usr/share/nginx/html# cat index.html
root@2b2a7e4b05b4:/usr/share/nginx/html# exit
exit
[root@doc03 Docker]# curl http://10.125.7.74:33333
volume shard test
test10 add content
[root@doc03 Docker]# curl http://10.125.7.74:44444
volume shard test
test10 add content

        進入"nginx-volume-test11"嘗試追加內容

[root@doc03 Docker]# docker exec -it nginx-volume-test11 /bin/bash
root@ca310b2e5076:/# cd /usr/share/nginx/html/
root@ca310b2e5076:/usr/share/nginx/html# echo 1 > index.html 
bash: index.html: Read-only file system

        "nginx-volume-test10"、"nginx-volume-test11"測試說明數據已經共享,可是"nginx-volume-test11"因爲設置了"ro"只讀權限,沒有權限作增刪改操做,若是在主機上刪除文件,則2個容器的數據也會刪除

    4. 多容器數據繼承

        指令模型: docker run -itd --name 子容器名稱 --volumes-from  父容器名稱 鏡像名稱 /bin/bash

        建立"nginx-volume-test20"實例

[root@doc03 Docker]# docker run -d --name nginx-volume-test20 -p 60000:80 -v //opt/app/Docker/Container_data/nginx-volume-test20:/usr/share/nginx/html nginx:v1
cda5bd44e77c979ddede127322fca7d5a0abe4997be78a4a8973b0700bceb81d

        以"nginx-volume-test20" 實例爲父容器,建立"nginx-volume-test20.1"子容器

[root@doc03 Docker]# docker run -d --name nginx-volume-test20.1 --volumes-from nginx-volume-test20 nginx:v1
96df84470069a6cb59a1ba160ffd74b1fc0c91f11e60eae9f6d6544a90bf742f

        以"nginx-volume-test20.1" 實例爲父容器,建立"nginx-volume-test20.1.1"子容器  

[root@doc03 Docker]# docker run -d --name nginx-volume-test20.1.1 --volumes-from nginx-volume-test20.1 nginx:v1
4224e166eade5b8348736d31d9f9e3146630bfa92772aea78522a6a323075ec5

        nginx-volume-test20.1 繼承 nginx-volume-test20、nginx-volume-test20.1.1 繼承 nginx-volume-test20.1,繼承方自動建立目錄

多容器數據場景使用的很少,這裏不作過多的演示,只說明我的結論

            ● 父子容器磁盤共享,全部容器都可對容器卷作讀寫操做

            ● 刪除父子容器中的某個節點,不會對數據形成損壞、丟失

六. volume、mount bind2者的特色

    1. volume

        ● 數據存儲路徑由docker程序自身管理

        ● container 內部目錄數據統一在 "$volumes/_data"路徑下

        ● container內數據有文件,則會統一同步至 "$volumes/_data"路徑下

        ● 多個container 使用相同的 "$volumes/_data"時,全部數據共享

        ● 即便容器被銷燬,數據也不會丟失

        ● 當本地路徑不存在時,會自動建立

        ● 權限控制,當有多個容器共享統一數據時,能夠針對部分容器目錄只有只讀權限(不作演示,test-volume3:/usr/share/nginx/html:ro),此限制只針對容器

        ● 實例可移植性強,數據存儲路徑有docker自身管理

        ● -v參數定義的名稱一定是目錄,不多是文件

    2. bind mount

        ● 數據存儲路徑由用戶自身去定義

        ● container內部有數據文件時,不會遷移至數據存儲目錄

        ● 多個container 使用相同的數據存儲目錄時,全部數據共享

        ● 即便容器被銷燬,數據也不會丟失

        ● 當本地路徑不存在時,會自動建立

        ● 權限控制,當有多個容器共享統一數據時,能夠針對部分容器目錄只有只讀權限(不作演示,test-volume3:/usr/share/nginx/html:ro),此限制只針對容器

        ● 可移植性差,由於有用戶自定義的host_path參數

        ● -v 參數便可指明目錄也能夠指明文件,當指明文件時此文件必須存在

相關文章
相關標籤/搜索