什麼是映象
映象是一種輕量級、 可執行的獨立軟體包,用來打包軟體執行環境和基於執行環境開發的軟體,它包含執行某個軟體所需的所有內容,包括程式碼、執行時、庫、環境變數和配置檔案。
所有應用,直接打包docker映象,就可以直接跑起來
如何得到映象:
- 遠端倉庫
- 自己製作一個映象DockerFile
Docker 映象載入的原理
UnionFS(聯合檔案系統)
UnionFS (聯合檔案系統) : Union檔案系統( UnionFS)是一種分層、 輕量級並且高效能的檔案系統,它支援對檔案系統的修改
作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬檔案系統下(unite several directories into a single virtual
filesystem)。Union 檔案系統是Docker映象的基礎。映象可以通過分層來進行繼承,基於基礎映象(沒有父映象) ,可以製作各
種具體的應用映象。
特性:一次同時載入多個檔案系統,但從外面看起來,只能看到一個檔案系統,聯合載入會把各層檔案系統疊加起來,這樣最終的
檔案系統會包含所有底層的檔案和目錄
Docker 映象載入原理
docker的映象實際上由一層一層的檔案 系統組成,這種層級的檔案系統UnionFS.
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引導載入kernel, Linux剛啟動時會載入bootfs檔案系統,在Docker映象的最底層是bootfs。這-層與我們典型的Linux/Unix系統是一樣的 ,包含boo載入器和核心。當boot載入完成之後整個核心就都在記憶體中了,此時記憶體的使用權已由bootfs轉交給核心,此時系統也會解除安裝bootfs.
rootfs (root file system) , 在bootfs之上。包含的就是典型Linux系統中的/dev, /proc, /bin, /etc等標準目錄和檔案。rootfs就是各種不同的作業系統發行版,比如Ubuntu , Centos等等。
平時我們安裝進虛擬機器的Centos都是好幾個G,為什麼docker才200MB
對於一個精簡的OS,rootfs可以是很小,只需要包含最基本的命令,工具和程式庫就可以了,因為底層直接用Host的kernel,自己只需要提供rootfs就可以了,由此可見對於不同的linux發行版,bootfs基本是一致的,rootfs會有差別,因此不同的發行版可以公用bootfs。
分層理解
分層的映象
我們可以去下載一個映象,注意觀察下載的日誌輸出,可以看到是一層一層的在下載。
為什麼Docker映象要採用這種分層的結構呢
最大的好處就是資源共享,比如多個映象都從相同的Base映象構建而來的,那麼宿主機只需要在磁碟上保留一份base映象,同時記憶體中也只需要載入一份base映象,這樣就可以為所有的容器服務了,而且映象的每一層都可以被共享。
檢視映象的分層的方式可以通過docker image inspect
命令。
$ docker image inspect redis:latest
[
//...
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:95ef25a3204339de1edf47feaa00f60b5ac157a498964790c58c921494ce7ffd",
"sha256:ad9080bec957893dd0e5d146ec4fed09232e4d2c40d6975bfb1d31ad7eeba6ae",
"sha256:03f8dae99b4d972acfb5afb240d170f71420aed3960b1b9e502c718938fc41a5",
"sha256:ce89ae6e6358780e4f0ac30e78edb8a867c577765ab2daa7eaac447701228863",
"sha256:e7b10f84d45b2e8277e0d2b49db8137aa2c5a01f90c8e951477425a1521f1bc2",
"sha256:ed8f8f354de8b585acea9d30ce39cfea0b2f74d1572b3ba045cdbd5441e8f918"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
- 理解
所欲的Docker 映象都起始於一個基礎映象層,當進行修改或者增加新的內容時,就會在當前映象層之上,建立新的映象層。
舉一個簡單的例子,假如基於Ubuntu Linux 16.04 建立一個新的映象,這就是映象的第一層;如果在該映象中新增Python包,就會在基礎映象層之上建立第二個映象層;如果繼續新增一個安全補丁,就會建立第三個映象層。
該映象當前已經包含三個映象層,如下圖所示(這只是一個用於演示的簡單的例子)
在新增額外的映象層的同時,映象始終保持當前所有映象的組合,理解這一點非常重要,下圖中舉了一個簡單的例子,每個映象層包含3個檔案,而映象包含了來自兩個映象層的6個檔案。
上圖中的映象層跟之前圖中的略有所區別,主要是便於展示檔案。
下圖中展示了一個稍微複雜的三層映象,在外部看來整個映象檔案只有6個,這是因為最上層的檔案7是檔案5的一個更新版本。
這種情況下,上層映象層中的檔案覆蓋了底層映象層中的檔案。這樣就使得檔案的更新版本作為一個新映象層新增到映象當中。
Docker通過儲存引擎(新版本採用快照機制)的方式來實現映象層堆疊,並保證多映象層對外展示為統一的檔案 系統。
Linux上可用的儲存引擎有AUFS、Overlay2、 Device Mapper、Btrfs 以及ZFS.顧名思義,每種儲存引擎都基於Linux 中對應的
檔案系統或者塊裝置技術,並且每種儲存引擎都有其獨有的效能特點。
Docker在Windows上僅支援windowsfilter 一種儲存引擎,該引擎基於NTFS檔案系統之上實現了分層和CoW[1]。
下圖展示了與系統顯示相同的三層映象。所有映象層堆疊併合並,對外提供統一的檢視。
特點
Docker映象都是隻讀的,當容器啟動後,一個新的可寫層被載入到映象的頂部!
這一層就是我們通常說的容器層,容器層之下的都交映象層。
我們所有的操作都是基於容器操作的。
在這幅圖中,我們可以看到,Docker 容器的生命週期裡分為五種狀態,其分別代表著:
Created:容器已經被建立,容器所需的相關資源已經準備就緒,但容器中的程式還未處於執行狀態。
Running:容器正在執行,也就是容器中的應用正在執行。
Paused:容器已暫停,表示容器中的所有程式都處於暫停 ( 不是停止 ) 狀態。
Stopped:容器處於停止狀態,佔用的資源和沙盒環境都依然存在,只是容器中的應用程式均已停止。
Deleted:容器已刪除,相關佔用的資源及儲存在 Docker 中的管理資訊也都已釋放和移除。
Commit 映象
docker commit 提交容器成為一個新的副本
# 命令和git原理類似
$ docker commit -m="提交的描述資訊" -a="作者" 容器id 目標映象名:[TAG]
實戰測試
1.啟動tomcat
$ docker run -it --name tomcat02 -p 8080:8080 tomcat:9.0
2.進入tomcat容器
$ docker exec -it tomcat02 /bin/bash
3.將操作過的容器通過commit提交為一個映象!我們之後就使用修改過的映象即可,這就是我們修改過的映象
$ docker commit -a="hudu" -m="add webapps app" a44a58b7174b tomcat02:1.0
如果想要儲存當前容器的狀態,可以通過commit來提交,獲得一個映象,就好比之前vm虛擬機器的快照
本作品採用《CC 協議》,轉載必須註明作者和本文連結