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


Image

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

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

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

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 遠程執行命令。

Load

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

Container

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

Export

先准備一個正在運行的服務,並且弄臟環境。

$ 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

執行導出操作:

docker export test -o test.tar

Import

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

$ docker kill test
test

執行導入操作:

$ 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需要手動遷移、備份嗎? 這需要專業而完善的插件來實現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM