Ⅰ Docker鏡像
1.像一個文件聯合系統UnionFS,是一種分層、輕量級並且高性能的文件系統,它支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下,Union 文件系統是 Docker 鏡像的基礎。鏡像可以通過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以製作各種具體的應用鏡像。
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 等標准目錄和文件
對於一個精簡的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序庫就可以了,因為底層直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可見對於不同的linux發行版, bootfs基本是一致的, rootfs會有差別, 因此不同的發行版可以公用bootfs。
3.鏡像分層的好處就是資源共享
列如:有多個鏡像都從相同的 base 鏡像構建而來,那麼宿主機只需在磁碟上保存一份base鏡像,
同時內存中也只需載入一份 base 鏡像,就可以為所有容器服務了。而且鏡像的每一層都可以被共享。
4.docker 鏡像都是只讀的,當容器啟動時,一個新的可寫層會載入到鏡像的頂部,這一層被稱為容器層,容器層之下都稱為鏡像層。
5.鏡像的構建可以通過 Dockfile 和docker commit 這兩種方式
docker commit 方式是在一個鏡像的基礎上,重新對該鏡像操作後重新生成的一個專屬的鏡像。
命令格式 docker commit -m "提交的描述信息" -a "作者信息" 容器ID 要創建的目標的鏡像名:[標簽名]
示例
Ⅱ 本地的鏡像文件都存放在哪裡
於Docker相關的本地資源存放在/var/lib/docker/目錄下,其中container目錄存放容器信息,graph目錄存放鏡像信息,aufs目錄下存放具體的鏡像底層文件。我推薦你去看看時速雲,他們是一家全棧雲原生技術服務提供商,提供雲原生應用及數據平台產品,其中涵蓋容器雲PaaS、DevOps、微服務治理、服務網格、API網關等。大家可以去體驗一下。 如果我的回答能夠對您有幫助的話,求給大大的贊。
Ⅲ windows7版本下的docker 鏡像文件存放位置在本地哪個文件夾
方案1, 使用參數-g 來修改 Docker 的鏡像存儲文件夾.
修改方法如下:
在 Ubuntu/Debian 系統下:
編輯 /etc/default/docker 文件, 添加-g 參數的設置, 如下:
DOCKER_OPTS="-dns 8.8.8.8 -dns 8.8.4.4 -g /mnt"
在 Fedora/Centos 系統下:
編輯 /etc/sysconfig/docker 文件, 添加-g 參數的設置, 如下:
other_args="-g /mnt"
重啟 Docker 服務, 問題就解決了.
方案2 使用鏈接
1) 停止 Docker: service docker stop.
2) 做個備份 tar -zcC /var/lib/docker > /mnt/var_lib_docker-backup-$(date + %s).tar.gz
3) 遷移/var/lib/docker目錄到met 目錄下: mv /var/lib/docker /mnt/docker
4) 建個 symlink: ln -s /mnt/docker /var/lib/docker
5) 確認文件夾類型為symlink 類型 ls /var/lib/docker
6) 啟動 docker service.
Ⅳ 介紹——修改cache.img(緩存鏡像)
緩存鏡像用於存儲系統或用戶應用產生的臨時數據,通常的鏡像文件名為chche.img。一般ROM並不需要包含緩存鏡像,不過在這里還是介紹一下如何製作和刷緩存鏡像。
緩存鏡像實際上就是一個空的ext4格式的文件系統鏡像,可以使用下面的命令生成緩存鏡像。
mkdir -p /mnt/rom/cache
make_ext4fs -s -l 256M -a cache cache.img /mnt/rom/cache
可以使用下面的命令刷緩存鏡像。
adb reboot bootloader
fastboot flash cache cache.img
fastboot reboot
Ⅳ Docker鏡像存儲格式分析
新版本的docker鏡像存儲其實是很繞的,各種ID和目錄定義較多,不是很直觀,本文較詳細的分析一下鏡像本地存儲和在registry存儲的格式。測試用的docker版本是20.10.9,存儲引擎overlay2。
為了方便分析鏡像層級結構,我們基於ubuntu加兩個文件,使用 docker build -t myubuntu . 創建一個新鏡像myubuntu。
鏡像元數據存儲在 /var/lib/docker/image/overlay2 :
imagedb目錄存儲的是鏡像元數據。
鏡像ID是從Image Json文件得到的,即 sha256sum(ImageJson)。
Layer DiffID是沒有壓縮的對應層的tar文件的sha256sum值。當然,打包和截包文件的適合得保證是可以可重復操作的,不然會導致Layer的DiffID出錯(可以使用tar-split保存tar headers)。比如上面例子中ubuntu鏡像只有一層,diff_ids列表只有 (history裡面的CMD不佔磁碟空間) "sha256:"。每一層的tar文件我們可以通過 docker save ubuntu -o ubuntu.tar 得到,解壓ubuntu.tar後可以得到對應的層級的打包後的layer.tar文件,如下可以驗證DiffID的值計算原理。
ChainID用於標識鏡像層級棧,它的值由DiffID計算得來。ChainID對應的layer目錄是 /var/lib/docker/image/overlay2/layerdb/sha256 ,這下面的目錄就是ChainID,其中內容存儲了鏡像的層級棧關系。比如這一層的parent是什麼,以及對應的鏡像數據存儲目錄的cache_id。本身layerdb只是存儲layer的元數據信息,並不存儲實際鏡像數據。
即最底層的ChainID跟DiffID一樣,而其他層的ChainID則是通過計算從最底層到這層的Digest得到。
查看Image Json文件可以看到myubuntu相比ubuntu的diff_ids加了兩層,imagedb目錄下面也多了兩個鏡像元數據信息文件,對應新增加的兩層鏡像。
除了之前的350f...對應ubuntu,其中7c7e是one.txt那層,而a58f則是two.txt那層。
我們可以看下ChainID目錄下的內容,可以看到除了ubuntu的基礎層,其他層都有一個文件parent,值就是父層的diff_id,diff是diff_id值,cache-id則是鏡像實際存儲目錄,位於 /var/lib/docker/overlay2/{cache-id} ,size是這一層實際增加文件的大小,tar-split.json.gz是打包這層鏡像的配置(參考 https://github.com/vbatts/tar-split )。
CacheID是一個uuid值,每次都不一樣。它對應的目錄 /var/lib/docker/overlay2/${CacheID} ,該目錄存儲了鏡像每層文件和下一層的鏈接等。驗證一下:
其中diff目錄下面便是這一層的文件。link是對應的diff目錄的短鏈接,lower則是下一層diff目錄的短鏈接。
在layerdb目錄的size文件可以看到每一層的鏡像大小,但是加起來跟 docker images 顯示的大小會有點差距,比如myubuntu鏡像每一層計算加起來是 4 + 65593591 + 4 = 65593599 / 1024 / 1024 = 62.55MiB ,實際顯示是 65.6MB,這是因為 docker images 裡面計算是按 65593599/1000/1000=65.59 計算的。
另外,因為鏡像每層記錄的是相對前一層的文件變化,即便刪除了文件和軟體包,新鏡像大小也不會變小。除非使用 docker export 重新導出一個新鏡像。
這個目錄存儲的是layer diffid和digest的關系,其中digest是鏡像倉庫裡面的目錄ID。
其中 v2metadata-by-diff存儲了layer diffid對應在鏡像倉庫的信息,包括digest,sourcerepository等。
diffid-by-digest則是反過來的,文件名是倉庫裡面的layer digest,內容是layer diffid。因為我們新加的鏡像myubuntu並沒有push到倉庫,所以這個目錄下面沒有信息。
我們創建一個本地的registry,然後對myubuntu另外打個tag, docker tag myubuntu 127.0.0.1:5000/myubuntu ,則respositories.json會多一條新的記錄。此時,distribution目錄還沒有變化。
當我們執行 docker push 127.0.0.1:5000/myubuntu ,則會發現distribution的兩個目錄分別多了兩條記錄,對應的是myubuntu的 7c7e... 和 a58f... 兩個diffid。此時repository.json裡面 127.0.0.1:5000/myubuntu 會多一條帶digest的記錄,這就是鏡像倉庫裡面對應的digest。其中push時顯示的 digest:sha256:bb3c... 對應的是registry的manifest文件的digest,下一節分析。
registry中存儲的鏡像文件是經過gzip壓縮,比如myubuntu本地大小是65.6MB,推到registry壓縮後大小約27MB,壓縮比還是不錯的。registry存儲目錄如下,主要分為blobs和repositories兩個目錄。
repositories的一級子目錄是鏡像名,這里是myubuntu。下面對應三個子目錄 _manifests,_layers, _uploads。
blobs存儲的內容除了各鏡像layer的壓縮後的文件,還包括Manifest Json和Image Json文件(未壓縮)。
選一個layer的壓縮文件data解壓看一下內容:
另外需要注意的是, docker pull 時前面顯示的值是對應層在registry的壓縮文件的digest值,並不是layer diffid,size也是registry存儲的壓縮文件大小。