docker 系列 - 容器數據持久化和數據共享


docker 主要有兩種數據存儲形式, 一種是storage driver(也叫做 Graph driver), 另一種是 volume driver. stroage driver主要是存儲那些無狀態的數據, 寫入密集型的場景應該使用 volume driver.

======================
storage driver
======================
容器運行的文件系統是鏡像層和容器層組成的, 一層一層疊加, 只有最上面的那層是可寫的, 其他層都是只讀的. Docker通過Union FS技術支持文件的讀寫和新建, Docker 采用插件式的方式支持多種Union FS實現, 官方文檔中一般使用stroage driver術語, 目前已經有多種實現的插件, 比如: aufs/overlay/overlay2/devicemanger等等.

boot2docker 缺省使用的storage-driver 為 aufs, 下面命令將創建一個使用 overlay2 的 storage driver docker運行環境.

docker-machine create --driver virtualbox --engine-storage-driver overlay2 test2

 

正式的docker 環境, 需要修改 /etc/docker/daemon.json 文件, 具體參考選用btrfs driver的官方文檔 https://docs.docker.com/storage/storagedriver/btrfs-driver/#configure-docker-to-use-the-btrfs-storage-driver
{
"storage-driver": "btrfs"
}
對於不同的Linux發行版的主機, 官方有一些推薦說明:
https://docs.docker.com/storage/storagedriver/select-storage-driver/
https://success.docker.com/article/compatibility-matrix
對於CentOS 7推薦使用 overlay2, 可參考 https://blog.csdn.net/lusyoe/article/details/80208260 ,


幾個查詢storage driver的命令:
docker info 命令, 查詢docker運行環境使用的storage-driver.
docker image inspect 命令,查看鏡像使用的存儲driver.
docker container inspect 命令,查看容器使用的存儲driver.

 

======================
volume driver
======================
volume driver 經常用來實現數據持久化和文件共享功能, 具體有兩種存在方式, 分別是:
1. bind mount 方式:
是將host的目錄或文件直接mount到容器中, host的目錄或文件既可以容器運行之前就已存在的, 也可以是在容器運行之前不存在的.
如果在docker run 命令中采用了 -v /host/dir_or_file:/container/dir_or_file的形式, 就是bind mount方式, 即指定了host的掛載點的絕對路徑.
2. volume 方式: 是由 Docker 管理, 該volume最終存儲到host的 /var/lib/docker/volumes 下. volume 方式還分為 named volume 和 Anonymous volume.
named volume 有兩種創建方法,
(1) docker run 命令中采用了 -v one_volume_name:/container/dir_or_file , 這里的one_volume_name不是host中的絕對路徑, 而是一個名稱.
(2) 通過 docker volume create 創建的, 該命令支持更多的選項, 推薦使用.
匿名volume方式 是通過 docker run 命令中傳入了 -v /container/dir 類型的參數.
3. bind mount 方式和volume方式的簡單對比:
bind mount方式, docker容器直接訪問host的目錄或文件, 性能是最好的.
bind mount方式, docker容器直接訪問host的目錄或文件, 對於該host絕對目錄可能會引入權限問題. 如果容器僅需要只讀訪問權限, 最好是顯式設定只讀方式.
對於 volume方式, 如果host中落地目錄為空, docker先將容器中的對應目錄復制到host下, 然后再進行掛載操作; 對於bind mount方式, 掛載之前沒有復制操作.
容器要依賴host主機的一個絕對路徑, 使得容器的移植性變差, docker 官方並不推薦這個方法, 而是推薦使用volume.

 

 

幾個示例說明:

docker run -d --name web0 -v myetc:/etc busybox /bin/sh -c "while true; do echo hello world; sleep 1; done" 
  #創建了一個named volume, 該volume 在 /var/lib/docker/volume/myetc 下. 
docker run -d --name web1 -v /etc busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"
  #創建了一個匿名的volume, 該volume在/var/lib/docker/volume父目錄下, 具體子目錄不確定, 
  #比如 /var/lib/docker/volume/9170d32e15b7578240afde81d5514637beece7d469b7ea253e23759a23b0a397  
docker run -d --name web2 -v /etc2:/etc  busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"
  #使用  bind mount 方式, host上的目錄為 /etc2 

 

docker run 命令的--volume 和 --mount 參數
--volume 和 --mount 兩種參數寫法都支持上述volume和bind mount方式, --mount 采用key-value的寫法, 支持更多的設置選項, docker 新版更加推薦使用 --mount 參數寫法, 但 --volume 寫法更加簡潔, 仍然給廣泛使用.
另一種推薦的volume寫法是, 顯式地使用 docker volume create 命令創建 named volume, 更多信息見官方文檔: https://docs.docker.com/engine/reference/commandline/volume_create/#usage

有了上面的知識, 很容易就能實現容器和Host之間共享數據. 對於同一Host下多個容器共享數據, 直接docker run -v參數非常不方便, 最好是使用 data container作為橋梁. 一般data container 不啟任何應用, 也不需要將容器真正運行起來, 僅僅是掛載一下 volume, data container除了用於多個容器之間數據共享之外, 也可用於volume的備份和恢復.

 

data container和volume的備份恢復

#創建一個名 為 dbstore 的數據容器, 設置一個匿名的/dbdata volume. 
docker create -v /dbdata --name dbstore busybox /bin/sh 

#創建一個名為 web3 的應用容器, 將 dbstore 數據容器的volume 掛載過來. 
docker run -d --name web3 --volumes-from dbstore busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"


#備份數據容器 dbstore 的/dbdata目錄到容器到host的host_backup目錄下, 最終在host上的文件名為 /host_backup/backup.tar
docker run --rm --volumes-from dbstore  -v /host_backup:/backup busybox tar -cvf /backup/backup.tar /dbdata
   
#恢復數據容器dbstore 的/dbdata目錄, 數據源為host上的文件 /host_backup/backup.tar
docker run --rm --volumes-from dbstore -v /host_backup:/backup busybox /bin/sh -c "cd /dbdata && tar -xvf /backup/backup.tar --strip 1"

 

======================
容器之間的通訊
======================
同一個docker daemon 下的容器, When containers are placed in the same network, they are reachable by each other using their container name and other alias as host.
https://stackoverflow.com/questions/35832095/difference-between-links-and-depends-on-in-docker-compose-yml

 

======================
參考
======================
http://www.cnblogs.com/sammyliu/p/5932996.html
http://www.cnblogs.com/lkun/p/7750629.html
https://blog.csdn.net/lusyoe/article/details/80208260


免責聲明!

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



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