深入理解Docker Volume(一)


   想要了解Docker Volume,首先我們需要知道Docker的文件系統是如何工作的.Docker鏡像是由多個文件系統(只讀層)疊加而成.當我們啟動一個容器的時候,Docker會加載鏡像層並在其上添加一個讀寫層.如果運行中的容器修改了現有的一個已存在的文件,那該文件將會從讀寫層下的只讀層復制到讀寫層,該文件的只讀版本仍然存在,只是已經被讀寫層中該文件的副本所隱藏.當刪除Docker容器,並通過該鏡像重新啟動時,之前的更改將會丟失.在Docker中,只讀層以及在頂部的讀寫層的組合被稱為Union FIle System(聯合文件系統).

    為了能夠保存(持久化)數據以及共享容器間的數據,Docker提出了Volume的概念.簡單來說,Volume就是目錄或者文件,它可以繞過默認的聯合文件系統,而以正常的文件或者目錄的形式存在於宿主機上.  

    我們可以通過兩種方式來初始化Volume,這兩種方式有些細小而又重要的差別.我們可以在運行時使用-v來聲明Volume:

root@syx-VB:/home/syx# docker run -it --name container-test -h CONTAINER -v /data ubuntu /bin/bash  
root@CONTAINER:/# ls /data/  
root@CONTAINER:/#  

   上面的命令會將/data掛載到容器中,並繞過聯合文件系統,我們可以在主機上直接操作該目錄.任何在該鏡像/data路徑的文件的文件都會被復制到Volume.我們可以使用docker inspect命令找到Volume在主機上的存儲位置:

$docker inspect container-test  
    "Mounts": [  
        {  
            "Name": "6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134",  
            "Source": "/var/lib/docker/volumes/6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134/_data",  
            "Destination": "/data",  
            "Driver": "local",  
            "Mode": "",  
            "RW": true  
        }  
    ],  

這說明Docker把在/var/lib/docker下的某個目錄掛載到了容器內的/data目錄下.讓我們從主機添加文件都此文件夾下:

root@syx-VB:~# touch /var/lib/docker/volumes/6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134/_data/test-file  

 

進入容器

root@syx-VB:~# docker attach container-test  
root@CONTAINER:/# ls /data/  
test-file  

 

只要將主機的目錄掛載到容器的目錄上,那改變就會立即生效.我們可以在Dockerfile中通過使用VOLUME指令來達到相同的目的:

 
  1. FROM ubunut VOLUME /data  

但是還有另一件只有-v參數能夠做到而Dockerfile是做不到的事情就是在容器上掛載指定的主機目錄.例如:

root@syx-VB:~# docker run -v /home/syx/dockerfile:/data ubuntu ls /data  
df_test1  

 

    該命令將掛載主機的/home/syx/dockerfile目錄到容器內的/data目錄上.任何在/home/syx/dockerfile目錄下的文件都會出現在容器內.這對於在主機和容器之間共享文件是非常有用的,例如掛載需要編譯的源代碼.為了保證可移植性,掛載主機目錄不需要從Dockerfile指定.當使用-v參數時,鏡像目錄下的任何文件都不會被復制到Volume中.

數據共享

    如果要授權一個容器訪問另一個容器的Volume,我們可以使用-volumes-from參數來執行docker run

root@syx-VB:~# docker run -it -h NEWCONTAINER --volumes-from container-test ubuntu /bin/bash  
root@NEWCONTAINER:/# ls /data/  
test-file  

 

 

   值得注意的是,就算你這個時候把container-test停止了,它仍然會起作用.只要有容器連接Volume,他就不會被刪除,如果這個時候你執行:

 

root@syx-VB:~# docker rm container-test  
Error response from daemon: Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f  
Error: failed to remove containers: [container-test]  

  數據容器

 

常見的使用場景是使用純數據容器來持久化數據庫,配置文件或者數據文件等.例如:

 
  1. $docker run --name dbdate postgres echo “Data-Only container for postgres” 

該命令將會創建一個已經包含在Dockerfile里定義過Volume的postgres鏡像,運行echo命令然后退出.當我們運行docker ps命令時,echo可以幫助我們識別某鏡像的用途.我們可以用-volume-from命令來識別其他容器的Volume:

 
  1. $docker run -d --volumes-from dadate --name db1 postgres  

使用數據容器的兩個注意點:

1.不要運行數據容器,這純屬是在兩非自願

2.不要為了數據容器而使用”最小的鏡像”,如busybox或scratch,只使用數據庫鏡像本身就可以了.你已經擁有了該鏡像,所以不需要占用額外的空間.

備份

如果你在用數據容器,那做備份是相當容易的.

  1. root@syx-VB:~# docker run --rm --volumes-from dbdate -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /var/lib/postgresql/data  

該命令會將Volume里所有的東西壓縮為一個tar包(官方的postgres Dockerfile在/var/lib/postgresql/data目錄下定義了一個Volume).   

  1. root@syx-VB:~# ls  
  2. backup.tar  

刪除Volumes

這個功能太重要了,如果你已經使用docker run來刪除你的容器,那可能會有很多孤立的Volume仍在占用着空間.

Voulume可以被刪除的條件:

1.該容器可以用docker rm -v來刪除且沒有其他容器連接到該Volume(以及主機目錄是也沒被指定為Volume).注意,-v是必不可少的.

2.docker run中使用rm參數.

 
 


免責聲明!

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



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