前言
學習狂神老師的 Docker 系列課程,並總結
鏡像是什么
- 鏡像是一種輕量級、可執行的獨立軟件保,用來打包軟件運行環境和基於運行環境開發的軟件
- 他包含運行某個軟件所需的所有內容,包括代碼、運行時庫、環境變量和配置文件
- 所有應用,都可以直接打包 docker 鏡像,就可以直接跑起來
如何得到鏡像
- 從遠程倉庫下載
- 別人拷貝給你
- 自己制作一個鏡像 DockerFile
UnionFs (聯合文件系統)
- Union文件系統(UnionFs)是一種分層、輕量級並且高性能的文件系統
- 他支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下
- Union文件系統是 Docker 鏡像的基礎
- 可以通過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以制作各種具體的應用鏡像
- 特性:一次同時加載多個文件系統,但從外面看起來,只能看到一個文件系統,聯合加載會把各層文件系統疊加起來,這樣最終的文件系統會包含所有底層的文件和目錄
Docker鏡像加載原理
- Docker 的鏡像實際上由一層一層的文件系統組成,這種層級的文件系統叫 UnionFS
- boots(boot file system)主要包含 bootloader 和 Kernel, bootloader 主要是引導加載 kernel, Linux 剛啟動時會加 bootfs 文件系統,在 Docker 鏡像的最底層是 boots,幾乎不變
- 這一層與我們典型的 Linux/Unix 系統是一樣的,包含 bootloader 和 Kernel
- 當 boot 加載完成之后,整個內核就都在內存中了,此時內存的使用權已由 bootfs 轉交給內核,此時系統也會卸載 bootfs
- rootfs(root file system),在 bootfs之上,包含的就是典型 Linux 系統中的 /dev、/proc/bin、/etc 等標准目錄和文件
- rootfs 就是各種不同的操作系統發行版,比如 Ubuntu, Centos 等等
平時我們安裝進虛擬機的 CentOS 都是好幾個G,為什么 Docker 這里才200M?
- 對於個精簡的 OS , rootfs 可以很小,只需要包合最基本的命令,工具和程序庫就可以了
- 因為底層直接用主機的 kernel,自己只需要提供 rootfs 就可以了
- 由此可見對於不同的 Linux 發行版, boots 基本是一致的, rootfs 會有差別,因此不同的發行版可以公用 bootfs
- 所以虛擬機啟動是分鍾級別,容器是秒級!
分層理解
下載鏡像的時候看到一層層下載就是分層
思考:為什么Docker鏡像要采用這種分層的結構呢?
- 最大的好處,我覺得莫過於資源共享了!
- 比如有多個鏡像都從相同的 Base 鏡像構建而來,那么宿主機只需在磁盤上保留一份 base 鏡像,同時內存中也只需要加載一份 base 鏡像
- 這樣就可以為所有的容器服務了,而且鏡像的每一層都可以被共享
- Already exists 代表宿主機已存在鏡像所需的文件,所以不再需要下載,直接使用即可
- Downloading 代表宿主機沒有所需的文件,所以需要下載,下載完之后就會存在宿主機,以后下載其他鏡像時如果用到這些文件就可以直接拿來用,不用二次下載了
如何查看鏡像分層?
docker inspect redis
能看到它分了六層,比如說第一層可能就是安裝 centos,后面幾層就是安裝 redis 所需的緩解經
關於鏡像分層的理解
- 所有的 Docker 鏡像都起始於一個基礎鏡像層,其實就是 rootfs,像 Ubuntu、CentOS
- 當進行修改或添加新的內容時,就會在當前鏡像層之上,創建新的鏡像層
栗子
- 基於 Ubuntu Linux16.04 創建一個新的鏡像,這就是新鏡像的第一層
- 如果在該鏡像中添加 Python包,就會在基礎鏡像層之上創建第二個鏡像層
- 如果繼續添加一個安全補丁,就會創健第三個鏡像層
- 該鏡像當前已經包含 3 個鏡像層
- 現在可以把它再次打包成一個新的鏡像(commit)提供給其他人下載,其他人 pull 下來之后就會有三層東西
重點
在添加額外的鏡像層的同時,鏡像始終保持是當前所有鏡像的組合
下圖中舉了一個簡單的例子,每個鏡像層包含3個文件,而鏡像包含了來自兩個鏡像層的6個文件
上圖中的鏡像層跟之前圖中的略有區別,主要目的是便於展示文件
下圖中展示了一個稍微復雜的三層鏡像,在外部看來整個鏡像只有6個文件,這是因為最上層中的文件7是文件5的一個更新版
這種情況下,上層鏡像層中的文件覆蓋了底層鏡像層中的文件
這樣就使得文件的更新版本作為一個新鏡像層添加到鏡像當中
存儲引擎
- Docker 通過存儲引擎(新版本采用快照機制)的方式來實現鏡像層堆棧,並保證多鏡像層對外展示為統一的文件系統
- Linux 上可用的存儲引撃有 AUFS、 Overlay2、 Device Mapper、Btrfs 以及 ZFS
- 每種存儲引擎都基於 Linux 中對應的文件系統或者塊設備技術,井且每種存儲引擎都有其獨有的性能特點
- Docker 在 Windows上僅支持 windowsfilter 一種存儲引擎,該引擎基於 NTFS 文件系統之上實現了分層和CoW
鏡像層合並
- 下圖展示了與系統顯示相同的三層鏡像
- 所有鏡像層堆並合井,對外提供統一的視圖
上面有查看 redis 鏡像的 layer 是 6 層,跟上圖差不多,6 個文件就是 6 個 layer
特點
- Docker 鏡像都是只讀的,當容器啟動時,一個新的可寫層加載到鏡像的頂部!
- 這一層就是我們通常說的容器層,容器之下的都叫鏡像層!