1. 程式人生 > >Docker容器和映象儲存機制—images—目錄樹結構

Docker容器和映象儲存機制—images—目錄樹結構

http://ju.outofmemory.cn/entry/114344


Docker的儲存機制採用了非常靈活的模組化設計,目前支援5種儲存引擎,分別為aufs、btrfs、device mapper、vfs和overlay。它們的共同特點都是實現了graphdriver.Driver介面:

點選(此處)摺疊或開啟

  1. type ProtoDriver interface {
  2.   String() string
  3.   //建立layer
  4.   Create(id, parent string) error
  5.   /
    /刪除layer
  6.   Remove(id string) error
  7.   //mount, 獲取容器掛載點
  8.   Get(id, mountLabel string) (dir string, err error)
  9.   //umount檔案系統
  10.   Put(id string)
  11.   Exists(id string) bool
  12.   Status() [][2]string
  13.   Cleanup() error
  14. }
  15. type Driver interface {

  16.   ProtoDriver
  17.   Diff(id, parent string) (archive.Archive, error)
  18.   Changes(id, parent string) ([]archive.Change, error)
  19.   ApplyDiff(id, parent string, diff archive.ArchiveReader)(size int64,err error)
  20.   DiffSize(id, parent string) (size int64, err error)
  21. }

所以,只要實現了儲存驅動介面定義的方法,就可以擴展出一種儲存引擎。想要更換儲存引擎有兩種方法:
1. docker daemon程序啟動時指定-s引數:docker –s aufs。
2. 修改配置檔案:DOCKER_OPTS=”–storage-driver=aufs”。

在Docker儲存模型中,bootfs同宿主機,rootfs則是由多個映象層和一個容器層構成,其中映象層只讀,容器層可讀寫,多個映象層之間有父子關係,下層作為上層映象的父映象,最下面的映象稱為base images(基礎映象),相關定義可以參考官網解釋
docker image layer

aufs是Docker最早支援的一種儲存引擎,它的工作機制和優缺點在前文『aufs檔案系統』中已有介紹,aufs能將不同的目錄掛載到某一目錄下,將各個源目錄下的內容聯合到目標目錄下,並可對不同目錄進行許可權控制。這個特性非常契合Docker的儲存模型:
1. 映象分層模型對應aufs中的分支(源目錄)。
2. 映象層對應aufs的ro分支,只讀;容器層對應aufs的rw分支,可讀寫。

預設配置下,Docker映象和容器儲存路徑($DOCKROOT)位於/var/lib/docker,如果選擇的是aufs檔案系統作為儲存引擎,那麼它的子目錄樹結構(基於docker 1.4.1)應該如下:


點選(此處)摺疊或開啟

  1. # tree .
  2. ├── aufs
  3. │ ├── diff 映象和容器每層的差異內容
  4. │ ├── layers 映象和容器每層的繼承關係
  5. │ └── mnt 容器掛載點
  6. ├── containers 容器配置檔案,環境變數和日誌檔案
  7. ├── graph 映象詳情、大小等
  8. └── repositories-aufs 映象摘要

舉例說明,當前本地映象庫有一個ubuntu:14.04的映象,它的層級關係如下:


點選(此處)摺疊或開啟

  1. # docker images -t
  2. └─511136ea3c5a Virtual Size: 0 B
  3.   └─3b363fd9d7da Virtual Size: 192.5 MB
  4.     └─607c5d1cca71 Virtual Size: 192.7 MB
  5.       └─f62feddc05dc Virtual Size: 192.7 MB
  6.         └─8eaa4ff06b53 Virtual Size: 192.7 MB Tags: ubuntu:14.04

那麼在aufs/diff目錄(相對於$DOCKROOT,下同)下會有以各個層級id命名的目錄,每個目錄儲存著與它父映象之間的差異:


點選(此處)摺疊或開啟

  1. # ls -l aufs/diff/
  2. total 20
  3. drwxr-xr-x 21 3b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
  4. drwxr-xr-x 2 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
  5. drwxr-xr-x 6 607c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
  6. drwxr-xr-x 2 8eaa4ff06b53ff7730c4d7a7e21b4426a4b46dee064ca2d5d90d757dc7ea040a
  7. drwxr-xr-x 3 f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73

