Docker(三)-Docker中Image、Container與Volume的遷移

Image

鏡像的遷移,適用於離線環境。docker

通常離線環境,都會自建Docker Registry。 不管 官方的 ,仍是最近流行的 Harbor ,都是不錯的選擇。 可是,這個世界上就是有些環境,或者說一些環境在某些時期,沒有外網,也沒有內部的Registry。 這個時候要部署Docker的服務,怎麼辦?網絡

只能經過鏡像的遷移。 實際上, Harbor 的offline installer,就是採用這種形式。ssh

Save

# use stdout docker save alpine > /tmp/alpine.tar # or write to a file directly docker save alpine -o /tmp/alpine.tar

推薦使用 -o 的形式,由於利用stdout的作法雖然直觀,但在某些場景下無效,好比利用ssh 遠程執行命令。spa

Load

# use stdout docker load < /tmp/wekan.tar # or read from a file directly docker load -i /tmp/wekan.tar

Container

容器的遷移,適用於已經上線,且狀態複雜、從零開始啓動不能正常工做的服務。 容器遷移的包,包含了鏡像。插件

Export

先準備一個正在運行的服務,而且弄髒環境。3d

$ docker run --rm -d --name test alpine tail -f /dev/null 9232f0c1dafe0f29918f281ca37bb41914677e818cb6f252abf3dab3be04fbb2 $ docker exec test touch proof $ docker exec test ls -hl proof -rw-r--r-- 1 root root 0 Nov 20 14:33 proof

執行導出操做:rest

docker export test -o test.tar

Import

首先,關閉剛纔運行的服務。code

$ docker kill test
test

執行導入操做:blog

$ docker import test.tar test-img sha256:e03727eeba7e16dd3acfcc7536f1244762508f9b6b9856e49cc837c1b7ffa444

要注意的是, import 後獲得的是一個鏡像,至關因而執行了 docker commit 後的內容。 固然, docker commit 不是一個推薦的操做,因此容器的導入、導出,就顯得不是那麼的順眼。部署

最後,檢查以前建立的文件。

$ docker run --rm -d --name test test-img tail -f /dev/null ee29cb63bb2d3ed8ac890789ba80c4fe4078b9d5343a8952b6217d64b4dcbe23 $ docker exec test ls -hl proof -rw-r--r-- 1 root root 0 Nov 20 14:33 proof

能夠看到,前面建立的文件是存在的,而且時間戳徹底一致。

Volume

數據卷的遷移,比較麻煩。 Docker並未提供官方的簡單方案。

固然,直接用 root 用戶訪問文件系統的Docker數據,好比默認的/var/lib/docker/volumes/ 下的文件夾,直接進行打包操做,也不是不行。 但這毫無疑問是最糟糕的方案。

目前參考《 Use volumes | Docker Documentation 》,找到的最佳方案是,用另外一個容器,把數據卷內容打包,而且經過掛載的形式傳遞到宿主機。

Backup

首先,準備一個Volume。

$ docker run --rm -d --name test -v test-vol:/data test-img tail -f /dev/null f4ff81f4c31025ff476fbebc2c779a915b43ba5940b5bcc42e3ef9b1379eaeab $ docker exec test touch /data/proof $ docker exec test ls -hl proof -rw-r--r-- 1 root root 0 Nov 20 14:40 proof

執行備份操做:

$ docker run --rm -v test-vol:/volume -v $PWD:/backup alpine tar cvf /backup/backup.tar volume volume/ volume/proof

直接在已運行容器中打包,而後經過 docker cp 複製出來,也是一個方案。 但這會對正在運行的容器有影響,不建議在真正重要的容器中使用。

這裏利用了一個 Alpine 鏡像來執行操做。 實際上,任何一個自帶 tar 的鏡像都是能夠的。

Restore

首先,清理剛纔的容器和數據卷。

$ docker kill test
test
$ docker volume rm test-vol
test-vol

執行還原操做:

docker run --rm -v test-vol:/volume -v $PWD:/backup alpine tar xf /backup/backup.tar

最後,檢查還原後的結果。

$ docker run --rm -v test-vol:/data alpine ls -ahl /data total 8 drwxr-xr-x 2 root root 4.0K Nov 20 14:48 . drwxr-xr-x 1 root root 4.0K Nov 20 14:50 .. -rw-r--r-- 1 root root 0 Nov 20 14:40 proof

結論

以上其實都不是常規手段。

Image的傳遞,更應該依賴於內部Docker Registry而非tar。 (固然,也有例外,好比集羣部署大鏡像的P2P方案,也許能夠借鑑這個手段。)

Container的狀態,應該是可棄的。 一個運行了很長時間的Container,應該是能夠 restart 、甚至 kill 後再從新 run 也不影響既有功能的。 任何有依賴的狀態,都應該考慮持久化、網絡化,而不能單純地保存在本地文件系統中。

Volume的手動遷移,的確能夠採用上述方式。 可是,Volume須要手動遷移、備份嗎? 這須要專業而完善的插件來實現。

相關文章
相關標籤/搜索