## 數據卷
數據卷是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,可以提供很多有用的特性:
* 數據卷可以在容器之間共享和重用
* 對數據卷的修改會立馬生效
* 對數據卷的更新,不會影響鏡像
* 數據卷默認會一直存在,即使容器被刪除
>[info]注意:數據卷的使用,類似于 Linux 下對目錄或文件進行 mount,鏡像中的被指定為掛載點的目錄中的文件會隱藏掉,能顯示看的是掛載的數據卷。
## 創建數據卷
創建一個名為 web 的容器,并加載一個數據卷到容器的 `/webapp` 目錄。
~~~
docker run -d -P --name web -v /webapp webapp
~~~
## 刪除數據卷
數據卷是被設計用來**持久化數據**的,它的生命周期獨立于容器,Docker不會在容器被刪除后自動刪除數據卷,并且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的數據卷。如果需要在刪除容器的同時移除數據卷。可以在刪除容器的時候使用 `docker rm -v`
## 掛載主機目錄作為數據卷
使用 -v 標記也可以指定掛載一個本地主機的目錄到容器中去。
~~~
docker run -d -P --name web -v /src/webapp:/opt/webapp webapp
~~~
Docker 掛載數據卷的默認權限是讀寫,用戶也可以通過 :ro 指定為只讀。
~~~
docker run -d -P --name web -v /src/webapp:/opt/webapp:ro webapp
~~~
>[info]注意:Dockerfile 中不支持這種用法,這是因為 Dockerfile 是為了移植和分享用的。然而,不同操作系統的路徑格式不一樣,所以目前還不能支持。
## 查看數據卷的具體信息
~~~
docker inspect --format "{{json .Mounts }}" dock_registry_1
~~~
## 掛載一個本地主機文件作為數據卷
記錄在容器輸入過的命令
~~~
sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
~~~
>[info]注意:如果直接掛載一個文件,很多文件編輯工具,包括 vi 或者 sed --inplace ,可能會造成文件 inode 的改變,從 Docker 1.1.0起,這會導致報錯誤信息。所以最簡單的辦法就直接掛載文件的父目錄。
## 數據卷容器
如果你有一些持續更新的數據需要在**容器之間共享**,最好創建數據卷容器。
數據卷容器,其實就是一個正常的容器,專門用來提供數據卷供其它容器掛載的。
首先,創建一個名為 webapp_code 的數據卷容器
~~~
docker run -d -v /webapp --name webapp_code centos
~~~
在其他容器中使用 `--volumes-from` 來掛載 webapp_code 容器中的數據卷。`--volumes-from`支持級聯掛載。
~~~
docker run -it --volumes-from webapp_code --name webapp_1 centos /bin/bash
docker run -it --volumes-from webapp_1 --name webapp_2 centos /bin/bash
~~~
>[info]數據卷的容器自己并不需要保持在運行狀態。
## 借助于容器進行數據恢復
### 備份

首先使用 --volumes-from 標記來創建一個加載 **database 容器卷容器**,并從主機掛載**當前目錄**到容器的 /backup 目錄。命令如下:
~~~
docker run -d --volumes-from webapp_code -v $(pwd):/backup --name backup centos tar cf /backup/webapp.tar /webapp
~~~
容器啟動后,使用了 tar 命令來將 **database** 卷備份為容器中 /backup/backup.tar.gz文件,也就是主機當前目錄下的名為 backup.tar 的文件。
此處為何不直接從數據卷容器備份文件呢?
數據卷容器無法再次掛載用來備份的**數據卷**,所以只能將數據卷容器掛載到新的容器的同時掛載用來備份的數據卷,將備份文件備份到本地的文件系統中。
備份到本地后,直接解壓,啟動新的數據卷容器時將解壓后的內容直接掛載到新的數據卷容器中。
為何不直接從本地文件系統備份數據卷容器中的內容?
### 恢復
如果要恢復數據到一個容器,首先創建一個帶有**空數據卷容器** dbdata2。
~~~
docker run -d -v /webapp --name new_webapp_code centos
~~~
然后創建另一個容器(這個容器只作為**解壓使用**),掛載 dbdata2 容器卷中的數據卷,并使用 untar 解壓備份文件到掛載的容器卷中。
~~~
docker run -it --volumes-from new_webapp_code -v $(pwd):/backup --name temp_data centos tar xf /backup/webapp.tar
~~~
為了查看/驗證恢復的數據,可以再啟動一個容器掛載同樣的容器卷來查看
~~~
docker run -it --volumes-from new_webapp_code centos /bin/bash
~~~
## 使用文件系統進行數據恢復
### 創建數據卷容器
創建時掛載本地的文件目錄
~~~
docker run -d -v /webapp:/webapp --name webapp_code centos
~~~
在其他容器中使用 `--volumes-from` 來掛載 webapp_code 容器中的數據卷。`--volumes-from`支持級聯掛載。
~~~
docker run -it --volumes-from webapp_code --name webapp_1 centos /bin/bash
docker run -it --volumes-from webapp_1 --name webapp_2 centos /bin/bash
~~~
### 本地文件系統備份
~~~
cp /webapp /webapp_backup
~~~
### 創建新的數據卷容器
~~~
docker run -d -v /webapp_backup:/webapp --name webapp_code centos
~~~