Docker学习笔记之保存和共享镜像
0x00 概述?
讓 Docker 引以為傲的是它能夠實現相比于其他虛擬化軟件更快的環境遷移和部署,在這件事情上,輕量級的容器和鏡像結構的設計無疑發揮了巨大的作用。通過將容器打包成鏡像,再利用體積遠小于其他虛擬化軟件的 Docker 鏡像,我們可以更快的將它們復制到其他的機器上。在這一節中,我們就專門來談談如何進行這樣的遷移。
?
0x01 提交容器更改
之前我們已經介紹過了,Docker 鏡像的本質是多個基于 UnionFS 的鏡像層依次掛載的結果,而容器的文件系統則是在以只讀方式掛載鏡像后增加的一個可讀可寫的沙盒環境。
基于這樣的結構,Docker 中為我們提供了將容器中的這個可讀可寫的沙盒環境持久化為一個鏡像層的方法。更淺顯的說,就是我們能夠很輕松的在 Docker 里將容器內的修改記錄下來,保存為一個新的鏡像。
將容器修改的內容保存為鏡像的命令是?docker commit,由于鏡像的結構很像代碼倉庫里的修改記錄,而記錄容器修改的過程又像是在提交代碼,所以這里我們更形象的稱之為提交容器的更改。
$ sudo docker commit webapp sha256:0bc42f7ff218029c6c4199ab5c75ab83aeaaed3b5c731f715a3e807dda61d19eDocker 執行將容器內沙盒文件系統記錄成鏡像層的時候,會先暫停容器的運行,以保證容器內的文件系統處于一個相對穩定的狀態,確保數據的一致性。
在使用?docker commit?提交鏡像更新后,我們可以得到 Docker 創建的新鏡像的 ID,之后我們也能夠從本地鏡像列表中找到它。
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 0bc42f7ff218 3 seconds ago 372MB ## ......像通過 Git 等代碼倉庫軟件提交代碼一樣,我們還能在提交容器更改的時候給出一個提交信息,方便以后查詢。
$ sudo docker commit -m "Configured" webapp?
0x02 為鏡像命名
在上面的例子里,我們發現提交容器更新后產生的鏡像并沒 REPOSITORY 和 TAG 的內容,也就是說,這個新的鏡像還沒有名字。
之前我們談到過,使用沒有名字的鏡像并不是很好的選擇,因為我們無法直觀的看到我們正在使用什么。好在 Docker 為我們提供了一個為鏡像取名的命令,也就是?docker tag?命令。
$ sudo docker tag 0bc42f7ff218 webapp:1.0使用?docker tag?能夠為未命名的鏡像指定鏡像名,也能夠對已有的鏡像創建一個新的命名。
$ sudo docker tag webapp:1.0 webapp:latest當我們對未命名的鏡像進行命名后,Docker 就不會在鏡像列表里繼續顯示這個鏡像,取而代之的是我們新的命名。而如果我們對以后鏡像使用?docker tag,舊的鏡像依然會存在于鏡像列表中。
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE webapp 1.0 0bc42f7ff218 29 minutes ago 372MB webapp latest 0bc42f7ff218 29 minutes ago 372MB ## ......由于鏡像是對鏡像層的引用記錄,所以我們對鏡像進行命名后,雖然能夠在鏡像列表里同時看到新老兩個鏡像,實質是它們其實引用著相同的鏡像層,這個我們能夠從鏡像 ID 中看得出來 ( 因為鏡像 ID 就是最上層鏡像層的 ID )。正是這個原因,我們雖然創建了新的鏡像,但對物理存儲的占用空間卻不是鏡像大小直接翻倍,并且創建也在霎那之間。
除了使用?docker tag?在容器提交為新的鏡像后為鏡像命名這種方式外,我們還可以直接在?docker commit?命令里指定新的鏡像名,這種方式在使用容器提交時會更加方便。
$ sudo docker commit -m "Upgrade" webapp webapp:2.0?
0x03 鏡像的遷移
在我們將更新導出為鏡像后,就可以開始遷移鏡像的工作了。
由于 Docker 是以集中的方式管理鏡像的,所以在遷移之前,我們要先從 Docker 中取出鏡像。docker save?命令可以將鏡像輸出,提供了一種讓我們保存鏡像到 Docker 外部的方式。
$ sudo docker save webapp:1.0 > webapp-1.0.tar在默認定義下,docker save?命令會將鏡像內容放入輸出流中,這就需要我們使用管道進行接收 ( 也就是命令中的 > 符號 ),這屬于 Linux 等系統控制臺中的用法,這里我們不做詳細講解。
管道這種用法有時候依然不太友好,docker save?命令還為我們提供了?-o?選項,用來指定輸出文件,使用這個選項可以讓命令更具有統一性。
$ sudo docker save -o ./webapp-1.0.tar webapp:1.0在鏡像導出之后,我們就可以找到已經存儲鏡像內容的 webapp-1.0.tar 這個文件了。有興趣的朋友,可以使用解壓軟件查看其中的內容,你會看到里面其實就是鏡像所基于的幾個鏡像層的記錄文件。
?
0x04 導入鏡像
我們可以通過很多種方式將導出的鏡像文件復制到另一臺機器上,在這么操作之后,我們就要將鏡像導入到這臺新機器中運行的 Docker 中。
導入鏡像的方式也很簡單,使用與?docker save?相對的?docker load?命令即可。
$ sudo docker load < webapp-1.0.tar相對的,docker load?命令是從輸入流中讀取鏡像的數據,所以我們這里也要使用管道來傳輸內容。當然,我們也能夠使用?-i?選項指定輸入文件。
$ sudo docker load -i webapp-1.0.tar鏡像導入后,我們就可以通過?docker images?看到它了,導入的鏡像會延用原有的鏡像名稱。
?
0x05 批量遷移
通過?docker save?和?docker load?命令我們還能夠批量遷移鏡像,只要我們在?docker save?中傳入多個鏡像名作為參數,它就能夠將這些鏡像都打成一個包,便于我們一次性遷移多個鏡像。
$ sudo docker save -o ./images.tar webapp:1.0 nginx:1.12 mysql:5.7裝有多個鏡像的包可以直接被?docker load?識別和讀取,我們將這個包導入后,所有其中裝載的鏡像都會被導入到 Docker 之中。
?
0x06 導出和導入容器
也許 Docker 的開發者認為,提交鏡像修改,再導出鏡像進行遷移的方法還不夠效率,所以還為我們提供了一個導出容器的方法。
使用?docker export?命令我們可以直接導出容器,我們可以把它簡單的理解為?docker commit?與?docker save?的結合體。
$ sudo docker export -o ./webapp.tar webapp相對的,使用?docker export?導出的容器包,我們可以使用?docker import?導入。這里需要注意的是,使用?docker import?并非直接將容器導入,而是將容器運行時的內容以鏡像的形式導入。所以導入的結果其實是一個鏡像,而不是容器。在?docker import?的參數里,我們可以給這個鏡像命名。
$ sudo docker import ./webapp.tar webapp:1.0在開發的過程中,使用?docker save?和?docker load,或者是使用?docker export?和?docker import?都可以達到遷移容器或者鏡像的目的。
?
轉載于:https://www.cnblogs.com/JetpropelledSnake/p/10404654.html
總結
以上是生活随笔為你收集整理的Docker学习笔记之保存和共享镜像的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git的简单使用(一些小操作,持续更新)
- 下一篇: java实现线程间通信的四种方式