docker卷、持久化和遷移

容器中的數(shù)據(jù)與Host相互獨立,隨著容器的釋放(刪除),這些數(shù)據(jù)也將丟失.
為了避免這個問題,Docker提供了數(shù)據(jù)卷(Volume)這個數(shù)據(jù)持久化工具.
持久化后的數(shù)據(jù),不會隨著容易刪除而丟失.

概述

試想這樣一個場景,幾年前我創(chuàng)建了一個mysql5.5的容器,幾年后由于業(yè)務變動,需要升級到mysql5.6,這個時候需要登陸到容器里面,把mysql的表文件復制下來,再想辦法遷移到新的mysql服務中.

這個手動復制的過程很容易出現(xiàn)意外,萬一不粗心大意,沒有復制data就刪除了容器,那差不多可以跑路了,否則就等著全村吃席吧.

好在Docker提供了bind mountvolume兩種方式來做數(shù)據(jù)持久化,先準備個mysql鏡像準備演示.

docker pull mysql:5.6

bind mount

bind mount是將host上的一個目錄mount到容器中,類似于一個共享文件夾.

bind mount一個目錄到容器,需要在創(chuàng)建容器時使用-v 本地目錄:容器目錄參數(shù)指定

docker run  -v /Users/zhangsan/opt:/opt ......

上述例子將本地/Users/zhangsan/opt目錄掛在到容器的/opt目錄. 登陸容器,

docker exec -it mysql_test_volume /bin/bash
echo Hello,World  >> index.html
exit

此時本地的/Users/zhangsan/opt目錄就會出現(xiàn)剛才創(chuàng)建index.html.

反之,如果在本地新增文件index2.html,容器內也會出現(xiàn)這個文件.

使用bind mount需要注意以下幾點:

  • host路徑必須為全路徑,否則回和volume混淆
  • 如果host目錄不存在,docker會自動創(chuàng)建該目錄
  • 如果容器目錄不存在,docker會自動創(chuàng)建該目錄
  • 如果容器目錄已有數(shù)據(jù),那么docker會將其覆蓋掉

就上面那個場景,如果使用了 bind mount,此時只需要新起一個5.6版本的容器,將目錄mount到新地址即可.

docker run  -v /Users/zhangsan/opt:/opt --name mysql_test_volume -d -e MYSQL_ROOT_PASSWORD=123456  -p 3306:3306 mysql:5.6

由于bind mount本質是個共享文件夾,因而依賴于系統(tǒng)文件系統(tǒng),不同系統(tǒng)間無法移植,

windowsNTFS文件系統(tǒng)就無法與linux常用的ext3/4兼容,windows目錄為\Users\zhangsan\...格式,
ext4文件系統(tǒng)目錄路徑為/usr/...

volume

volume是容器上的一個或者多個目錄,此目錄可以繞過文件系統(tǒng),與宿主機上的某目錄綁定.

volume于容器化初始化之時即會創(chuàng)建,可以在不同host上移植,卷中的數(shù)據(jù)會在build image期間完成復制.

  • 數(shù)據(jù)卷可以在容器之間共享和重用
  • 對數(shù)據(jù)卷的更改是直接進行的
  • 更新鏡像時,不包括對數(shù)據(jù)卷的更改
  • 即使刪除容器本身,數(shù)據(jù)卷也會保持

使用docker volume create volume_name來創(chuàng)建一個卷

docker volume create test

test掛在到容器上

docker run  -v test:/opt --name mysql_test_volume -d -e MYSQL_ROOT_PASSWORD=123456  -p 3306:3306 mysql:5.6

查看所有卷,使用

docker volume ls

查看一個卷信息,使用

docker volume inspect volume_name
docker_volume.png

刪除未使用的卷

docker volume prune

刪除一個卷

docker volume rm volume_name

bind mount不同的是,

  • 如果volume是空的而容器中的目錄有內容,那么docker會將container目錄中的內容拷貝到volume中
  • 但是如果volume中已經有內容,則會將container中的目錄覆蓋
  • Mac系統(tǒng)的docker Desktop實際上是構建在虛擬機上的,其volume在虛擬機的var/lib/docker/volume中,本機上不存在這個路徑.

volume遷移

最2的方式,登陸host/var/lib/docker/volume目錄找到對應的volume,打包帶走,在新hostvolume中解壓.
上面部分提到過volume的特點,可以利用這點來進行遷移,假設有一個卷test需要遷移,步驟如下
1.下載一個鏡像,越小越好,比如(alpine)
2.通過這個鏡像創(chuàng)建容器A,掛在test,由于容器內容為空,test中的數(shù)據(jù)會被復制到容器目錄中
3.打包這個容器A打包成鏡像image-A,push或者本地快照
4.新機器上新建同名volume,然后pull或者import鏡像image-A
5.通過鏡像image-A啟動容器B,掛載卷test,由于test是空的而容器目錄有內容,docker會將container目錄中的內容拷貝到volume中.
6.刪除鏡像image-A,容器A,容器B,由于數(shù)據(jù)卷不會被刪除,因而就完成了遷移,可以給新的容器使用.
這樣volume就隨著容器遷移到新的host上了

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容