上節講到當容器運行期間產生的數據是不會在寫鏡像里面的,重新用此鏡像啟動新的容器就會初始化鏡像,會加一個全新的讀寫入層來保存數據。如果想做到數據持久化,Docker提供數據卷(Data volume)或者數據容器卷來解決問題,另外還可以通過commit提交一個新的鏡像來保存產生的數據。那么,來一一看下各自的使用方法。
一、數據卷
數據卷特性:
-
可以繞過UFS文件系統,為一個或多個容器提供訪問。
-
完全獨立於容器的生存周期,因此不會在刪除容器時刪除其掛在的數據卷。
數據卷特點:
-
數據卷在容器啟動初始化時,如果容器使用的鏡像在掛載點包含了數據,這些數據會拷貝到新初始化的數據卷中。
-
數據卷可以在容器直接共享和重用。
-
可以直接對數據卷里的內容進行修改。
-
數據卷的變化不會影響鏡像的更新。
-
卷會一直存在,即使掛載數據卷的容器已經刪除。
1.數據卷使用
創建並掛載數據卷:
$ sudo docker run -itd --name ubuntu_test1 -v /container_data:/data ubuntu
注:container_data為宿主機目錄,/data是容器中目錄,目錄不存在會自動創建
$ sudo docker inspect ubuntu_test1
"Mounts": [
{
"Source": "/container_data",
"Destination": "/data",
"Mode": "",
"RW": true
}
],
可以看到已經掛載成功,並且容器對這個目錄具有讀寫權限。
測試:
$ cd container_data
$ sudo touch test.txt
$ sudo docker exec ubuntu_test1 ls /data
test.txt
在宿主機目錄創建的文件,同樣在容器內看到。
2.刪除容器,數據會一同刪除嗎?
$ sudo docker stop ubuntu_test1
$ sudo docker rm ubuntu_test1
$ ls container_data
test.txt
看到宿主機上數據卷目錄里的文件並沒有發生變化,說明刪除容器不會影響數據卷。
3.重新啟動一個容器,同樣掛載這個數據卷試試
$ sudo docker run -itd --name ubuntu_test2 -v /container_data:/data ubuntu
$ sudo docker exec ubuntu_test1 ls /data
test.txt
文件依然存在,說明初始化時將數據拷貝到了容器中。
3.再啟動一個容器,還將數據卷掛載到這里
$ sudo docker run -itd --name ubuntu_test3 -v /container_data:/data ubuntu
$ sudo docker exec ubuntu_test1 ls /data
test.txt
同樣可以看到數據,說明數據卷可以共享多個容器使用。
二、 容器 數據卷
將一個正常的容器作為數據卷,讓其他容器通過掛載這個容器實現數據共享。
注意:數據卷容器會降低I/O性能。
1.容器數據卷使用
創建一個dvdata的數據卷容器:
$ sudo docker run -itd -v /data --name dvdata ubuntu
注:/data是數據卷容器內共享的目錄
在其他容器中掛載dvdata容器的數據卷:
$ sudo docker run -itd --name web1 --volumes-from dbdata ubuntu
$ sudo docker run -itd --name web2 --volumes-from dbdata ubuntu
分別進入web1、web2容器中,會有一個/data目錄,在web1里的/data目錄創建文件,web2也能看的到。
總結: 如果刪除dvdata、web1、web2,時,數據卷並不會被自動刪除。如果想刪除需在刪除最后一個掛載着它的容器時使用docker rm -v 命令來指定刪除關聯的容器。
博客地址: http://lizhenliang.blog.51cto.com
三、commit命令使用
commit命令作用是將已存在容器中的鏡像和修改內容提交為一個新的鏡像,通過這個方式同樣能保存讀寫層內容。
1.啟動一個新容器,並在容器/opt目錄下創建test.txt文件
$ sudo docker run -itd --name web ubuntu
$ sudo docker exec web touch /opt/test.txt
$ sudo docker exec web ls /opt
test.txt
2.提交一個新的鏡像
$ sudo docker commit web web:v2
$ sudo docker images
3.成功提交一個新的鏡像,用這個新的鏡像啟動一個容器,看是否創建的文件存在
$ sudo docker run -itd --name web_v2 web:v2
$ sudo docker exec web_v2 ls /opt
test.txt
總結: commit命令同樣能實現保存讀寫層數據,但不適於做數據持久化
四、數據卷容器備份和還原
備份:
$ sudo docker run --volumes-from dvdata -v /container_backup:/backup ubuntu tar cvf /backup/backup.tar /data
說明:先創建一個臨時容器,並掛載dvdata容器數據卷,再掛載數據卷/container_backup目錄到容器/bakcup,在容器中執行備份/data目錄到/backup,也就是備份到宿主機/container_backup目錄。
恢復:
#先創建一個數據卷容器
$ sudo docker run -v /data --name dvdata2 ubuntu
注意:這個數據卷目錄名要與備份的一樣
#再將備份文件恢復到這個數據卷容器
$ sudo docker run --volumes-from dvdata2 -v /container_backup:/backup ubuntu tar xvf /backup/backup.tar
#最后啟動一個容器掛載驗證/data目錄數據恢復成功
$ sudo docker run -itd --volumes-from dvdata2 --name web_recover ubuntu
五、遷移容器和鏡像
export與import命令使用:
#export導出容器會丟失歷史記錄和元數據,類似與快照
先創建測試容器:
$ sudo docker exec web touch /opt/test.txt
$ sudo docker exec web ls /opt
test.txt
執行導出:
$ sudo docker export web > web.tar
執行導入:
$ cat web.tar | sudo docker import - web:v2
$ sudo docker images
$ sudo docker run -itd --name web_v2 web:v2 /bin/bash
#啟動這個鏡像要加/bin/bash,否則報錯Error response from daemon: No command specified
$ sudo docker exec web_v2 ls /opt
test.txt
總結: 通過export命令也可以將容器里的數據保存,並可以遷移到別的docker主機
save與load命令使用:
#一般用於遷移鏡像到別處
導出:
$ sudo docker save web > web.tar
導入:
$ sudo docker load < ubuntu.tar
注:不會丟棄歷史記錄和元數據,並可以回滾版本。啟動不用加/bin/bash