是時候瞭解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 .
Docker自身提供了"docker volume ls"的指令查看數據卷
[root@doc03 Docker]# docker volume ls DRIVER VOLUME NAME local 2f68c77fb5b576bdb94857f113e7e5d12be7faaecd752a1ce31317655d809028 local 50d1bb27a79fd743b3b69f4be90d21f4a717b34ff5a3b2017493bbf0abeddd2b local 58441bc7713392eb3c6895ba2aae7e26b03f325ff366a1bde3ee51b0b6f45d1c
第二列"VOLUME NAME"爲數據存儲目錄名稱,第一眼看很懵,數據存儲對應的是那個容器?若是數據量太小可使用"find"指令去查到關鍵文件從而得到容器數據存儲路徑,當數據量過大時使用"find"不太現實
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自身的數據管理目錄下
這裏數據存儲路徑命名得有規範性,如果隨意命名有可能致使環境混亂,筆者建議按照服務的名稱或者是提供業務去命名
建立一個實例"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
刪除實例"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"查看具體使用方式
與"volume"不一樣的是,此方式用戶能夠自定義數據掛載路徑
docker run -d -v host_path:container_path ······
[root@doc03 Docker]# pwd /opt/app/Docker [root@doc03 Docker]# tree Container_data/ Container_data/ 0 directories, 0 files
[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"
建立一個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個容器的數據也會刪除
指令模型: 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,繼承方自動建立目錄
多容器數據場景使用的很少,這裏不作過多的演示,只說明我的結論
● 父子容器磁盤共享,全部容器都可對容器卷作讀寫操做
● 刪除父子容器中的某個節點,不會對數據形成損壞、丟失
● 數據存儲路徑由docker程序自身管理
● container 內部目錄數據統一在 "$volumes/_data"路徑下
● container內數據有文件,則會統一同步至 "$volumes/_data"路徑下
● 多個container 使用相同的 "$volumes/_data"時,全部數據共享
● 即便容器被銷燬,數據也不會丟失
● 當本地路徑不存在時,會自動建立
● 權限控制,當有多個容器共享統一數據時,能夠針對部分容器目錄只有只讀權限(不作演示,test-volume3:/usr/share/nginx/html:ro),此限制只針對容器
● 實例可移植性強,數據存儲路徑有docker自身管理
● -v參數定義的名稱一定是目錄,不多是文件
● 數據存儲路徑由用戶自身去定義
● container內部有數據文件時,不會遷移至數據存儲目錄
● 多個container 使用相同的數據存儲目錄時,全部數據共享
● 即便容器被銷燬,數據也不會丟失
● 當本地路徑不存在時,會自動建立
● 權限控制,當有多個容器共享統一數據時,能夠針對部分容器目錄只有只讀權限(不作演示,test-volume3:/usr/share/nginx/html:ro),此限制只針對容器
● 可移植性差,由於有用戶自定義的host_path參數
● -v 參數便可指明目錄也能夠指明文件,當指明文件時此文件必須存在