<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] # <span style="font-size:15px">**Docker鏡像的核心原理一:鏡像的存儲和管理方式**</span> ## <span style="font-size:15px">**鏡像的設計**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一個鏡像都由多個鏡像層組成。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;為了區別鏡像層,Docker為每個鏡像層都計算了UUID,根據鏡像層中的數據使用加密哈希算法生成UUID。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所有鏡像層和容器層都保存在宿主機的文件系統/var/lib/docker/中,由存儲驅動進行管理。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在下載鏡像時,Docker Daemon會檢查鏡像中的鏡像層與宿主機文件系統中的鏡像層進行對比,如果存在則不下載,只下載不存在的鏡像層。 ![](https://img.kancloud.cn/e6/9e/e69e0729db8e6d4e1d59d2ee6c3f2e00_623x370.png) ## <span style="font-size:15px">**棧層式管理鏡像層**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;docker 中存儲驅動用于管理鏡像層和容器層。不同的存儲驅動使用不同的算法和管理方式。在容器和鏡像管理中,使用的兩大技術是**棧式層管理和寫時復制。** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dockerfile中的每一條指令都會對應于Docker鏡像中的一層,因此在docker build完畢之后,鏡像的總大小將等于每一層鏡像的大小總和。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每個鏡像都由多個鏡像層組成,從下往上以棧的方式組合在一起形成容器的根文件系統,Docker的存儲驅動用于管理這些鏡像層,對外提供單一的文件系統。Docker 的鏡像實際上由一層一層的文件系統組成,這種層級的文件系統叫 UnionFS(聯合文件系統)。 > **由于聯合文件系統的存在,容器文件系統內容的大小不等于Docker鏡像大小。** ![](https://img.kancloud.cn/a0/88/a088fc60fc529c2b5a01f9606d9359ab_369x231.png) 由于聯合文件系統的存在,如果鏡像層是相同的,則不同的鏡像會共享該層。 如上圖中,鏡像A與鏡像B就共享第二層鏡像,使得A+B鏡像文件大小并不等于A+B鏡像占用宿主機存儲空間容量的大小。 `doker images`命令列出的鏡像體積總和并不能代表實際使用的磁盤空間,需要使用`docker system df`命令來代替。 <br> ### <span style="font-size:15px">**UnionFS (聯合文件系統)**</span> 聯合文件系統(UnionFS)是一種**分層**、輕量級并且高性能的文件系統,它支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下。 >**分層的原因:** >1. 分層最大的一個好處就是共享資源 >2. 有多個鏡像都從相同的base鏡像構建而來,那么宿主機只需在磁盤上保存一份base鏡像; >3. 同時內存中也只需加載一份base鏡像,就可以為所有容器服務了,而且鏡像的每一層都可以被共享。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;聯合文件系統是 Docker 鏡像的基礎。鏡像可以通過分層來進行繼承,基于基礎鏡像(沒有父鏡像),可以制作各種具體的應用鏡像。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;特性:一次同時加載多個文件系統,但從外面看起來,只能看到一個文件系統,聯合加載會把各層文件系統疊加起來,這樣最終的文件系統會包含所有底層的文件和目錄。 > 如圖,在下載鏡像時,也是一層一層下載的 ![](https://img.kancloud.cn/22/fe/22fe564d9ed93e3961864acfe6d1c660_693x182.png) # <span style="font-size:15px">**Docker鏡像的核心原理二:鏡像結構**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;要了解docker的鏡像結構,需要先對linux的文件系統結構有所了解。 ## <span style="font-size:15px">**linux文件系統結構**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Linux 文件系統由 `bootfs`和 `rootfs` 兩部分組成。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bootfs(boot file system) 主要包含 bootloader 和 kernel,bootloader 主要是引導加載 kernel(內核),當 kernel 被加載到內存中后 bootfs 就被 umount (卸載)了。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rootfs (root file system) 包含的就是典型 Linux 系統中的 /dev,/proc,/bin,/etc 等標準目錄和文件。rootfs就是各種Linux發行版。比如redcat、centOS。 ![](https://img.kancloud.cn/05/c2/05c2ac5198f3a8be072c4a8f35fc5eb3_681x464.png) ## <span style="font-size:15px">**docker鏡像結構**</span> ![](https://img.kancloud.cn/04/a4/04a4dc88522d13cba13089bcca714f41_430x324.png) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;docker的分層鏡像結構如圖所示,鏡像的最底層必須是一個啟動文件系統(`bootfs`)的鏡像層。`bootfs`的上層鏡像稱為根鏡像(`rootfs`)或者基礎鏡像(`Base Image`),它一般是操作系統,比如centos、debian或者Ubuntu。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用戶的鏡像必須構建在基礎鏡像之上。如圖所示, emacs鏡像層就是在基礎鏡像上安裝emacs創建出來的鏡像,在此基礎上安裝apache又創建了新的鏡像層。利用這個新的鏡像層啟動的容器里運行的是一個已經安裝好emacs和apache的Debian系統。 ## <span style="font-size:15px">**docker鏡像分層的理解**</span> 查看鏡像分層方式可以通過`docker image inspect [IMAGE]`命令。其中RootFS部分則是表示了分層信息。 ``` [root@iZbp1bum6107bp8mgzkeunZ ~]# docker image inspect redis [ { "Id": "sha256:53aa81e8adfa939348cd4c846c0ab682b16dc7641714e36bfc57b764f0b947dc", ... ... "RootFS": { "Type": "layers", "Layers": [ "sha256:ad6562704f3759fb50f0d3de5f80a38f65a85e709b77fd24491253990f30b6be", "sha256:49cba0f0997b2bb3a24bcfe71c7cbd6e9f6968ef7934e3ad56b0f1f9361b6b91", "sha256:309498e524b3e2da1f036d00cd5155e0b74cf9e1d964a3636c8ed63ca4a00d43", "sha256:f7c9b429437f7ada2d3d455ac4ea90ff38e0cb7ef2551b08d152264b74116309", "sha256:4dabdd56bbf16307e2328cb6ed1d42b0bb9b8f40551421271c0b38dc9a685dcc", "sha256:ea450ad6ef893e998f88a35dc9cc22f952c62b88d58f948344cf4eda1a6264fc" ] }, } ] ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所有的Docker鏡像都起始于一個基礎鏡像層,當鏡像修改或者新增新的內容時,就會在當前鏡像層之上,創建新的鏡像層。**即在添加額外的鏡像層的同時,鏡像始終保持是當前所有鏡像的組合**。docker通過存儲引擎(新版本采用快照機制)的方式實現鏡像層堆棧,并保證多個鏡像層對外展示為統一的文件系統。示例: ![](https://img.kancloud.cn/15/28/15280ae5bbf2f1631907fe4266341647_547x379.png) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;這個鏡像中包含了三個鏡像層,第一層有三個文件,第二層也有三個文件,第三層鏡像中僅有一個文件,且這個文件是對第二層鏡像中的文件5的一個更新版本。在這種情況下,上層鏡像層中的文件會覆蓋底層鏡像層的文件,這樣就使得文件的更新版本作為一個新的鏡像層添加到鏡像當中。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最后docker通過存儲引擎將所有鏡像層堆疊并合并,對外提供統一的視圖。 ![](https://img.kancloud.cn/ff/23/ff2301d18d0c7bf014cbc92be28985a6_626x180.png) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dockerfile中的操作對于鏡像分層的影響:**在鏡像構建過程中需要向鏡像寫入數據的時候會產生分層,一個寫操作指令產生一個分層**。 ``` // 實例,驗證Dockerfile中的操作對于鏡像分層的影響 // 第一步,簡單編寫一個Dockerfile,復制宿主機的文件到容器中,并且RUN 執行相關命令 [root@iZbp1bum6107bp8mgzkeunZ test]# cat Dockerfile FROM centos:7 # 寫指令-COPY、RUN COPY * /root/test/ RUN touch /etc/pidstst.log \ && yum -y install sysstat CMD /root/test/process.sh // 第二步,創建鏡像 [root@iZbp1bum6107bp8mgzkeunZ test]# docker build -f Dockerfile -t test . Sending build context to Docker daemon 4.096kB Step 1/4 : FROM centos:7 ---> eeb6ee3f44bd Step 2/4 : COPY * /root/test/ ---> 897bd9a5ead0 Step 3/4 : RUN touch /etc/pidstst.log && yum -y install sysstat ---> Running in 4b90b3c273b0 Step 4/4 : CMD /root/test/test.sh ---> Running in dd115ea2e7f7 Removing intermediate container dd115ea2e7f7 ---> 205226fedbc6 Successfully built 205226fedbc6 Successfully tagged test:latest // 查看創建的鏡像 [root@iZbp1bum6107bp8mgzkeunZ docker]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE test latest 205226fedbc6 12 minutes ago 407MB // 查看該鏡像的分層結構信息 // 所有的Docker鏡像都起始于一個基礎鏡像層,因此第一個layer為dockerfile中指定的基礎鏡像層 // 然后dockerfile中有多少個寫指令,就會有多少個lay。 這里是三個layer,跟dockerfile中剛好對應上。 [root@iZbp1bum6107bp8mgzkeunZ docker]# docker image inspect 205226fedbc6 ... "RootFS": { "Type": "layers", "Layers": [ "sha256:174f5685490326fc0a1c0f5570b8663732189b327007e47ff13d2ca59673db02", "sha256:114bd86a861ccc7b8fcc9c5702529d3e2df0fa7ad3e753e0ad072362db417e7c", "sha256:9759cbc1af5e6651027f437b3e902ab08725eda7fcf16cdeb5acc45cefb90a5b" ] } ... ``` # <span style="font-size:15px">**Docker鏡像的核心原理三:寫時復制策略(Copy On Write)**</span> >當某個容器修改了基礎鏡像的內容,比如 /bin文件夾下的文件,這時其他容器的/bin文件夾是否會發生變化呢? 答案是不會的。根據容器鏡像的寫時復制(Copy-on-Write)技術,某個容器對基礎鏡像的修改會被限制在單個容器內。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;寫時復制策略采用了共享和復制技術,**針對相同的數據系統只保留一份,所有操作都訪問這一份數據**。當有操作需要修改或添加數據時,操作系統會把這部分數據復制到新的地方再進行修改或添加,而其他操作仍然訪問原數據區數據,這項技術節約了鏡像的存儲空間,加快了系統啟動時間。 ![](https://img.kancloud.cn/25/fd/25fd9907a156275a2eb45dbf8e94d4f0_599x526.png) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如圖所示,當需要對鏡像中的文件進行修改時,會將文件復制到容器層進行修改,上層文件會覆蓋原始鏡像文件。**注意:該文件存在于容器層,容器重啟之后容器層重新建立,上一次容器運行時對于文件的修改全部丟失!** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;只有當需要修改時才復制一份數據,這種特性被稱作`Copy-on-Write`。可見,容器層保存的是鏡像變化的部分,不會對鏡像本身進行任何修改。 # <span style="font-size:15px">**Docker鏡像的核心原理四:內容尋址原理**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在docker中,內容尋址就是根據文件內容來索引對應的鏡像和鏡像層,實際上就是對于鏡像層的內容計算和校驗后生成一個內容哈希值,并作為這個鏡像層的唯一ID。在構造鏡像時,根據這個ID來索引鏡像層。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看