場景:在處理mysql數據庫時重啟發現數據不見了。
原因:提交操作不包含 包含在容器內的卷中包含的任何數據,也就是說只有初始化的配置操作以及一開始的建庫操作會被commit掉,其他的不會記錄。
當然在容器中操作,去“提交”到一個新的容器時,同樣也會被容器默認的保存下來。
The commit operation will not include any data contained in volumes mounted inside the container.
It can be useful to commit a container’s file changes or settings into a new image.
docker的數據掛載分為三種volume, bind mount和tmpfs:
volume是由docker默認及推薦的掛載方式,volume由docker直接管理,同一個volume可以共享給多個容器使用,volume和容器的生命周期完全獨立,容器刪除時volume仍然存在,除非使用docker volume
相應命令刪除volume;缺點是volume在宿主機上比較難定位,在宿主機上直接操作volume比較困難。
bind mount是直接將宿主機文件系統上的文件路徑映射到容器中,兩邊雙向同步,顯而易見,有缺點也有優點,優點是可以直接訪問,也可以被別的程序使用,比如我們打包一個本地應用到本地/target路徑,我們就可以把這個路徑使用bind mount的方式掛在到依賴他的應用的docker容器中,這樣本地應用打包后,docker里的數據卷也會同時更新;缺點也是顯而易見的,因為你可以把任何文件路徑使用bind mount的方式綁定到容器中,這樣有可能一些安全問題,比如把宿主機的系統文件綁定到容器中。
tmpfs這種方式是使用宿主機的內存作為存儲,不會寫到宿主機的文件系統中,和前兩種區別較大。
mysql dockerHub主頁中的推薦方式是在宿主機中新建一個專門用來存放mysql docker數據的文件路徑,同時在新建容器的時候將該路徑映射到容器中,也就是使用bind mount的方式,之所以不使用volume的方式是因為volume是由docker管理,在宿主機上比較難定位。
那對於我的情況,既已經有一個容器使用了volume,想把volume里的數據在新的容器中使用bind mount方式掛載該怎么辦呢?我們可以先把mysqldock容器中所需要的文件拷貝出來到本地的/var/own/mysqldata,通過
docker cp hub.c.163.com/library/mysql:/var/lib/mysql /var/own/mysqldata
然后在創建新的mysql容器時,掛載該文件即可
docker run -v /var/own/mysqldata:/var/lib/mysql --name mysqlnew -d mysql
這樣新的容器就可以保留mysqldock中的數據了,問題解決!當然,我們也可以使用docker推薦的volume方式掛載,首先找到mysqldock的volume,然后在運行新容器時指定該volume進行掛載就行了:
這種方式繁瑣?別急,還有更簡單的,在創建容器的時候,可以指定使用其他容器的volume,也就是共享其他容器的volume,使用--volumes-from參數
docker run --name mysqlvolumn2 --volumes-from mysqldock -d mysql
其實volume還可以在創建的時候進行命名,從而是查找起來不那么繁瑣,具體的參數就請大家參考官網或者--help了,其實官方更加推薦的是使用--mount代替-v參數,官網上有詳盡的例子,大家也可以自行進行嘗試。