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

AUFS

AUFS是一個聯合文件系統。aufs存儲驅動程序以前是默認的存儲驅動程序,用於管理Ubuntu的Docker上的鏡像和層,以及在Stretch之前的Debian版本。如果Linux內核是4.0或更高版本,並且使用Docker Engine - Community,那麼可以考慮使用更新的overlay2,它與aufs存儲驅動程序相比具有潛在的性能優勢。

前提條件

  • 對於Docker Engine - Community,在Ubuntu上支持AUFS,在Stretch之前支持Debian版本。

  • 對於Docker EE, Ubuntu支持AUFS。

  • 如果使用Ubuntu,需要安裝額外的包來將AUFS模塊添加到內核中。如果不安裝這些包,需要在ubuntu14.04上使用devicemapper(這是不推薦的),或者在ubuntu16.04或更高版本上使用overlay2,也是受支持的。

  • AUFS不能使用以下備份文件系統:AUFS、btrfs或ecryptfs。這意味着包含/var/lib/docker/aufs的文件系統不能是這些文件系統類型之一。

用aufs存儲驅動程序配置Docker

如果在啓動Docker時將AUFS驅動程序加載到內核中,並且未配置其他存儲驅動程序,則Docker默認使用它。

  1. 使用以下命令來驗證您的內核是否支持AUFS。
    grep aufs /proc/filesystems
    
    nodev   aufs
    
  2. 檢查Docker使用哪個存儲驅動程序。
    docker info
    
    <truncated output>
    Storage Driver: aufs
     Root Dir: /var/lib/docker/aufs
     Backing Filesystem: extfs
     Dirs: 0
     Dirperm1 Supported: true
    <truncated output>
    

aufs存儲驅動程序如何工作

AUFS是一個聯合文件系統,這意味着它在單個Linux主機上分層多個目錄,並將它們顯示爲單個目錄。這些目錄在AUFS術語中稱爲分支,在Docker術語中稱爲層。

統一的過程稱爲聯合掛載。

下圖顯示了基於 ubuntu:latest 鏡像的Docker容器。
在這裏插入圖片描述
每個鏡像層和容器層在Docker主機上均表示爲圖中的子目錄/var/lib/docker/。聯合掛載提供了所有層的統一視圖。目錄名稱並不直接對應於鏡像層本身的ID。

AUFS使用寫時複製(CoW)策略來最大化存儲效率並最小化開銷

示例:映像和磁盤上的容器構造

下面的docker pull命令顯示了一個docker主機正在下載一個包含四層的docker鏡像。
在這裏插入圖片描述
鏡像層

所有鏡像層和容器層的信息都存儲在 /var/lib/docker/aufs/ 的子目錄中。

  • diff/:每一層的內容,每一層都存儲在一個單獨的子目錄中。
  • layers/:關於鏡像層如何堆積的元數據。此目錄包含Docker主機上每個鏡像或容器層的一個文件。每個文件包含堆棧中它下面所有層的id(它的父層)。
  • mnt/:掛載點,每個鏡像或容器層一個,用於組裝和掛載容器的統一文件系統。對於只讀的鏡像,這些目錄總是空的。

容器層

如果容器正在運行,則/var/lib/docker/aufs/更改內容的方式如下:

  • diff/:可寫容器層中引入的差異,如新文件或修改的文件。
  • layers/:關於可寫容器層的父層的元數據。
  • mnt/:每個運行容器的統一文件系統的掛載點,與容器內的掛載點完全相同。

容器如何使用aufs進行讀寫操作

讀取文件

考慮三種情況,其中容器使用aufs打開文件進行讀訪問。

  • 該文件在容器層中不存在: 存儲驅動程序在鏡像層中搜索該文件,從容器層下面的層開始。從找到它的那一層讀取。
  • 該文件僅存在於容器層中: 文件存在於容器層中,則從該層讀取該文件。
  • 該文件同時存在於容器層和鏡像層: 如果容器打開一個文件進行讀取訪問,並且該文件存在於容器層和一個或多個鏡像層中,則從容器層讀取該文件。容器層中的文件掩蓋了在鏡像層中具有相同名稱的文件。

修改文件或目錄

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

  • 第一次寫入文件:容器第一次寫入現有文件時,該文件在容器中不存在。aufs驅動程序執行copy_up操作,將文件從存在它的鏡像層複製到可寫的容器層。然後容器將更改寫入容器層中文件的新副本。
    但是,AUFS是在文件級別而不是塊級別工作的。這意味着所有的copy_up操作都會複製整個文件,即使文件非常大,並且只有一小部分被修改。

  • 刪除文件和目錄 :

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

AUFS和Docker性能

總結已經提到的一些與性能相關的方面:

  • AUFS存儲驅動程序的性能不如overlay2驅動程序,但是對於容器密度很重要的PaaS和其他類似用例來說,它是一個不錯的選擇。這是因爲AUFS在多個正在運行的容器之間有效地共享鏡像,從而縮短了容器的啓動時間,並減少了磁盤空間的使用。

  • AUFS如何在鏡像層和容器之間共享文件的基本機制非常有效地使用了頁面緩存。

  • AUFS存儲驅動程序可能會在容器寫入性能中引入較大的延遲。這是因爲容器第一次寫入任何文件時,都需要找到該文件並將其複製到容器的頂層可寫層中。當這些文件存在於許多鏡像層下面並且文件本身很大時,這些等待時間會增加並且變得更加複雜。

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