Docker Image


Docker 對 container 的使用基本是建立在 LXC 基礎之上,然而 LXC 存在的問題是難以移動,難以通過標准化的模板去制作、重建、復制和移動 container。

在以 VM 為基礎的虛擬化中,有 image 和 snapshot 可以用於 VM 的復制、重建以及移動的功能。

想要通過 container 來實現快速的大規模部署和更新,這些功能不可或缺。

在 Docker 0.7 中引入了 Storage Driver(儲存驅動), 現在已經支持 AUFS、Btrfs、Device Mapper、OverlayFS、ZFS、VFS。

 

一、儲存驅動

https://docs.docker.com/storage/storagedriver/select-storage-driver/

1.Union FileSystem

簡稱 Union FS(聯合文件系統),儲存驅動的一種。

一種分層、輕量級並且高性能的文件系統,它支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下。

特性:一次同時加載多個文件系統,但從外面看起來,只能看到一個文件系統,聯合加載會把各層文件系統疊加起來,這樣最終的文件系統會包含所有底層的文件和目錄。

2.Overlay2

Overlay2 是一種 Union FS,支持為每一個成員目錄(AKA branch)設定 readonly、readwrite 和 whiteout-able 權限。

通常 Union FS 有兩個用途:

  • 不借助 LVM, RAID 將多個 disk 和掛載到一個目錄下。
  • 將一個 readonly 的 branch 和一個 writeable 的 branch 聯合在一起,Live CD 正是基於此,可以允許在 OS image 不變的基礎上允許用戶在其上進行一些寫操作。

Docker 在 Overlay2 上構建的 container image 也正是如此。

OverlayFS 將單個 Linux 主機上的兩個目錄分層,並將它們顯示為單個目錄。這些目錄稱為層,統一過程稱為聯合安裝。

Overlay2 原生支持多達 128 OverlayFS 層。

下圖顯示了 Docker鏡像 和 Docker容器 的分層方式。圖像層是 lowerdir,容器層是 upperdir。統一視圖通過一個被稱為 merged 容器掛載點的目錄公開。

 

二、Linux 系統啟動

典型的 Linux 啟動到運行需要兩個FS - bootfs + rootfs (從功能角度而非文件系統角度)

bootfs(boot file system):

主要包含 bootloader 和 kernel,bootloader 主要是引導加載 kernel,當 kernel 被加載到內存中后,bootfs 就被 umount 了,此時內存的使用權已由 bootfs 轉交給 kernel。

rootfs (root file system) :

在 bootfs 之上。包含的就是典型 Linux 系統中的 /dev、/proc、/bin、/etc 等標准目錄和文件。

由此可見對於不同的 linux 發行版,bootfs 基本是一致的,rootfs 會有差別,,因此不同的發行版可以公用 bootfs。如下圖:

 

 

三、Docker image 結構

典型的 Linux 在啟動后,首先將 rootfs 置為 readonly,進行一系列檢查, 然后將其切換為 "readwrite" 供用戶使用。

在 Docker 中,起初也是將 rootfs 以 readonly 方式加載並檢查,然而接下來利用 union mount 將一個 readwrite 文件系統掛載在 readonly 的 rootfs 之上,並且允許再次將下層的 file system 設定為 readonly,並且向上疊加。

這樣一組 readonly 和一個 writeable 的結構構成一個 container 的運行目錄,每一個被稱作一個 Layer。如下圖:

得益於 AUFS 的特性,每一個對 readonly 層文件或目錄的修改都只會存在於上層的 writeable 層中。

這樣,由於不存在競爭, 多個 container 可以共享 readonly 的 layer。

所以 docker 將 readonly 的層稱作 image,對於 container 而言整個 rootfs 都是 read-write 的,但事實上所有的修改都寫入最上層的 writeable 層中。

image 不保存用戶狀態,可以用於模板、重建和復制。

某個鏡像:

基於該鏡像創建的容器:

上層的 image 依賴下層的 image,因此 docker 中把下層的 image 稱作父 image,沒有父 image 的 image 稱作 base image。

因此想要從一個 image 啟動一個 container,docker 會先加載其父 image 直到 base image,用戶的進程運行在 writeable 的 layer 中。

所有 parent image 中的數據信息以及 ID、網絡和 lxc 管理的資源限制等具體 container 的配置,構成一個 docker 概念上的 container。如下圖:

Docker image 采用分層結構的好處

共享資源,節省存儲空間:有多個鏡像都從相同的 base 鏡像構建而來,那么宿主機只需在磁盤上保存一份 base 鏡像,同時內存中也只需加載一份 base 鏡像,就可以為所有容器服務了。而且鏡像的每一層都可以被共享。

快速部署:如果要部署多個 container,base image 可以避免多次拷貝。

內存更省:因為多個 container 共享 base image,以及 OS 的 disk 緩存機制,多個 container 中的進程命中緩存內容的幾率大大增加。

升級更方便:相比於 copy-on-write 類型的文件系統,base-image 也是可以掛載為可 writeable 的,可以通過更新 base image 而一次性更新其之上的 container。

允許在不更改 base-image 的同時修改其目錄中的文件,所有寫操作都發生在最上層的 writeable 層中。

 

四、Docker 鏡像 commit

docker commit 提交容器副本使之成為一個新的鏡像

# docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要創建的目標鏡像名:[標簽名]

# 下載鏡像
docker pull tomcat
# 啟動鏡像
docker run -d -p 8080:8080 tomcat
# 查看容器ID
docker ps -a
# 進入容器
docker exec -it a41c393cfa45 /bin/bash
# 刪除 tomcat
rm -rf /usr/local/tomcat/webapps/*
# 退出容器
exit
# 生成新鏡像
docker commit -m=“沒有webapps的tomcat鏡像” -a=“jhxxb” a41c393cfa45 jhxxb/tomcat-del:1.0
# 查看生成的新鏡像
docker images

# 運行新鏡像(需要指定版本,默認為 latest)
docker run -d -p 8080:8080 jhxxb/tomcat-del:1.0

可以看到新鏡像的 webapps 目錄下沒有文件


http://tiewei.github.io/cloud/Docker-Getting-Start/

https://docs.docker.com/storage/storagedriver/overlayfs-driver/#how-the-overlay2-driver-works


免責聲明!

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



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