欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談docker學習之docker數(shù)據(jù)卷(volume)

 更新時間:2017年12月14日 11:46:04   作者:夢_殤  
這篇文章主要介紹了淺談docker學習之docker數(shù)據(jù)卷(volume),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1.什么是數(shù)據(jù)卷volume

為了了解什么是Docker Volume,首先我們需要明確Docker內(nèi)的文件系統(tǒng)是如何工作的。Docker鏡像被存儲在一系列的只讀層。當我們開啟一個容器,Docker讀取只讀鏡像并添加一個讀寫層在頂部。如果正在運行的容器修改了現(xiàn)有的文件,該文件將被拷貝出底層的只讀層到最頂層的讀寫層。在讀寫層中的舊版本文件隱藏于該文件之下,但并沒有被不破壞 - 它仍然存在于鏡像以下。當Docker的容器被刪除,然后重新啟動鏡像時,將開啟一個沒有任何更改的新的容器 - 這些更改會丟失。此只讀層及在頂部的讀寫層的組合被Docker稱為Union File System(聯(lián)合文件系統(tǒng))。
為了能夠保存(持久)數(shù)據(jù)以及共享容器間的數(shù)據(jù),Docker提出了Volumes的概念。很簡單,volumes是目錄(或者文件),它們是外部默認的聯(lián)合文件系統(tǒng)或者是存在于宿主文件系統(tǒng)正常的目錄和文件。

2.為什么使用數(shù)據(jù)卷volume

Docker的鏡像是由一系列的只讀層組合而來,當啟動一個容器的時候,Docker加載鏡像的所有只讀層,并在最上層加入一個讀寫層。這個設計使得Docker可以提高鏡像構建、存儲和分發(fā)的效率,節(jié)省了時間和存儲空間,然而也存在如下問題。

(1)容器中的文件在宿主機上存在形式復雜,不能在宿主機上很方便的對容器中的文件進行訪問

(2)多個容器之間的數(shù)據(jù)無法共享

(3)當刪除容器時,容器產(chǎn)生的數(shù)據(jù)將丟失

為了解決這些問題,Docker引入了數(shù)據(jù)卷(volume)機制。volume是存在一個或多個容器中的特定文件或文件夾,這個目錄能夠獨立于聯(lián)合文件系統(tǒng)的形式在宿主機中存在,并為數(shù)據(jù)的共享與持久提供一下便利。

(1)volume在容器創(chuàng)建時就初始化,在容器運行時就可以使用其中的文件

(2)volume能在不同的容器之間共享和重用

(3)對volume中的數(shù)據(jù)的操作會馬上生效

(4)對volume中數(shù)據(jù)操作不會影響到鏡像本身

(5)volume的生存周期獨立于容器的生存周期,即使刪除容器,volume仍然會存在,沒有任何容器使用的volume也不會被Docker刪除

3.如何使用數(shù)據(jù)卷 

3.1 從容器掛載volume(-v /path)

在使用docker run創(chuàng)建新容器的時候,可以使用-v 標簽為容器添加數(shù)據(jù)卷volume,以下用法是從容器中的某個文件夾創(chuàng)建volume,如果容器中指定的文件夾不存在,會自動生成


在上面的概念中,有說道,宿主機應該會有一個文件夾綁定掛載到容器中的volume掛載點,那默認的宿主機上的文件夾在哪呢,使用docker inspect命令,查看下容器詳情(CRT令起一個SSH終端)

