Docker 學習之 Docker 鏡像講解

鏡像是什麼

鏡像是一種輕量級、可執行的獨立的軟件包,用來打包軟件運行環境和基於運行環境開發的軟件,它包含運行某個軟件所需要的所有內容,包括代碼、運行時、庫、環境變量和配置文件。

所有的應用,直接打包 docker 鏡像,就可以直接跑起來!

如何得到鏡像:

  • 從遠程倉庫下載

  • 朋友拷貝給你

  • 自己製作一個鏡像 DockerFile

Docker鏡像加載原理

  • UnionsFS (聯合文件系統)

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 系統是一 樣的 ,包含 boot 加載器和內核。當 boot 加載完成之後整個內核就都在內存中了,此時內存的使用權已由 bootfs 轉交給內核,此時系統也會卸載 bootfs。

rootfs (root file system), 在 bootfs 之上。包含的就是典型 Linux 系統中的 /dev,/proc,/bin,/etc 等標準目錄和文件。rootfs 就是各種不同的操作系統發行版,比如 Ubuntu,Centos 等等。

平時我們安裝在虛擬機上的Centos都是幾個G,而Docker只有200M

[root@zhujixiang /]# docker images centos
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              470671670cac        4 months ago        237MB

對於一個精簡的 OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序庫就可以了,因爲底層直接用 Host 的 kernel,自己只需要提供 rootfs 就可以了。由此可見對於不同的 Iinux 發行版, bootfs 基本是一致的,rootfs 會有差別,因此不同的發行版可以公用 bootfs。

分層理解

分層的鏡像

[root@zhujixiang /]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
afb6ec6fdc1c: Already exists 
608641ee4c3f: Pull complete 
668ab9e1f4bc: Pull complete 
78a12698914e: Pull complete 
d056855f4300: Pull complete 
618fdf7d0dec: Pull complete 
Digest: sha256:ec277acf143340fa338f0b1a9b2f23632335d2096940d8e754474e21476eae32
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest

Docker鏡像採用分層結構的好處?

最大的好處,莫過於是資源共享了!比如有多個鏡像都從相同的 Base 鏡像構建而來,那麼宿主機只需在磁盤上保留一份 base 鏡像,同時內存中也只需要加載一份 base 鏡像,這樣就可以爲所有的容器服務了,而且鏡像的每一層都可以被共享。

查看鏡像的方分層的方式可以通過 docker image inspect

[root@zhujixiang /]# docker image inspect redis:latest
[
	// ......
        "RootFS": {
            "Type": "layers",
            "Layers": [
             "sha256:ffc9b21953f4cd7956cdf532a5db04ff0a2daa7475ad796f1bad58cfbaf77a07",
             "sha256:d4e681f320297add0ede0554524eb9106d8c3eb3a43e6e99d79db6f76f020248",
             "sha256:59bd5a888296b623ae5a9efc8f18285c8ac1a8662e5d3775a0d2d736c66ba825",
             "sha256:c112794a20c5eda6a791cbec8700fb98eab30671a2248ac7e2059b475c46c45f",
             "sha256:bf8b736583f08c02b92f8a75ac5ea181e4d74107876177caa80ddad8b6b57a72",
              "sha256:6ef422d19214800243b28017d346c7ab9bfe63cb198a39312d1714394b232449"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

理解

所有的 Docker 鏡像都起始於一個基礎鏡像層,當進行修改或增加新的內容時,就會在當前鏡像層之上,創建新的鏡像層。

舉一個簡單的例子,假如基於 Ubuntu Linux 16.04 創建一個新的鏡像,這就是新鏡像的第一層;如果在該鏡像中添加 Python包,就會在基礎鏡像層之上創建第二個鏡像層;如果繼續添加一個安全補丁,就會創建第三個鏡像層。

該鏡像當前已經包含3個鏡像層,如下圖所示(這只是一個用於演示的很簡單的例子)。

再添加額外鏡像層的同時,鏡像始終保持是當前所有鏡像的組合,(理解這一點非常重要)如下圖,每個鏡像層包含 3 個文件,而鏡像包含了來自兩個鏡像層的 6 個文件。

上圖中的鏡像層跟之前圖中的略有區別,主要目的是便於展示文件。

下圖中展示了一個稍微複雜的三層鏡像,在外部看來整個鏡像只有 6 個文件,這是因爲最上層中的文件 7 是文件 5 的一個更新版本。

這種情況下,上層鏡像層中的文件覆蓋了底層鏡像層中的文件。這樣就使得文件的更新版本作爲一個新鏡像層添加到鏡像當中。

Docker 通過存儲引擎(新版本採用快照機制)的方式來實現鏡像層堆棧,並保證多鏡像層對外展示爲統一的文件系統。

Linux 上可用的存儲引擎有AUFS、Overlay2、 Device Mapper、Btrfs 以及 ZFS。顧名思義,每種存儲引擎都基於Linux 中對應的文件系統或者塊設備技術,並每種存儲引擎都有其獨有的性能特點。

Docker 在 Windows 上僅支持 windowsfilter 一種存儲引擎,該引擎基於 NTFS 文件系統之上實現了分層和CoW[1]。

下圖展示了與系統顯示相同的三層鏡像。所有鏡像層堆疊併合並,對外提供統一的視圖。

特點:

Docker鏡像都是隻讀的,當容器啓動時,一個新的可寫層被加載到鏡像的頂部!

這一層通常就是我們說的容器層,容器之下的都叫鏡像層

commit鏡像

如何提交一個自己的鏡像 !

docker commit 提交一個容器成爲一個新的副本

docker commit -m="提交的描述信息" -a="作者" 容器id 目標鏡像名:[TAG]

測試:

# 1、啓動一個默認的tomcat

# 2、發現默認的 tomcat 是沒有 webapps 應用   鏡像的原因,官方的鏡像默認 webapps 裏面是沒有東西的

# 3、我自己拷貝了基本文件

# 4、將操作過的容器通過 commit 提交爲一個鏡像!以後即可使用自己修改過的鏡像

如果想要保存當前容器狀態,就可以通過 commit 來提交,獲得一個鏡像,類似於 VM 的快照

如果你能看到這裏,那麼恭喜你,你就可以說你的 Docker 已經入門了!

 PS:我只是一個剛剛開始學習 Docker 的小白,學習源自B站 遇見狂神說

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章