docker 存儲驅動(一) ---- overlay2

官方的文檔請參考:docker overlay stroage

一直很好奇docker是怎麼存image的。再這總結一下。

前提

OverlayFS is supported if you meet the following prerequisites:

  • The overlay2 driver is supported on Docker CE, and Docker EE 17.06.02-ee5 and up, and is the recommended storage driver.
    Version 4.0 or higher of the Linux kernel, or RHEL or CentOS using version 3.10.0-514 of the kernel or higher. If you use an older kernel, you need to use the overlay driver, which is not recommended.

    • The overlay and overlay2 drivers are supported on xfs backing filesystems, but only with d_type=true enabled.
  • Use xfs_info to verify that the ftype option is set to 1. To format an xfs filesystem correctly, use the flag -n ftype=1.
    Warning: Running on XFS without d_type support now causes Docker to skip the attempt to use the overlay or overlay2 driver. Existing installs will continue to run, but produce an error. This is to allow users to migrate their data. In a future version, this will be a fatal error, which will prevent Docker from starting.

  • Changing the storage driver makes existing containers and images inaccessible on the local system. Use docker save to save any images you have built or push them to Docker Hub or a private registry before changing the storage driver, so that you do not need to re-create them later.

官網給出了使用overlay2的前提條件。
那麼如何看docker的存儲驅動呢?

mcong@mcong-Virtual-Machine:~$ docker info|grep "Storage Driver"
Storage Driver: overlay2

docker overlay2 工作機制

Image and container layers on-disk

我們把ubuntu的image作爲例子。

root@mcong-Virtual-Machine:/var/lib/docker/overlay2# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
6abc03819f3e: Pull complete
05731e63f211: Pull complete
0bd67c50d6be: Pull complete
Digest: sha256:f08638ec7ddc90065187e7eabdfac3c96e5ff0f6b2f1762cf31a4f49b53000a5
Status: Downloaded newer image for ubuntu:latest

可以看出,這個image有三層。那麼這個image是怎麼存儲的呢?

root@mcong-Virtual-Machine:/home/mcong# cd /var/lib/docker/overlay2/
root@mcong-Virtual-Machine:/var/lib/docker/overlay2# ls -l
total 16
drwx------ 4 root root 4096 May 21 03:26 071bf84e3c225f0b81340d225832100b04bb015b0a3dcd0fb376e0d88e97f8f3
drwx------ 4 root root 4096 May 21 03:26 0aa86c675bb91414fe320abbe7d04ef1f916f17caaca16f4d3d5ff65f8a3e7d1
drwx------ 3 root root 4096 May 21 03:26 8ea06311f7fa82211f09765c9880b1bf1b947ac21bb98b99f6a573ce69b55859
drwx------ 2 root root 4096 May 21 03:26 l

overlay2這個文件夾裏邊有四個文件夾,有個怪異的文件叫“l“,就是小寫的”L“,這裏面都是軟連接文件目錄的簡寫標識,這個主要是爲了避免mount時候頁大小的限制。

root@mcong-Virtual-Machine:/var/lib/docker/overlay2# ls -l l
total 12
lrwxrwxrwx 1 root root 72 May 21 03:26 2AKHZHYWB6NVU54RID3EVEOJRL -> ../071bf84e3c225f0b81340d225832100b04bb015b0a3dcd0fb376e0d88e97f8f3/diff
lrwxrwxrwx 1 root root 72 May 21 03:26 IVKI5UJXVI6PDDFG772SYUG5BF -> ../0aa86c675bb91414fe320abbe7d04ef1f916f17caaca16f4d3d5ff65f8a3e7d1/diff
lrwxrwxrwx 1 root root 72 May 21 03:26 V445NSA64ILRIBFUP5D4NVHC5I -> ../8ea06311f7fa82211f09765c9880b1bf1b947ac21bb98b99f6a573ce69b55859/diff

其他三個文件夾就我我們pull時候下載的3層layer
那麼這三個文件是如何組織成一個image的?
首先我們看看8ea06311f7fa82211f09765c9880b1bf1b947ac21bb98b99f6a573ce69b55859這個文件夾

root@mcong-Virtual-Machine:/var/lib/docker/overlay2# ls 8ea06311f7fa82211f09765c9880b1bf1b947ac21bb98b99f6a573ce69b55859
diff  link
root@mcong-Virtual-Machine:/var/lib/docker/overlay2# cat 8ea06311f7fa82211f09765c9880b1bf1b947ac21bb98b99f6a573ce69b55859/link
V445NSA64ILRIBFUP5D4NVHC5I

上邊說過‘l“這個目錄裏邊有V445NSA64ILRIBFUP5D4NVHC5I是link到…/8ea06311f7fa82211f09765c9880b1bf1b947ac21bb98b99f6a573ce69b55859/diff, 我們看看這個文件裏邊有什麼:

root@mcong-Virtual-Machine:/var/lib/docker/overlay2# ls 8ea06311f7fa82211f09765c9880b1bf1b947ac21bb98b99f6a573ce69b55859/diff
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

