Docker小記-從容器構建鏡像

從容器構建鏡像

  • 步驟:
    • 根據最終想要的東西包選擇一個已存在的鏡像來創建一個容器。
    • 修改這個容器的文件系統。這些改動會被保存在容器的聯合文件系統的新文件層
    • 改動完成後將這些改動提交(commit)。一旦改動被提交,你就能夠從新鏡像創建新的容器了。
 // 這條命令會啓動一個運行bash shell的新容器。基於這個shell,你就能夠輸入命令來自定義你的容器了
 docker run -it -name image-dev ubuntu:latest /bin/bash
docker commit old_container_name new_container_name
  • 對容器內文件系統的改動都會被寫入到新的文件層中,這個文件層歸創建它的容器所有。(聯合文件系統(UFS)掛載提供了容器的文件系統)
  • Commit創建新鏡像:使用-a選項爲新鏡像指定作者的信息,使用-m選項,設置關於提交的信息
  • 啓動原始容器時附帶的命令會被提交到新鏡像中,入口點(entrypoint)是更好的做法
  • 一個入口點就是一個程序,它會在容器啓動時被執行。如果入口點沒有被設置,那麼默認的命令會被直接執行。如果入口點被設置,那麼默認的命令和它的參數就會作爲參數傳遞給入口點。
  • diff,它能夠顯示容器中文件系統的所有改動。這些改動包括添加、修改、刪除文件和目錄:
    • A開頭的行表示文件被添加。以C開頭表示修改,以D開頭表示刪除。

深入聯合文件系統

  • 聯合文件系統由多個層組成。每當對聯合文件系統改動一次,改動會被記錄到一個新的層中,這個新層放置於所有層的最上面。容器(和用戶)訪問文件系統所看到的,就是所有這些層的“聯合”,或者說是自上而下的觀察角度。
  • 當你從聯合文件系統讀取一個文件時,系統會從存在該文件的、最上面的一層中讀取。如果文件沒有在最頂層被創建或者改動,那麼讀取操作就會沿着層不斷向下找,直到找到存在這個文件的層。
  • 文件修改和刪除也通過修改最頂層來工作的。當一個文件被刪除,一個刪除記錄就被寫入到最頂層,它遮擋了底層該文件的所有版本。當一個文件被修改,修改也被寫入到最頂層,它也同樣遮擋了底層所有該文件的版本。聯合文件系統實際上上會在最頂層添加一個文件來標記一個文件被刪除。原始的文件和任何文件副本依舊保留在鏡像的其他層中。
  • 當只讀層(read-only layer)上一個文件被修改了,那麼這整個文件會在改動發生之前被複制到最上面的可寫層(writable layer)。這對運行時性能和鏡像的大小會有負面影響
  • 層包含這一層的改動信息和元數據。當你向容器的文件系統提交容器的改動時,你也是以同樣的方式保存了最頂層的一個副本。
  • 當你提交一層時,一個新的ID會爲這一層創建,所有文件改動的副本都會被保存,新層的元數據包含了之前生成的ID,還有更低一層的層ID(父層),還有新層被創建時的執行上下文(execution context)。
  • 層ID和元數據形成了一個圖,Docker和聯合文件系統(UFS)使用這個圖來構造鏡像。從某些起始層開始,遍歷尋找到它們的依賴層,然後這些層以棧的形式構造成鏡像。
  • 如果你想要複製一個鏡像,那麼你只需要從現有的鏡像創建一個新的標籤或倉庫。你可以使用docker tag命令來完成。
  • 創建容器會創建一個可寫層,所有在可寫層下面的層都是不可變的,
  • 聯合文件系統可能有一個層數量的限制。這個限制取決於文件系統,但42層限制在使用AUFS系統的計算機上是非常常見的。
  • docker history命令來查看一個鏡像的所有層。輸出內容包含以下內容:
    • 縮寫的層ID
    • 層的年齡
    • 創建容器時的初始命令
      -這一層的全部文件大小
  • 層系統使其可以返回到某個鏡像歷史節點,並且使創建新分支變得更加簡單方便。使用層系統來創建分支,這能夠同時解決鏡像大小和層增長問題。(每當你從同一個鏡像創建一個容器,你就潛在地創建了一個新的分支)
  • socker export命令會將扁平的聯合文件系統的所有內容導出到標準輸出或者一個壓縮文件上。輸出信息包含了所有從容器角度能夠觀察到的文件。(如果你需要在容器上下文外使用鏡像中的文件系統,這是非常有幫助的。)也可以使用 docker cp 命令來完成這個目標(但如果你想要多個文件,導出整個文件系統可能是更直接的辦法)
  • docker import命令會將壓縮格式的內容導入到一個新鏡像中。import命令能夠識別多種壓縮或未壓縮的壓縮文件格式。

相關鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章