[root@localhost ~]# docker inspect volume-test01 
[ 
 { 
  "Id": "81a74152e6f45a3f780ac7cdc37c9a089814f9a70aad1d27747093ca3c3dae3e", 
  "Created": "2016-08-25T07:48:55.942949334Z", 
  "Path": "/bin/bash", 
  "Args": [], 
  "State": { 
   "Status": "running", 
   "Running": true, 
   "Paused": false, 
   "Restarting": false, 
   "OOMKilled": false, 
   "Dead": false, 
   "Pid": 10199, 
   "ExitCode": 0, 
   "Error": "", 
   "StartedAt": "2016-08-25T07:48:56.777918888Z", 
   "FinishedAt": "0001-01-01T00:00:00Z" 
  }, 
  "Image": "sha256:4fd21defa24c8c07b3689b267a63d563ca0e26ef931b329fc3f3d46efb5bba2d", 
  "ResolvConfPath": "/var/lib/docker/containers/81a74152e6f45a3f780ac7cdc37c9a089814f9a70aad1d27747093ca3c3dae3e/resolv.conf", 
  "HostnamePath": "/var/lib/docker/containers/81a74152e6f45a3f780ac7cdc37c9a089814f9a70aad1d27747093ca3c3dae3e/hostname", 
  "HostsPath": "/var/lib/docker/containers/81a74152e6f45a3f780ac7cdc37c9a089814f9a70aad1d27747093ca3c3dae3e/hosts", 
  "LogPath": "", 
  "Name": "/volume-test01", 
  "RestartCount": 0, 
  "Driver": "devicemapper", 
  "MountLabel": "system_u:object_r:svirt_sandbox_file_t:s0:c47,c332", 
  "ProcessLabel": "system_u:system_r:svirt_lxc_net_t:s0:c47,c332", 
  "AppArmorProfile": "", 
  "ExecIDs": null, 
  "HostConfig": { 
   "Binds": null, 
   "ContainerIDFile": "", 
   "LogConfig": { 
    "Type": "journald", 
    "Config": {} 
   }, 
   "NetworkMode": "default", 
   "PortBindings": {}, 
   "RestartPolicy": { 
    "Name": "no", 
    "MaximumRetryCount": 0 
   }, 
   "VolumeDriver": "", 
   "VolumesFrom": null, 
   "CapAdd": null, 
   "CapDrop": null, 
   "Dns": [], 
   "DnsOptions": [], 
   "DnsSearch": [], 
   "ExtraHosts": null, 
   "GroupAdd": null, 
   "IpcMode": "", 
   "Links": null, 
   "OomScoreAdj": 0, 
   "PidMode": "", 
   "Privileged": false, 
   "PublishAllPorts": false, 
   "ReadonlyRootfs": false, 
   "SecurityOpt": null, 
   "UTSMode": "", 
   "ShmSize": 67108864, 
   "ConsoleSize": [ 
    0, 
    0 
   ], 
   "Isolation": "", 
   "CpuShares": 0, 
   "CgroupParent": "", 
   "BlkioWeight": 0, 
   "BlkioWeightDevice": null, 
   "BlkioDeviceReadBps": null, 
   "BlkioDeviceWriteBps": null, 
   "BlkioDeviceReadIOps": null, 
   "BlkioDeviceWriteIOps": null, 
   "CpuPeriod": 0, 
   "CpuQuota": 0, 
   "CpusetCpus": "", 
   "CpusetMems": "", 
   "Devices": [], 
   "KernelMemory": 0, 
   "Memory": 0, 
   "MemoryReservation": 0, 
   "MemorySwap": 0, 
   "MemorySwappiness": -1, 
   "OomKillDisable": false, 
   "PidsLimit": 0, 
   "Ulimits": null 
  }, 
  "GraphDriver": { 
   "Name": "devicemapper", 
   "Data": { 
    "DeviceId": "29", 
    "DeviceName": "docker-253:0-101330881-9cb32851050b1707022b475489686582a272d883a56a8ff52f3344f56b65639f", 
    "DeviceSize": "10737418240" 
   } 
  }, 
  "Mounts": [ 
   { 
    "Name": "5ddd734c53a38a78a9f739157c63074b4aff736d4045925616d7753402304137", 
    "Source": "/var/lib/docker/volumes/5ddd734c53a38a78a9f739157c63074b4aff736d4045925616d7753402304137/_data", 
    "Destination": "/opt/vol-data", 
    "Driver": "local", 
    "Mode": "", 
    "RW": true, 
    "Propagation": "" 
   } 
  ], 
  "Config": { 
   "Hostname": "81a74152e6f4", 
   "Domainname": "", 
   "User": "", 
   "AttachStdin": true, 
   "AttachStdout": true, 
   "AttachStderr": true, 
   "Tty": true, 
   "OpenStdin": true, 
   "StdinOnce": true, 
   "Env": null, 
   "Cmd": [ 
    "/bin/bash" 
   ], 
   "Image": "test/mycentos:v1.0", 
   "Volumes": { 
    "/opt/vol-data": {} 
   }, 
   "WorkingDir": "", 
   "Entrypoint": null, 
   "OnBuild": null, 
   "Labels": {} 
  }, 
  "NetworkSettings": { 
   "Bridge": "", 
   "SandboxID": "c73841812aab480cf8e6a02071e36951dceb002d7b36f7dc0b38ccd9db833ba5", 
   "HairpinMode": false, 
   "LinkLocalIPv6Address": "", 
   "LinkLocalIPv6PrefixLen": 0, 
   "Ports": {}, 
   "SandboxKey": "/var/run/docker/netns/c73841812aab", 
   "SecondaryIPAddresses": null, 
   "SecondaryIPv6Addresses": null, 
   "EndpointID": "3e492b611d9bd2c202c8a6c8fe4b4a755393545348b1aeb4e60995609dabb07c", 
   "Gateway": "172.17.0.1", 
   "GlobalIPv6Address": "", 
   "GlobalIPv6PrefixLen": 0, 
   "IPAddress": "172.17.0.2", 
   "IPPrefixLen": 16, 
   "IPv6Gateway": "", 
   "MacAddress": "02:42:ac:11:00:02", 
   "Networks": { 
    "bridge": { 
     "IPAMConfig": null, 
     "Links": null, 
     "Aliases": null, 
     "NetworkID": "54001aaff29a231c9b2fe83459805d99dce0c21d6e2719f9b11bc90d8fe2f9c9", 
     "EndpointID": "3e492b611d9bd2c202c8a6c8fe4b4a755393545348b1aeb4e60995609dabb07c", 
     "Gateway": "172.17.0.1", 
     "IPAddress": "172.17.0.2", 
     "IPPrefixLen": 16, 
     "IPv6Gateway": "", 
     "GlobalIPv6Address": "", 
     "GlobalIPv6PrefixLen": 0, 
     "MacAddress": "02:42:ac:11:00:02" 
    } 
   } 
  } 
 } 
] 