aufs/layers目錄下有以各個層級id命名的檔案,檔案內容為該層所有的祖先映象id。例如


點選(此處)摺疊或開啟

  1. # cat aufs/layers/8eaa4ff06b53ff7730c4d7a7e21b4426a4b...
  2. f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73
  3. c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
  4. b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
  5. ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158

graph目錄中儲存的是每一層映象的詳細資訊和大小:


點選(此處)摺疊或開啟

  1. # tree graph/
  2. graph/
  3. ├── 3b363fd9d7dab4db9591058a3f43e806f6fa6f7e2744b63b2df4b84eadb0685a
  4. │ ├── json
  5. │ └── layersize
  6. ├── 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
  7. │ ├── json
  8. │ └── layersize
  9. ├── 607c5d1cca71dd3b6c04327c3903363079b72ab3e5e4289d74fb00a9ac7ec2aa
  10. │ ├── json
  11. │ └── layersize
  12. ├── 8eaa4ff06b53ff7730c4d7a7e21b4426a4b46dee064ca2d5d90d757dc7ea040a
  13. │ ├── json
  14. │ └── layersize
  15. └── f62feddc05dc67da9b725361f97d7ae72a32e355ce1585f9a60d090289120f73
  16.     ├── json
  17.     └── layersize

其中,json為該層元資訊,layersize為該層大小。

此時用ubuntu:14.04映象起一個容器:


點選(此處)摺疊或開啟

  1. # docker run -it -d ubuntu:14.04 /bin/bash
  2. b0311350933de15936136b4c9142635782f8fd1a015d2fd2d6c54ed05efb

新建容器的操作會在aufs下三個子目錄中分別新建兩個以容器id為名的檔案/目錄,例如4262b031135…和4262b031135…- init,其中4262b031135…-init表示容器的初始層,它記錄的資訊和ubuntu:14.04映象的最上層一致。所有在新建容器中的檔案 操作最終都會記錄到aufs/diff/4262b031135…目錄中,比如:
1. 新建檔案,修改檔案。
2. 刪除檔案和目錄,以.wh.{obj}標記。在聯合檔案系統中被稱為除白(Whiteout)物件。
3. 刪除目錄後新建,以.wh..wh..opq標記。在聯合檔案系統中被稱為不透明(Opaque directory)物件。

aufs/mnt目錄是容器的掛載點,通過df命令和mount -v命令進行確認,另外容器的操作日誌、環境變數、元資訊等也會在containers目錄以容器id命名的目錄中。容器執行後,可以在sysfs目錄中 找到對應的從上到下的映象層次結構,讀寫許可權一目瞭然(si可以通過mount -v查詢):


點選(此處)摺疊或開啟

  1. # cat /sys/fs/aufs/si_13ac476258e8c5e8/br*
  2. /var/lib/docker/aufs/diff/4262b031135...=rw
  3. /var/lib/docker/aufs/diff/4262b031135...-init=ro
  4. /var/lib/docker/aufs/diff/8eaa4ff06b5...=ro
  5. /var/lib/docker/aufs/diff/f62feddc05d...=ro
  6. /var/lib/docker/aufs/diff/607c5d1cca7...=ro
  7. /var/lib/docker/aufs/diff/3b363fd9d7d...=ro
  8. /var/lib/docker/aufs/diff/511136ea3c5...=ro

aufs為Docker映象儲存帶來了可重用性、許可權分明、層次清晰等優點後,也帶來了它的固有缺陷:
1. 寫時複製(Copy On Write),效能不夠好。
2. 最大層數限制(127層)。

關於繞開最大層數限制,在『aufs檔案系統』中已有討論,這裡針對Docker的使用場景再進行一次歸納:
1. 更換docker儲存驅動型別:device mapper, btrfs …
2. 重新編譯aufs: CONFIG_AUFS_BRANCH_MAX_32767=y
3. 精簡Dockerfile指令:RUN指令合併,指令碼化
4. docker export & docker import

EOF

















<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script> 閱讀(70) | 評論(0) | 轉發(0) | 給主人留下些什麼吧!~~ 評論熱議