Docker鏡像分層的實(shí)現(xiàn)示例
docker鏡像分層
Docker 鏡像由一些松耦合(關(guān)系不怎么緊密)的只讀鏡像層組成,Docker Daemon 負(fù)責(zé)堆疊這些鏡像層,并將它們關(guān)聯(lián)為一個(gè)統(tǒng)一的整體,即對(duì)外表現(xiàn)出的是一個(gè)獨(dú)立的對(duì)象。
介紹
Docker 鏡像采用分層結(jié)構(gòu)來(lái)構(gòu)建和管理,這是其輕量、高效和可復(fù)用性的關(guān)鍵。鏡像的分層結(jié)構(gòu)使得 Docker 鏡像在構(gòu)建、部署和更新過(guò)程中非常靈活,同時(shí)節(jié)省存儲(chǔ)空間和下載時(shí)間。下面是 Docker 鏡像分層的詳細(xì)介紹:
只讀分層:
Docker 鏡像由多個(gè)只讀的文件系統(tǒng)層組成,每個(gè)分層包含了一個(gè)或多個(gè)文件或目錄的更改。這些分層按照從底部到頂部的順序疊加在一起,形成了一個(gè)完整的鏡像。底部的分層通常是一個(gè)基礎(chǔ)操作系統(tǒng)的根文件系統(tǒng),而頂部的分層包含了應(yīng)用程序代碼和配置等信息。由于每個(gè)分層是只讀的,所以鏡像在創(chuàng)建后不會(huì)被更改。
聯(lián)合文件系統(tǒng):
Docker 使用聯(lián)合文件系統(tǒng)(UnionFS)技術(shù)將多個(gè)只讀分層組合成一個(gè)單一的虛擬文件系統(tǒng)。聯(lián)合文件系統(tǒng)使得各個(gè)分層看起來(lái)像是一個(gè)整體,使得鏡像中的每個(gè)分層的內(nèi)容在文件系統(tǒng)層次結(jié)構(gòu)中可見(jiàn),但實(shí)際上并不復(fù)制這些內(nèi)容。這樣的設(shè)計(jì)節(jié)省了存儲(chǔ)空間,并且可以在不同的鏡像之間共享公共層,從而加快鏡像的構(gòu)建和下載速度。
分層繼承:
Docker 鏡像支持分層繼承,這意味著可以基于現(xiàn)有的鏡像構(gòu)建新的鏡像。當(dāng)新的鏡像構(gòu)建時(shí),它只需在現(xiàn)有鏡像的基礎(chǔ)上添加新的分層,而不需要重新復(fù)制現(xiàn)有的分層。這種分層繼承的特性使得鏡像構(gòu)建變得高效和快速,并允許鏡像的復(fù)用。
可讀寫容器層:
當(dāng)基于鏡像創(chuàng)建一個(gè)容器時(shí),Docker 會(huì)在鏡像的頂部添加一個(gè)可讀寫的容器層。這個(gè)容器層允許容器在運(yùn)行時(shí)對(duì)文件系統(tǒng)進(jìn)行寫操作,例如應(yīng)用程序的日志輸出、數(shù)據(jù)庫(kù)文件等。容器層是臨時(shí)的,只在容器運(yùn)行時(shí)存在,當(dāng)容器停止時(shí),對(duì)容器層的修改也會(huì)被丟棄,保持鏡像的不可變性。
鏡像的復(fù)用和共享:
Docker 鏡像分層的結(jié)構(gòu)使得鏡像可以復(fù)用和共享。多個(gè)鏡像可以共享相同的基礎(chǔ)層,從而節(jié)省存儲(chǔ)空間,并減少鏡像拉取和構(gòu)建的時(shí)間。這對(duì)于持續(xù)集成、持續(xù)部署和分布式系統(tǒng)的部署非常有益。
總結(jié)來(lái)說(shuō),Docker 鏡像的分層結(jié)構(gòu)是一種高效、靈活和可復(fù)用的設(shè)計(jì),它使得 Docker 容器化應(yīng)用程序在不同的環(huán)境中可以輕松部署和運(yùn)行,同時(shí)節(jié)省了存儲(chǔ)空間和提高了構(gòu)建和下載速度。這種設(shè)計(jì)也促進(jìn)了 Docker 生態(tài)系統(tǒng)的發(fā)展和鏡像的共享,使得 Docker 成為一種廣泛使用的容器化技術(shù)。
例子
通過(guò) docker pull 命令拉取指定的鏡像時(shí),每個(gè) Pull complete 結(jié)尾的行就代表下載完畢了一個(gè)鏡像層。
[root@docker ~]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx a2abf6c4d29d: Already exists a9edb18cadd1: Pull complete 589b7251471a: Pull complete 186b1aaa4aa6: Pull complete b4df32aa5a72: Pull complete a0bcbecc962e: Pull complete Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest
有些版本不一樣,但是他們的鏡像分層有些是一樣的。即不同鏡像對(duì)相同下層
鏡像的復(fù)用
[root@docker ~]# docker pull zookeeper:3.7.1-temurin 3.7.1-temurin: Pulling from library/zookeeper 9d19ee268e0d: Already exists 32db0ad82863: Already exists e01bb55fbcae: Already exists 297c6e3f57ee: Already exists 49c4f235b5f6: Already exists 82b2637e3748: Already exists
鏡像層構(gòu)成
Docker 鏡像是由一系列只讀的文件系統(tǒng)層構(gòu)成的,這些層會(huì)按特定順序疊加在一起,構(gòu)成一個(gè)完整的鏡像。鏡像層的設(shè)計(jì)使得 Docker 具有輕量、高效和可復(fù)用的特性。下面是 Docker 鏡像層構(gòu)成的詳細(xì)介紹:
基礎(chǔ)鏡像層:
Docker 鏡像的第一層是基礎(chǔ)鏡像層,它通常包含一個(gè)最小化的操作系統(tǒng),如Alpine Linux、Ubuntu、CentOS等。這個(gè)基礎(chǔ)鏡像提供了運(yùn)行應(yīng)用程序所需的最基本的文件和工具。基礎(chǔ)鏡像通常是公共或私有的,供其他鏡像構(gòu)建和擴(kuò)展使用。
應(yīng)用程序依賴層:
在基礎(chǔ)鏡像之上,Docker 可以添加應(yīng)用程序的依賴項(xiàng)和運(yùn)行時(shí)環(huán)境,這些依賴項(xiàng)可能包括軟件包、庫(kù)文件等。這些層用于支持應(yīng)用程序的執(zhí)行和運(yùn)行所需的軟件和工具。
應(yīng)用程序代碼層:
在依賴層之上,Docker 可以添加應(yīng)用程序的實(shí)際代碼和資源文件。這些層包含了應(yīng)用程序的源代碼、配置文件、靜態(tài)資源等。這使得 Docker 鏡像能夠完整地包含應(yīng)用程序的所有代碼。
只讀層:
鏡像的每個(gè)層都是只讀的,這意味著在構(gòu)建后,鏡像層的內(nèi)容不會(huì)再改變。這種設(shè)計(jì)有助于鏡像的高效性和可復(fù)用性。如果需要修改鏡像,Docker 將在現(xiàn)有層之上創(chuàng)建新的鏡像層,保持原有層的完整性。
共享相同層:
當(dāng)多個(gè)鏡像共享相同的基礎(chǔ)層時(shí),它們可以節(jié)省存儲(chǔ)空間和下載時(shí)間。因?yàn)檫@些鏡像只需在自己的特定層上添加差異層,而不是復(fù)制整個(gè)基礎(chǔ)鏡像。這使得鏡像的存儲(chǔ)和傳輸變得更加高效。
鏡像的唯一標(biāo)識(shí):
每個(gè)鏡像都有一個(gè)唯一的標(biāo)識(shí)符,稱為鏡像 ID,它是根據(jù)鏡像內(nèi)容生成的哈希值。鏡像 ID 是根據(jù)所有鏡像層的內(nèi)容計(jì)算得出的,即使一個(gè)鏡像只有一個(gè)小的改動(dòng),它的鏡像 ID 也會(huì)發(fā)生變化。這種特性有助于確保鏡像的唯一性和數(shù)據(jù)的完整性。
每個(gè)鏡像層由兩部分構(gòu)成:鏡像文件系統(tǒng)與鏡像 json 文件。這兩部分具有相同的 ImageID。鏡像文件系統(tǒng)就是對(duì)鏡像占有的磁盤空間進(jìn)行管理的文件系統(tǒng),擁有該鏡像所有鏡像層的數(shù)據(jù)內(nèi)容。而鏡像 json 文件則是用于描述鏡像的相關(guān)屬性的集合,通過(guò) docker inspect [鏡像]就可以直觀看到。
鏡像FS 構(gòu)成
Docker 鏡像的 FS(文件系統(tǒng))構(gòu)成是指鏡像是如何由多個(gè)只讀文件系統(tǒng)層疊加在一起的。鏡像的 FS 構(gòu)成具有聯(lián)合文件系統(tǒng)(UnionFS)的特點(diǎn),這使得 Docker 鏡像可以共享和重用底層層,并且能夠快速高效地創(chuàng)建新的鏡像。
下面是 Docker 鏡像 FS 構(gòu)成的詳細(xì)介紹:
分層結(jié)構(gòu):
Docker 鏡像由多個(gè)文件系統(tǒng)層組成,每個(gè)層包含一個(gè)或多個(gè)文件或目錄的更改。每一層都是只讀的,并且在創(chuàng)建后不會(huì)被更改。這種分層結(jié)構(gòu)是 Docker 鏡像的核心特點(diǎn)之一,它使得鏡像非常輕量且可共享。
鏡像層:
每個(gè) Docker 鏡像都由一個(gè)或多個(gè)鏡像層組成,這些層會(huì)按照特定的順序堆疊在一起。每個(gè)鏡像層都包含在上一個(gè)層基礎(chǔ)上的變更。這種分層結(jié)構(gòu)使得容器鏡像的構(gòu)建和分發(fā)變得高效,因?yàn)槊總€(gè)層都可以獨(dú)立地下載和使用。
Copy-on-Write:
Docker 使用了聯(lián)合文件系統(tǒng)的技術(shù)來(lái)實(shí)現(xiàn)鏡像的分層和構(gòu)成。這包括 Copy-on-Write(寫時(shí)復(fù)制)的特性。當(dāng)容器需要修改一個(gè)層中的文件時(shí),Docker 不會(huì)直接修改原始層,而是創(chuàng)建一個(gè)新的層,并在新層中存儲(chǔ)修改后的文件。這樣,只有發(fā)生更改的文件會(huì)在新層中存在,而其他文件仍然鏈接到原始層,節(jié)省了存儲(chǔ)空間。
鏡像的繼承:
Docker 鏡像的分層結(jié)構(gòu)使得鏡像可以基于現(xiàn)有鏡像創(chuàng)建。例如,如果你有一個(gè)基礎(chǔ)鏡像,并在其上添加了一些修改,Docker 只需創(chuàng)建一個(gè)新的層,其中包含這些修改,而不需要復(fù)制整個(gè)基礎(chǔ)鏡像。這使得容器鏡像的構(gòu)建非常高效,并允許鏡像的復(fù)用。
存儲(chǔ)驅(qū)動(dòng):
Docker 支持多種存儲(chǔ)驅(qū)動(dòng)來(lái)管理鏡像的 FS 構(gòu)成。常見(jiàn)的存儲(chǔ)驅(qū)動(dòng)有 OverlayFS、AUFS、Btrfs、DeviceMapper 等。不同的存儲(chǔ)驅(qū)動(dòng)可能在性能和特性上有所不同,你可以根據(jù)需求選擇適合你的存儲(chǔ)驅(qū)動(dòng)。
一個(gè) docker 鏡像的文件系統(tǒng) FS 由多層只讀的鏡像層組成,每層都完成了特定的功能。而這些只讀鏡像層根據(jù)其位置與功能的不同可分為兩類:基礎(chǔ)鏡像層與擴(kuò)展鏡像層。
基礎(chǔ)鏡像層
Docker 的基礎(chǔ)鏡像層是構(gòu)成 Docker 鏡像的核心組成部分之一。Docker 鏡像是由多個(gè)只讀的文件系統(tǒng)層疊加在一起構(gòu)成的,基礎(chǔ)鏡像層是這些層中的第一層。下面是基礎(chǔ)鏡像層的詳細(xì)介紹:
只讀的文件系統(tǒng)層:
基礎(chǔ)鏡像層是一個(gè)只讀的文件系統(tǒng)層,意味著一旦創(chuàng)建,就不能對(duì)其進(jìn)行更改。所有對(duì)基礎(chǔ)鏡像的更改都將作為上面的一系列可讀寫的鏡像層添加。這種分層的結(jié)構(gòu)是 Docker 鏡像輕量且高效的關(guān)鍵所在。
Dockerfile 中的 FROM 指令:
基礎(chǔ)鏡像是通過(guò) Dockerfile 文件中的 FROM 指令來(lái)指定的。FROM 指令定義了基于哪個(gè)現(xiàn)有鏡像構(gòu)建新鏡像。Docker 在構(gòu)建鏡像時(shí),會(huì)在指定的基礎(chǔ)鏡像之上創(chuàng)建新的只讀層,然后在其上添加其他層。
操作系統(tǒng)和軟件環(huán)境:
基礎(chǔ)鏡像通常包含操作系統(tǒng)(如 Ubuntu、Alpine、CentOS 等)以及一些最基本的軟件工具和運(yùn)行時(shí)庫(kù)。這些軟件環(huán)境為后續(xù)的鏡像層提供了一個(gè)穩(wěn)定的運(yùn)行基礎(chǔ)。
特定用途的基礎(chǔ)鏡像:
Docker 官方鏡像倉(cāng)庫(kù)和其他可信的鏡像倉(cāng)庫(kù)通常提供了許多特定用途的基礎(chǔ)鏡像,如數(shù)據(jù)庫(kù)鏡像、Web 服務(wù)器鏡像、編程語(yǔ)言運(yùn)行時(shí)環(huán)境鏡像等。這些基礎(chǔ)鏡像已經(jīng)配置好了特定的軟件和環(huán)境,使得用戶可以基于它們構(gòu)建和部署特定類型的應(yīng)用程序。
鏡像緩存:
Docker 鏡像構(gòu)建過(guò)程中,如果使用的基礎(chǔ)鏡像已經(jīng)存在于本地主機(jī)上,則 Docker 將從本地緩存中直接使用該鏡像,而不是重新下載或構(gòu)建。這樣可以節(jié)省時(shí)間和網(wǎng)絡(luò)帶寬。
基礎(chǔ)鏡像的選擇對(duì)于 Docker 鏡像的大小、性能、安全性和可維護(hù)性都有重要影響。因此,在選擇基礎(chǔ)鏡像時(shí),需要考慮以下幾點(diǎn):
- 選擇官方或經(jīng)過(guò)驗(yàn)證的發(fā)布者提供的鏡像,以確保鏡像的質(zhì)量和安全性。
- 盡量選擇小巧、輕量級(jí)的基礎(chǔ)鏡像,以減小鏡像的大小。
- 確?;A(chǔ)鏡像提供了適合你應(yīng)用程序的運(yùn)行環(huán)境和所需的依賴項(xiàng)。
所有鏡像的最下層都具有一個(gè)可以看得到的基礎(chǔ)鏡像層 Base Image,基礎(chǔ)鏡像層的文件系統(tǒng)稱為根文件系統(tǒng) rootfs。而 rootfs 則是建立在 Linux 系統(tǒng)中**“看不到的”引導(dǎo)文件系統(tǒng)bootfs 之上。
擴(kuò)展鏡像層
在 Docker 中,“擴(kuò)展鏡像層” 是指在一個(gè)現(xiàn)有的基礎(chǔ)鏡像上構(gòu)建新的鏡像層,以添加或修改容器所需的內(nèi)容和配置。Docker 使用分層文件系統(tǒng)的方式來(lái)管理鏡像,每個(gè)鏡像層都包含一個(gè)或多個(gè)文件或目錄的更改。當(dāng)你在現(xiàn)有的鏡像上進(jìn)行更改時(shí),Docker 會(huì)在原有的鏡像層之上創(chuàng)建一個(gè)新的鏡像層,這個(gè)過(guò)程就是所謂的 “擴(kuò)展鏡像層”。
下面是擴(kuò)展鏡像層的詳細(xì)介紹:
基礎(chǔ)鏡像:
擴(kuò)展鏡像層的起點(diǎn)是一個(gè)現(xiàn)有的基礎(chǔ)鏡像?;A(chǔ)鏡像通常是一個(gè)已經(jīng)構(gòu)建好的、可用于部署特定應(yīng)用程序的鏡像。這個(gè)基礎(chǔ)鏡像可以是 Docker 官方鏡像、第三方鏡像或者你自己構(gòu)建的鏡像。
創(chuàng)建 Dockerfile:
擴(kuò)展鏡像層的過(guò)程通常是通過(guò)創(chuàng)建一個(gè) Dockerfile 文件來(lái)完成的。Dockerfile 是一個(gè)文本文件,其中包含一系列的指令,用于定義新鏡像的構(gòu)建過(guò)程。Dockerfile 可以基于已有的基礎(chǔ)鏡像,然后在其上添加更改,以滿足特定的需求。
添加新的鏡像層:
Docker 會(huì)根據(jù) Dockerfile 中的指令逐步構(gòu)建新的鏡像。當(dāng) Docker 構(gòu)建過(guò)程遇到一個(gè)指令時(shí),它會(huì)在當(dāng)前鏡像層的基礎(chǔ)上創(chuàng)建一個(gè)新的鏡像層,并應(yīng)用該指令所描述的更改。這樣,新的鏡像層就被添加到了構(gòu)建過(guò)程中。
緩存機(jī)制:
Docker 在構(gòu)建過(guò)程中使用了緩存機(jī)制,這意味著當(dāng)一個(gè)指令沒(méi)有發(fā)生變化時(shí),Docker 將重用之前構(gòu)建的層,而不會(huì)重新創(chuàng)建。這樣可以提高構(gòu)建的速度和效率。
多層繼承:
在 Dockerfile 中,你可以利用多層繼承的特性,基于多個(gè)基礎(chǔ)鏡像構(gòu)建一個(gè)新的鏡像。這使得擴(kuò)展鏡像層的過(guò)程更加靈活,可以根據(jù)實(shí)際需求選擇不同的基礎(chǔ)鏡像,并在其上添加所需的更改。
不可變性:
鏡像層是不可變的,一旦創(chuàng)建后就不會(huì)更改。這意味著每次在擴(kuò)展鏡像層上做出的更改都會(huì)創(chuàng)建一個(gè)新的鏡像層,而原有的鏡像層保持不變。這有助于確保鏡像的穩(wěn)定性和可重現(xiàn)性。
在基礎(chǔ)鏡像層之上的鏡像層稱為擴(kuò)展鏡像層。顧名思義,其是對(duì)基礎(chǔ)鏡像層功能的擴(kuò)展。在 Dockerfile 中,每條指令都是用于完成某項(xiàng)特定功能的,而每條指令都會(huì)生成一個(gè)擴(kuò)展鏡像層。
容器層
Docker 的容器層是 Docker 容器的一個(gè)核心概念,它是 Docker 鏡像的運(yùn)行實(shí)例。當(dāng)你從 Docker 鏡像創(chuàng)建一個(gè)容器時(shí),Docker 在鏡像的基礎(chǔ)上添加了一個(gè)可寫的容器層,用于存儲(chǔ)容器運(yùn)行時(shí)的變更和數(shù)據(jù)。容器層與鏡像層相互結(jié)合,使得容器能夠在鏡像的基礎(chǔ)上添加或修改文件、運(yùn)行進(jìn)程,并保留這些更改,而不影響基礎(chǔ)鏡像的原始內(nèi)容。
下面是容器層的詳細(xì)介紹:
可寫性:
容器層是一個(gè)可讀寫的文件系統(tǒng)層,它允許在容器運(yùn)行時(shí)修改和保存數(shù)據(jù)。容器中的進(jìn)程可以向容器層添加、修改或刪除文件,這些更改將僅影響容器本身,而不會(huì)影響基礎(chǔ)鏡像或其他容器。
聯(lián)合文件系統(tǒng):
容器層使用聯(lián)合文件系統(tǒng)(UnionFS)技術(shù),它允許將多個(gè)文件系統(tǒng)合并到一個(gè)單一的文件系統(tǒng)中。Docker 使用聯(lián)合文件系統(tǒng)來(lái)將容器層和基礎(chǔ)鏡像層組合在一起,以形成容器的完整文件系統(tǒng)視圖。
輕量和高效:
容器層是基于鏡像層的增量修改,這使得容器非常輕量且高效。因?yàn)槿萜髦槐4媾c基礎(chǔ)鏡像的差異,所以它們通常只需要很少的磁盤空間,并且在創(chuàng)建和啟動(dòng)時(shí)非??焖?。
容器生命周期:
當(dāng)容器運(yùn)行時(shí),容器層處于活動(dòng)狀態(tài)。容器內(nèi)的進(jìn)程可以讀取和寫入容器層的文件系統(tǒng),并在運(yùn)行時(shí)進(jìn)行修改。當(dāng)容器停止后,容器層仍然存在,但它將保持在停止的狀態(tài),并且可以隨時(shí)重新啟動(dòng)和使用。
臨時(shí)性:
容器層是臨時(shí)的,任何對(duì)容器的更改都只存在于容器的生命周期中。如果容器被刪除,容器層中的所有數(shù)據(jù)和修改也會(huì)被丟棄。這使得容器可以非常容易地重新創(chuàng)建和重置。
持久化數(shù)據(jù):
盡管容器層通常是臨時(shí)的,但通過(guò)掛載主機(jī)目錄或使用數(shù)據(jù)卷,可以實(shí)現(xiàn)容器數(shù)據(jù)的持久化。持久化數(shù)據(jù)不存儲(chǔ)在容器層中,而是存儲(chǔ)在主機(jī)的文件系統(tǒng)中或者專門管理的 Docker 數(shù)據(jù)卷中,這樣即使容器被刪除,數(shù)據(jù)仍然保留。
一旦鏡像運(yùn)行了起來(lái)就形成了容器,而容器就是一個(gè)運(yùn)行中的 Linux 系統(tǒng),其也是具有文件系統(tǒng)的。容器的這個(gè)文件系統(tǒng)是在 docker 鏡像最外層之上增加了一個(gè)可讀寫的容器層,對(duì)文件的任何更改都只存在于容器層。因此任何對(duì)容器的操作都不會(huì)影響到鏡像本身。
容器層如果需要修改某個(gè)文件,系統(tǒng)會(huì)從容器層開(kāi)始向下一層層的查找該文件,直到找到為止。任何對(duì)于文件的操作都會(huì)記錄在容器層。例如,要修改某文件,容器層會(huì)首先把在鏡像層找到的文件 copy 到容器層,然后再進(jìn)行修改。刪除文件也只會(huì)將存在于容器層中的文件副本刪除。
可以看出,Docker 容器就是一個(gè)疊加后的文件系統(tǒng),而這個(gè)容器層稱為 Union File System,聯(lián)合文件系統(tǒng)。
鏡像摘要
每個(gè)鏡像都有一個(gè)長(zhǎng)度為 64 位的 16 進(jìn)制字符串作為其摘要 digest。
介紹
Docker 鏡像摘要是指鏡像的摘要信息,通常被稱為鏡像的 Digest。它是鏡像內(nèi)容的唯一標(biāo)識(shí)符,類似于 Git 中的 SHA 值,用于確保鏡像的完整性和唯一性。摘要是一個(gè)由算法計(jì)算得出的長(zhǎng)字符串,它代表了鏡像內(nèi)容的具體信息,包括鏡像層和配置信息。
以下是 Docker 鏡像摘要的詳細(xì)介紹:
唯一性:
Docker 鏡像摘要是由 SHA256 算法計(jì)算得出的,因此它是唯一的。不同的鏡像內(nèi)容必定會(huì)產(chǎn)生不同的摘要值。這保證了鏡像的唯一性,可以避免兩個(gè)鏡像在不同的倉(cāng)庫(kù)或環(huán)境中具有相同的名稱和標(biāo)簽,但內(nèi)容實(shí)際上是不同的。
完整性驗(yàn)證:
摘要值可以用來(lái)驗(yàn)證鏡像的完整性。當(dāng)你從 Docker 鏡像倉(cāng)庫(kù)拉取鏡像時(shí),Docker 會(huì)根據(jù)摘要值來(lái)檢查鏡像內(nèi)容是否完整。如果鏡像內(nèi)容在傳輸過(guò)程中發(fā)生了任何變化,摘要值將會(huì)不匹配,Docker 將會(huì)拒絕使用這個(gè)鏡像。
不可篡改性:
鏡像摘要是根據(jù)鏡像內(nèi)容計(jì)算得出的,任何對(duì)鏡像內(nèi)容的修改都會(huì)導(dǎo)致摘要值的改變。因此,鏡像摘要具有不可篡改性,可以保護(hù)鏡像的完整性和安全性。
使用摘要拉取鏡像:
你可以使用鏡像的摘要值來(lái)拉取鏡像,而不僅僅使用標(biāo)簽。這在確保你拉取的是特定版本的鏡像時(shí)非常有用。使用摘要值拉取鏡像的格式為:**docker pull <image-name>@<digest>**
鏡像更新:
鏡像的摘要值是基于鏡像內(nèi)容計(jì)算的,因此,當(dāng)鏡像內(nèi)容發(fā)生更改時(shí),摘要值也會(huì)隨之改變。這意味著每次更新鏡像時(shí),都會(huì)產(chǎn)生一個(gè)新的摘要值。
摘要,即 digest,是鏡像內(nèi)容的一個(gè) Hash 值,即所謂的 Content Hash(內(nèi)容散列)。只要鏡像內(nèi)容發(fā)生了變更,其內(nèi)容散列值就一定會(huì)發(fā)生改變。也就是說(shuō),一個(gè)鏡像一旦創(chuàng)建完畢,其 digest 就不會(huì)發(fā)生改變了,因?yàn)殓R像是只讀的。
Docker 默認(rèn)采用的 Hash 算法是 SHA256,即 Hah 值是一個(gè)長(zhǎng)度為 256 位的二進(jìn)制值。Docker 使用 16 進(jìn)制表示,即變?yōu)榱碎L(zhǎng)度為 64 位的字符串。
通過(guò) docker inspect 命令可以查看指定鏡像的詳細(xì)信息。其中就包含該鏡像的摘要信息。
[root@docker ~]# docker inspect nginx
通過(guò) docker images --digests 命令也可以查看到鏡像的摘要信息。
[root@docker ~]# docker images nginx --digests REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE nginx latest sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31 605c77e624dd 18 months ago 141MB
分發(fā)散列值
在 push 或 pull 鏡像時(shí),都會(huì)對(duì)鏡像進(jìn)行壓縮以減少網(wǎng)絡(luò)帶寬和傳輸時(shí)長(zhǎng)。但壓縮會(huì)改變鏡像內(nèi)容,會(huì)導(dǎo)致經(jīng)過(guò)網(wǎng)絡(luò)傳輸后,鏡像內(nèi)容與其 digest 不相符。出現(xiàn)問(wèn)題。(也就是在自己機(jī)器上進(jìn)行壓縮的hash值和傳輸?shù)絛ocker hub后hsah值不相同了,因?yàn)閭鬏數(shù)臅r(shí)候還會(huì)壓縮)
? 為了避免該問(wèn)題,Docker 又為鏡像配置了 Distribution Hash(分發(fā)散列值)。在鏡像被壓縮后立即計(jì)算分發(fā)散列值,然后使該值隨壓縮過(guò)的鏡像一同進(jìn)行發(fā)送。在接收方接收后,立即計(jì)算壓縮鏡像的分發(fā)散列值,再與攜帶的分發(fā)散列值對(duì)比。如果相同,則說(shuō)明傳輸沒(méi)有問(wèn)題
鏡像的hsah值和壓縮后的hash值會(huì)一起傳輸?shù)絛ocker hub
多架構(gòu)鏡像
Docker 多架構(gòu)鏡像(Multi-architecture Images)是指一種能夠在不同硬件架構(gòu)上運(yùn)行的 Docker 鏡像。傳統(tǒng)上,Docker 鏡像是為特定的硬件架構(gòu)(如x86、ARM等)構(gòu)建的,而多架構(gòu)鏡像則允許在不同的硬件架構(gòu)上共享和使用相同的鏡像。
下面是 Docker 多架構(gòu)鏡像的詳細(xì)介紹:
跨平臺(tái)支持:
Docker 多架構(gòu)鏡像允許在不同的硬件架構(gòu)上運(yùn)行相同的鏡像。這意味著你可以使用同一個(gè)鏡像構(gòu)建和部署應(yīng)用程序,而無(wú)需為不同的硬件架構(gòu)編寫和維護(hù)多個(gè)鏡像。
架構(gòu)選擇:
Docker 多架構(gòu)鏡像支持在構(gòu)建鏡像時(shí)選擇目標(biāo)架構(gòu)。這意味著你可以根據(jù)目標(biāo)平臺(tái)的硬件架構(gòu),選擇適當(dāng)?shù)幕A(chǔ)鏡像和依賴項(xiàng)來(lái)構(gòu)建鏡像。例如,你可以使用不同的 Dockerfile 和構(gòu)建過(guò)程來(lái)創(chuàng)建適用于 x86、ARM、ARM64 等不同架構(gòu)的鏡像。
Manifest List:
Docker 通過(guò)使用 Manifest List 來(lái)支持多架構(gòu)鏡像。Manifest List 是一個(gè)包含多個(gè)平臺(tái)的描述文件,它允許 Docker 客戶端根據(jù)當(dāng)前環(huán)境自動(dòng)選擇最合適的鏡像。Docker 客戶端會(huì)檢查當(dāng)前主機(jī)的架構(gòu),并根據(jù) Manifest List 中的信息拉取和使用對(duì)應(yīng)的鏡像。
跨架構(gòu)構(gòu)建:
Docker 多架構(gòu)鏡像的構(gòu)建過(guò)程通常涉及交叉編譯或使用具有原生支持多架構(gòu)構(gòu)建的工具鏈。這樣可以確保在一個(gè)架構(gòu)上構(gòu)建的鏡像可以在其他支持的架構(gòu)上運(yùn)行。
鏡像推送與拉?。?/strong>
Docker 多架構(gòu)鏡像可以通過(guò) Docker Hub 或私有鏡像倉(cāng)庫(kù)進(jìn)行推送和拉取。你可以將多架構(gòu)鏡像推送到 Docker Hub 的同一個(gè)倉(cāng)庫(kù)中,并通過(guò)標(biāo)簽來(lái)區(qū)分不同的架構(gòu)。Docker 客戶端會(huì)根據(jù)當(dāng)前架構(gòu)自動(dòng)選擇并拉取適合的鏡像。
Multi-architecture Image,即多架構(gòu)鏡像,是某中的某鏡像針對(duì)不同操作系統(tǒng)/系統(tǒng)架構(gòu)的不同鏡像實(shí)現(xiàn)。即多架構(gòu)鏡像中包含的鏡像的:都是相同的,但它們針對(duì)的操作系統(tǒng)/系統(tǒng)架構(gòu)是不同的
工作原理
Docker 的多架構(gòu)鏡像(Multi-architecture Images)是指在同一個(gè)鏡像中包含了多個(gè)不同硬件架構(gòu)的二進(jìn)制文件,使得同一個(gè)鏡像可以在多個(gè)不同架構(gòu)的計(jì)算機(jī)上運(yùn)行。這種機(jī)制使得在不同硬件平臺(tái)上部署和運(yùn)行容器變得更加靈活和便捷。下面是 Docker 多架構(gòu)鏡像的工作原理的詳細(xì)介紹:
多平臺(tái)構(gòu)建:
Docker 多架構(gòu)鏡像的工作原理涉及到多平臺(tái)構(gòu)建。在構(gòu)建過(guò)程中,通過(guò) Docker CLI 或構(gòu)建工具(如 Buildx)指定目標(biāo)平臺(tái)架構(gòu),然后 Docker 引擎會(huì)自動(dòng)根據(jù)目標(biāo)架構(gòu)進(jìn)行構(gòu)建。這意味著同一個(gè) Dockerfile 可以用于構(gòu)建多個(gè)不同架構(gòu)的鏡像。
平臺(tái)特定文件:
在多架構(gòu)鏡像中,鏡像的文件系統(tǒng)中可能包含了針對(duì)特定架構(gòu)的二進(jìn)制文件。這些文件通常存儲(chǔ)在不同的文件夾或路徑中,并使用與架構(gòu)相關(guān)的標(biāo)識(shí)。例如,Linux x86 架構(gòu)的文件可能存儲(chǔ)在 /x86 文件夾下,而 ARM 架構(gòu)的文件可能存儲(chǔ)在 /arm 文件夾下。
平臺(tái)標(biāo)簽和映射:
Docker 多架構(gòu)鏡像通過(guò)使用平臺(tái)標(biāo)簽和映射來(lái)管理不同架構(gòu)的鏡像文件。每個(gè)鏡像都可以包含一個(gè)或多個(gè)平臺(tái)標(biāo)簽,用于指示鏡像適用的架構(gòu)。標(biāo)簽的格式通常是 架構(gòu)-操作系統(tǒng)。例如,linux/amd64 表示適用于 x86 架構(gòu)的 Linux 操作系統(tǒng)。
平臺(tái)選擇策略:
在運(yùn)行容器時(shí),Docker 引擎會(huì)根據(jù)主機(jī)的架構(gòu)選擇最合適的鏡像進(jìn)行部署。它會(huì)根據(jù)主機(jī)的架構(gòu)和可用鏡像的架構(gòu)進(jìn)行匹配,并選擇匹配的鏡像來(lái)運(yùn)行容器。如果找不到完全匹配的鏡像,它會(huì)嘗試選擇最接近的架構(gòu)進(jìn)行運(yùn)行。
Manifest 文件:
多架構(gòu)鏡像還使用了 Docker Manifest 文件來(lái)存儲(chǔ)有關(guān)不同架構(gòu)的鏡像的元數(shù)據(jù)信息。Manifest 文件包含了不同平臺(tái)的映射關(guān)系、鏡像 ID 和 Digest 等信息。通過(guò) Manifest 文件,Docker 引擎能夠在運(yùn)行容器時(shí)自動(dòng)選擇合適的鏡像。
在 Docker Hub 中,鏡像的多架構(gòu)信息保存在 Manifest 文件中。在拉取鏡像時(shí),Docker會(huì)隨著 pull 命令將當(dāng)前 Docker 系統(tǒng)的 OS 與架構(gòu)信息一并提交給 Docker Hub。Docker Hub 首先會(huì)根據(jù)鏡像的:查找是否存在 Manifest。如果不存在,則直接查找并返回:鏡像即可;如果存在,則會(huì)在 Manifest 中查找是否存在指定系統(tǒng)/架構(gòu)的鏡像。如果存在該系統(tǒng)/架構(gòu),則根據(jù) Manifest 中記錄的地址找到該鏡像的位置。
到此這篇關(guān)于Docker鏡像分層的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)docker鏡像分層內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
docker實(shí)踐之容器的導(dǎo)入與導(dǎo)出
Docker技術(shù)為IT界帶來(lái)了巨大的改變,它使得云服務(wù)可以用來(lái)共享應(yīng)用和工作流程自動(dòng)化,使得應(yīng)用可以用組件快速組合,消除了開(kāi)發(fā)、品質(zhì)保證、產(chǎn)品環(huán)境間的摩擦。這篇文章我們將詳細(xì)的介紹docker容器的導(dǎo)入與導(dǎo)出,感興趣的朋友們下面來(lái)一起看看吧。2016-10-10利用Docker搭建Nexus私有倉(cāng)庫(kù)實(shí)現(xiàn)Maven私服
Maven大家應(yīng)該都比較熟了,我這里就用安卓人狂喜的Gradle來(lái)演示一下,在build.gradle中編寫腳本即可上傳,接下來(lái)通過(guò)本文給大家介紹下利用Docker搭建Nexus私有倉(cāng)庫(kù)實(shí)現(xiàn)Maven私服的問(wèn)題,感興趣的朋友一起看看吧2022-01-01Docker-Compose搭建Redis集群的實(shí)現(xiàn)教程
本文主要介紹了Docker-Compose搭建Redis集群的實(shí)現(xiàn)教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03Mac下部署springBoot項(xiàng)目到Docker中(demo)
本文通過(guò)一個(gè)簡(jiǎn)單的demo給大家分享Mac下部署springBoot項(xiàng)目到Docker的方法,感興趣的朋友一起看看吧2018-01-01