注意看Mounts節(jié)點(Docker的版本用的是1.10.3),數(shù)據(jù)卷的使用,類似于 Linux 下對目錄或文件進行 mount。

"Mounts": [ 
   { 
    "Name": "5ddd734c53a38a78a9f739157c63074b4aff736d4045925616d7753402304137", 
    "Source": "/var/lib/docker/volumes/5ddd734c53a38a78a9f739157c63074b4aff736d4045925616d7753402304137/_data", 
    "Destination": "/opt/vol-data", 
    "Driver": "local", 
    "Mode": "", 
    "RW": true, 
    "Propagation": "" 
   } 
  ] 


     

當我們在容器的volume上操作時,宿主機上對應的文件是否也會跟著變動呢?測試一下,在容器的volume上創(chuàng)建一個文件test.txt,然后查看宿主機是不是也會同步存在



經(jīng)測試,當容器上的volume有變動時,宿主機也會跟著變動,那反過來呢?經(jīng)測試也是一樣的。不管是容器掛載點發(fā)生變動還是宿主機對掛載目錄進行操作,令一方都會跟著變動。

利用docker commit生成新鏡像,然后docker run -it 運行新鏡像,發(fā)現(xiàn)容器掛載目錄下沒有任何文件了。說明生成新鏡像時,是不保存掛載文件的。

3.2從宿主機掛載volume(-v /host-path:/container-path)

將主機的文件或文件夾作為volume掛載時,可以用多個 -v標簽為容器添加多個volume,還可以使用:ro指定該volume為只讀。注意:如果容器中指定的掛載目錄存在相同的文件時,會被宿主機覆蓋掉


在宿主機上建立了/opt/vol-01和/opt/vol-02掛載點,分別和容器中的/opt/vol-test-1和/opt/vol-test-2對應,前者權限默認讀寫,后者只能讀,用docker inspect


當在容器的vol-test-2上新建操作時,會提示只讀.在宿主機上,2個掛載點新增,修改,刪除操作都OK,但是在容器中居然2個都不行,按理說應用是第二個vol-test-2不行才對,不知是哪里出問題了。

利用docker commit生成新鏡像,然后docker run -it 運行新鏡像,發(fā)現(xiàn)容器掛載目錄下沒有任何文件了。說明生成新鏡像時,是不保存掛載文件的。

3.3使用Dockerfile添加volume

使用VOLUME指令向容器添加volume

VOLUME /data

多個時VOLUME ["/data1","/data2"]