這個就是我們的文件系統,最有可能是我們的base image。
這個文件夾搞明白了,那麼其他連個文件夾呢?

root@mcong-Virtual-Machine:/var/lib/docker/overlay2# cat 0aa86c675bb91414fe320abbe7d04ef1f916f17caaca16f4d3d5ff65f8a3e7d1/lower
l/2AKHZHYWB6NVU54RID3EVEOJRL:l/V445NSA64ILRIBFUP5D4NVHC5I

這就表明了這個文件應該是頂層的layer,它的lower包含其他兩個layer。
我們再去最後一個文件夾看看:

root@mcong-Virtual-Machine:/var/lib/docker/overlay2# cat 071bf84e3c225f0b81340d225832100b04bb015b0a3dcd0fb376e0d88e97f8f3/lower
l/V445NSA64ILRIBFUP5D4NVHC5I

這個應該就是中間層。

還有一個問題:這兩層有什麼東西呢。
東西都是存在diff這個目錄下。

那麼我們跑一下這個container會有什麼效果?

root@mcong-Virtual-Machine:~# docker run -ti ubuntu bash

root@mcong-Virtual-Machine:/var/lib/docker/overlay2# ls
071bf84e3c225f0b81340d225832100b04bb015b0a3dcd0fb376e0d88e97f8f3
0aa86c675bb91414fe320abbe7d04ef1f916f17caaca16f4d3d5ff65f8a3e7d1
8ea06311f7fa82211f09765c9880b1bf1b947ac21bb98b99f6a573ce69b55859
b22e19f8a8a698ee8b5c210285517cb141a8e5a248f864a5b87924eee227a3e1
b22e19f8a8a698ee8b5c210285517cb141a8e5a248f864a5b87924eee227a3e1-init

這裏多了兩個目錄。
先看不帶init的目錄:

root@mcong-Virtual-Machine:/var/lib/docker/overlay2/b22e19f8a8a698ee8b5c210285517cb141a8e5a248f864a5b87924eee227a3e1# ls
diff  link  lower  merged  work

這裏會多一個merged目錄,這個目錄就是我們再container裏邊看到的目錄結構。diff目錄存放了container裏邊多/少的
爲了測試, 我再container中創建了/home/aaa.test並且刪掉bin目錄下sleep和sync兩個文件。
我們再去目錄裏看看

root@mcong-Virtual-Machine:/var/lib/docker/overlay2/b22e19f8a8a698ee8b5c210285517cb141a8e5a248f864a5b87924eee227a3e1/diff/bin# ls -l
total 0
c--------- 1 root root 0, 0 May 21 04:03 sleep
c--------- 1 root root 0, 0 May 21 04:03 sync

可以看出diff裏邊這兩個文件已經mark成刪除了。

root@mcong-Virtual-Machine:/var/lib/docker/overlay2/b22e19f8a8a698ee8b5c210285517cb141a8e5a248f864a5b87924eee227a3e1/diff/home# ls -l
total 0
-rw-r--r-- 1 root root 0 May 21 04:00 aaa.test

aaa.test已經存在。

這裏如果啓動容器還有一點需要介紹,你會看到多了一個”讀寫層-init”,這個只讀層,它的目的是爲了初始化容器配置信息,譬如hostname等信息

How the overlay driver works

官網的圖片很生動, 就是原來diff目錄叫upperdir。官網還沒有更新。
OverlayFS將單個Linux主機上的兩個目錄合併成一個目錄。這些目錄被稱爲層,統一過程被稱爲聯合掛載。OverlayFS關聯的底層目錄稱爲lower,合併過後統一視圖稱爲merged。

下圖是一個docker鏡像和docke容器的分層圖,docker鏡像是lower,docker容器是diff。而統一的視圖層是merged層
how oerlay works

文件操作

那麼當我們讀寫文件的時候各層是怎樣合作的呢?

  • 如果該文件在容器層不存在:文件不存在diff中,則從lower中讀取
    只在容器層存在: 文件只存在diff中,則直接從容器中讀取改文件
    文件同事存在容器曾和鏡像層:容器層diff會覆蓋鏡像層lowdir中的文件

  • 修改

    首次寫入: 改文件在diff中不存在,在overlay和overlay2中,執行copy_up操作,把文件從lowdir拷貝到diff。然後所以的更改都是在容器層內修改副本的操作,由於overlayfs是文件級別的,不是塊級別的,這就意味着即使文件只有很少的一點修改,也會產生的copy_up的行爲,不過有兩點需要注意:

    1. copy_up操作只發生在文件首次寫入,以後都是隻修改副本
    2. overlayfs只適用兩層,因此性能很好,查找搜索都更快
  • 刪除文件和目錄: 當文件在容器被刪除時,在容器層(diff)創建whiteout文件,鏡像層的文件是不會被刪除的,因爲他們是隻讀的,但without文件會阻止他們展現,當目錄在容器內被刪除時,在容器層(diff)一個不透明的目錄,這個和上面whiteout原理一樣,阻止用戶繼續訪問,即便鏡像層仍然存在
    最後畫個圖:
    在這裏插入圖片描述

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