docker系列—聊一聊存儲驅動OverlayFS

OverlayFS

OverlayFS是一種現代的聯合文件系統,與AUFS類似,但是速度更快且實現更簡單。Docker爲OverlayFS提供了兩個存儲驅動程序:原始的overlay,更新的和更穩定的overlay2

前提條件

  • overlay2驅動程序支持Docker Engine - Community和Docker EE 17.06.02-ee5及以上,是推薦的存儲驅動程序。
  • Linux內核4.0或更高版本,或使用內核3.10.0-514或更高版本的RHEL或CentOS。如果使用一箇舊的內核,需要使用overlay驅動程序,這是不推薦的。
  • xfs支持的文件系統支持overlay和overlay2驅動程序,但只有啓用了d_type=true。
    使用xfs_info驗證ftype選項是否設置爲1。要正確格式化xfs文件系統,使用-n ftype=1標誌。
  • 更改存儲驅動程序會使本地系統上無法訪問現有的容器和鏡像。在更改存儲驅動程序之前,使用docker save來保存已經構建的任何鏡像,或者將它們推入docker Hub或私有註冊表,這樣就不需要在以後重新創建。

使用overlay或overlay2存儲驅動程序配置Docker

  1. 停止Docker。
    systemctl stop docker
    
  2. 編輯 vim /etc/docker/daemon.json ,切記,如果不止一項配置,需要 , 隔開
    {
      "storage-driver": "overlay2"
    }
    
    如果daemon.json文件包含格式錯誤的JSON,則Docker無法啓動。
  3. 啓動Docker。
    systemctl start docker
    
  4. 驗證守護程序正在使用overlay2存儲驅動程序。使用docker info命令並查找Storage Driver和 Backing filesystem。
    docker info
    
    Containers: 0
    Images: 0
    Storage Driver: overlay2
     Backing Filesystem: xfs
     Supports d_type: true
     Native Overlay Diff: true
    <output truncated>
    

overlay2驅動程序是如何工作的

在一個Linux主機上覆蓋兩個目錄,並將它們表示爲一個目錄。

這些目錄稱爲層,統一過程稱爲聯合掛載。

OverlayFS將下面的目錄稱爲lowerdir,上面的目錄稱爲upperdir。統一視圖通過其自己的目錄merged公開。
overlay2驅動程序本身最多支持128個較低的OverlayFS層。該功能爲與層相關的Docker命令(如Docker build和Docker committ)提供了更好的性能,並且消耗支持文件系統上的更少的inode。
在這裏插入圖片描述
當鏡像層和容器層包含相同的文件時,容器層“勝出”並掩蓋了鏡像層中相同文件的存在

創建一個容器,overlay驅動程序將代表鏡像頂層的目錄和容器的新目錄組合在一起。鏡像的頂層是覆蓋層中的下層,並且是隻讀的。容器的新目錄是upperdir,並且是可寫的。

磁盤上的鏡像和容器層

鏡像層
每個鏡像層在磁盤上都有自己的目錄,鏡像的ID和目錄ID不對應。
在這裏插入圖片描述
鏡像層目錄包含該層獨有的文件以及與較低層共享的數據的硬鏈接。這樣可以有效利用磁盤空間。

容器層
容器也存在於Docker主機文件系統下的磁盤上 /var/lib/docker/overlay/I。
在這裏插入圖片描述

容器如何使用overlay或overlay2進行讀寫

文件讀取

考慮三種情況

  • 該文件在容器層中不存在: 文件在容器中還不存在(upperdir),則從鏡像(lowerdir)中讀取該文件。這隻會帶來很少的性能開銷。
  • 該文件僅存在於容器層中: 文件存在於容器中(upperdir),而不在鏡像中(lowerdir),則直接從容器中讀取該文件。
  • 該文件同時存在於容器層和鏡像層: 文件存在於鏡像層和容器層中,則讀取該文件在容器層中的版本。容器層中的文件(upperdir)掩蓋了與鏡像層(lowerdir)同名的文件。

修改文件或目錄

考慮容器中的文件被修改的一些場景。

  • 第一次寫入文件: 容器第一次寫入現有文件時, 該文件在容器中不存在(upperdir)。overlay/overlay2驅動程序執行copy_up操作, 將文件從鏡像(lowerdir)複製到容器(upperdir)。然後容器將更改寫入容器層中文件的新副本。

    但是,OverlayFS是在文件級別而不是塊級別工作的。這意味着所有的OverlayFS copy_up操作都會複製整個文件,即使文件非常大,並且只有一小部分被修改。這對容器寫性能有明顯的影響。然而,有兩件事值得注意:

    1. copy_up操作只在第一次將給定文件寫入時發生。對同一個文件的操作後續都是在複製到容器層的副本上進行操作。
    2. OverlayFS只適用於兩層。這意味着性能應該優於AUFS,後者在搜索多層鏡像中的文件時可能會出現明顯的延遲。這一優勢適用於overlayoverlay2驅動程序。在初始讀取時,overlayfs2的性能略低於overlayfs,因爲它必須遍歷更多的層,但是它會緩存結果,所以這只是很小的損失。
  • 刪除文件和目錄 :

  1. 當在容器中刪除文件時,將在容器中創建一個whiteout文件(upperdir)。鏡像層(lowerdir)中的文件的版本沒有被刪除(因爲lowerdir是隻讀的)。但是,whiteout文件阻止容器使用它。
  2. 當在容器中刪除目錄時,將在容器中創建一個不透明的目錄(upperdir)。這與whiteout文件的工作方式相同,可以有效地阻止對目錄的訪問,即使它仍然存在於鏡像(lowerdir)中。
  • 重命名目錄:僅當源和目標路徑都位於頂層時,才允許對目錄調用rename(2)。否則,它將返回EXDEV錯誤(“不允許跨設備鏈接”)。應用程序需要設計成處理EXDEV並退回到“複製並斷開鏈接”策略。

OverlayFS和Docker性能

aufsdevicemapper相比,overlay2overlay驅動程序的性能更好。在某些情況下,overlay2也可能比btrfs表現得更好。但是,請注意以下細節。

  • 頁面緩存。OverlayFS支持頁面緩存共享。訪問同一文件的多個容器共享該文件的單個頁面緩存條目。這使得overlayoverlay2驅動程序在內存方面非常高效,對於高密度的用例(比如PaaS)是一個很好的選擇。
  • copy_up。與AUFS一樣,每當容器第一次寫入文件時,OverlayFS都會執行復制操作。這可能會增加寫操作的延遲,特別是對於大型文件。但是,一旦文件被複制,對該文件的所有後續寫操作都發生在上層,不需要進一步的複製操作。
    OverlayFS的copy_up操作比使用AUFS的相同操作要快,因爲AUFS支持比OverlayFS更多的層,如果搜索多個AUFS層,可能會導致更大的延遲。overlay2也支持多層,但是通過緩存可以降低任何性能損失。
  • Inode的限制。使用舊的overlay存儲驅動程序會導致過多的inode消耗。在Docker主機上存在大量的鏡像和容器時尤其如此。增加文件系統可用inode數量的惟一方法是重新格式化它。爲了避免遇到這個問題,強烈建議儘可能使用overlay2。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章