這種情況和第一個中情況docker run -v /data是一樣的。注意,dockerfile中使用volume是不能和第二種方法那樣掛載宿主機中指定的文件夾。這時為了保證Dockerfile的可移植性,因為不能保證所有的宿主機都有對應的文件夾。

需要注意的是,在Dockerfile中使用VOLUME指令后,如果嘗試對這個volume進行修改,這些修改指令都不會生效,比如下面例子,嘗試添加一個文件,并修改文件并改變文件所有權限

FROM test/mycent:v1.0 
RUN useradd foo 
VOLUME /data 
RUN touch /data/x 
RUN chown -R foo:foo /data 

通過該Dockerfile創(chuàng)建鏡像并啟動容器后,該容器中存在用戶foo,并且能看到在/data掛載的volume,但是/data文件夾的所有者并沒有被改變?yōu)閒oo,而且/data下也沒有/data/x文件。但是如果順序反過來,先建文件,先授權,再掛載volume,那就得到期待的結果。

4.共享volume/數(shù)據(jù)卷容器(--volumes-from)

如果你有一些持續(xù)更新的數(shù)據(jù)需要在容器之間共享,最好創(chuàng)建數(shù)據(jù)卷容器。數(shù)據(jù)卷容器,其實就是一個正常的容器,專門用來提供數(shù)據(jù)卷供其它容器掛載的。

先創(chuàng)建一個名為dbdata的數(shù)據(jù)卷容器,專門共其他容器掛載。


     在/opt/dbdata下創(chuàng)建了一個文件db.properties。

     再啟動2個容器,a,b都a--volumes-from dbdata,b --volumes-from a.



    可以看到vol_a,vol_b容器的/opt/dbdata下都有db.properties文件。在vol_b的/opt/dbdata下創(chuàng)建文件vol_b.txt時,容器dbdata,vol_a也都同時同步了。

    對dbdata,vol_a,vol_b使用命令docker inspect時,發(fā)現(xiàn)他們的Mounts下的Source都是一樣的,說明它們都綁定到宿主機的同一個目錄,所以當某個容器的掛載修改時,其他容器也看到了同樣的效果


如果掛載源有多個時,可以使用多個--volumes-from,如

docker run -it --name vol_use --volumes-from vol_a --volumes-from vol_b test/mycentos:v1.0 /bin/bash.

   如果一個容器掛在了volume,即使容器停止了運行,該volume仍然存在,其他容器仍然可以繼續(xù)--volumes-from它。


5.刪除volume

如果創(chuàng)建容器時掛載了volume,

在/var/lib/docker/volumes/04b003b21b873157433deffbaf08bb0c89d234d3ec3c6576fdd7b61f5d41163e/_data下會生成相應的文件(路徑,不同版本,不同操作系統(tǒng)會有所不同,具體可以用docker inspect查看容器具體信息),當刪除容器時,宿主機上的掛載目錄時不會刪除的,并且目錄名稱是隨機字符,不知意義,所以在刪除容器時,需要妥善處理容器的volume。刪除容器時一并刪除volume有2中方法

(1)docker rm -v 刪除容器。就是刪除容器時,加上-v

(2)docker run --rm .就是啟動容器的時候加上--rm,那么當容器運行停止時會自動刪除容器以及容器所掛載的volume

上面創(chuàng)建了容器dbdata,vol_a,vol_b,vol_c,現(xiàn)在使用docker rm -v看看有什么效果。


vol_c是--volumes-from dbdata的,刪除vol_c時,宿主機的掛載目錄仍存在,沒刪掉,猜測那是因為還有其他容器在連著或者說是dbdata -v的時候創(chuàng)建的。那現(xiàn)在刪除dbdata容器試試看(vol_a是--volumes-from dbdata的,vol_a還沒刪除,驗證下能否刪除dbdata)。


發(fā)現(xiàn)dbdata刪除時,宿主機那目錄仍然存在,同時也說明哪怕vol_a是--volumes-from dbdata的,vol_a還沒刪除,那也沒影響。同時也說明只要還有一個容器在掛載這宿主機的目錄,那宿主機的目錄就不會刪除。那接下來,把所有容器都刪除,再看結果。


可以看到,當最后一個容器刪除后,宿主機那volume目錄終于刪除了.

6.備份、恢復或遷移volume

上面有測試過,當使用docker commit等手段生成新鏡像,然后再啟動鏡像生成新容器時,原先volume目錄下的文件不見了,可以生成新鏡像時,并沒有把volume下的文件一起打包生成鏡像。

volume作為數(shù)據(jù)的載體,在很多情況下需要對其中的數(shù)據(jù)進行備份、遷移,或是從已有數(shù)據(jù)恢復。一個很容易想到的方法就是用docker inspect命令查找到volume對應宿主機上對應的那個目錄位置,然后復制其中內(nèi)容或使用tar打包。當這些笨拙的做法并不值得推薦,因為查找主機上文件夾后再操作容易出錯,也不適合腳本的自動化執(zhí)行。

備份volume可以使用以下方法

復制代碼 代碼如下:

docker run --rm --volumes-from dbdata -v $(pwd):/backup test/mycentos:v1.0 tar cvf /back/data.tar /data

這行指令啟動了一個臨時的容器,這個容器掛載了兩個volume,第一個volume與要備份的volume共享,第二個volume將宿主機的當前目錄(也可以絕對路徑)掛載到容器的/backup下。容器運行后將要備份的容器(/data)備份到/backup/data.tar,然后刪除容器,備份后的data.tar就留在了當前目錄。操作驗證一下


居然報錯了,說沒有權限。進入容器-it時,是docker隨機生成一個用戶的,至于怎樣給該用戶授權,以后再研究吧。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • DOCKERFILE學習及使用注意事項

    DOCKERFILE學習及使用注意事項

    Dockerfile 由一行行命令語句組成,并且支持以 # 開頭的注釋行。一般的,Dockerfile分為四部分:基礎鏡像信息、維護者信息、鏡像操作指令、容器啟動時執(zhí)行指令
    2017-02-02
  • 詳解如何使用Docker快速部署ELK環(huán)境(最新5.5.1版本)

    詳解如何使用Docker快速部署ELK環(huán)境(最新5.5.1版本)

    這篇文章主要介紹了詳解如何使用Docker快速部署ELK環(huán)境(最新5.5.1版本),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • docker run -e傳遞環(huán)境變量的過程

    docker run -e傳遞環(huán)境變量的過程

    這篇文章主要介紹了docker run -e傳遞環(huán)境變量的過程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-01-01
  • Docker數(shù)據(jù)目錄遷移方法詳解

    Docker數(shù)據(jù)目錄遷移方法詳解

    這篇文章主要介紹了Docker數(shù)據(jù)目錄遷移方法,Docker數(shù)據(jù)目錄遷移成功后再也不用擔心服務器系統(tǒng)盤目錄被占滿的情況的,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • Docker?安裝啟動Jenkins的方法(docker-compose)

    Docker?安裝啟動Jenkins的方法(docker-compose)

    這篇文章主要介紹了Docker?安裝啟動?Jenkins(docker-compose)的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • 詳解如何用docker安裝laravel開發(fā)環(huán)境

    詳解如何用docker安裝laravel開發(fā)環(huán)境

    本篇文章主要介紹了詳解如何用docker安裝laravel開發(fā)環(huán)境,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • Docker容器在系統(tǒng)啟動時自動運行配置方法

    Docker容器在系統(tǒng)啟動時自動運行配置方法

    docker容器化可以使得環(huán)境相對獨立,減少污染,這篇文章主要給大家介紹了關于Docker容器在系統(tǒng)啟動時自動運行配置的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-09-09
  • 詳解Docker容器運行多條命令(supervisor)

    詳解Docker容器運行多條命令(supervisor)

    本篇文章主要介紹了詳解Docker容器運行多條命令(supervisor),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • Docker實踐--部署Nodejs應用

    Docker實踐--部署Nodejs應用

    本篇文章主要介紹了Docker實踐--部署Nodejs應用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • Docker安裝Redis最新圖文教程(非常全)

    Docker安裝Redis最新圖文教程(非常全)

    Redis是一個開源的使用ANSI C語言編寫、支持網(wǎng)絡、可基于內(nèi)存亦可持久化的日志型、Key-Value的NoSQL數(shù)據(jù)庫,這篇文章主要給大家介紹了關于Docker安裝Redis的相關資料,需要的朋友可以參考下
    2023-11-11

最新評論