Docker容器基礎:文件系統

CgroupNamespace 的管理下,容器其實是一個隔離和限制的 子系統,那麼容器的文件系統又是如何隔離開來的呢?

Chroot 命令

chroot : 改變進程的根目錄到你指定的 的位置

# 將 /bin/bash進程的根目錄指定爲 /leon0204/home
# 執行 ls 將顯示 /leon0204/home 下的文件
$ chroot /leon0204/home /bin/bash

對於 /bin/bash 來說,它的根目錄就改變了,這種修改視圖的方法和namespace 是一個原理。

Rootfs

上節我們已經知道,容器啓動的是一個父進程和N個 fork 出來的子進程,並且這個父進程被 chroot 修改了視圖,所以容器的根目錄就是一個隔離的子目錄,爲了讓這個目錄看起來更像一個系統,往往會在這個目錄下增加一些 系統的文件、目錄和配置 ,比如 /bin ,/etc 等。

rootfs 即是容器鏡像的本身,是一個操作系統所包含的文件,配置和目錄,並不包括操作系統內核,在Linux系統開機時,需要加載系統內核,那麼一個鏡像的rootfs沒有了 內核,如何正常加載呢?

由於 docker 的內核是建立在 宿主機 上的,與宿主機共享內核,記住:docker 沒有自己的內核。所以 dockerrootfs 實際上打包的不只是應用,而是整個 操作系統 ,即應用運行的所有的依賴,而不是從語言層面上的依賴。這樣解決了跨機器的環境同步問題。

Layer 按層發佈

A同事發佈一個JAVA應用,會包含了一個操作系統的rootfs ,B同事發佈一個JAVA應用同樣需要製作一個 rootfs ,如何提取我們之間的 共性 ?製造出一個基礎的鏡像(base image)?
docker 在這方面實現上,引入了 layer(層) 的概念,在A和B 製作 rootfs docker 鏡像系統的時候,把每一步記錄下來,作爲一個 ,取AB rootfs 的交集形成我們 JAVA base 鏡像 ,以後我們發佈各自的應用都可以使用這個鏡像。

UFS

聯合文件系統 UFS Union File SystemUnionFS :功能是將多個不同的目錄 unoin mount 到一個目錄下,比如A和B目錄的文件可以聯合掛載到C目錄下。這樣 A&B下的文件就和C形成了掛載,同步 增減改變。

AUFS

AUFS 是對 Union FS 的重寫和改進的版本,這也是 docker 使用的版本,以 Mysql:5.6 的鏡像爲例子,查看這個鏡像(rootfs)的AUFS結構如下:

[root@macco-web ~]# docker image inspect mysql:5.6
"RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:9c2f1836d49346677f8280bf0eb89c20853f6af4aa6e2fad87b0000bb181fad2",
                "sha256:fd3b39222ee496a3cc115a4142a26babcad2f2008f4053ad5f893fcc503cd7fe",
                "sha256:7ffd9f004dec5b25c7861e97e8f4ed5534f980b270fe03d0b834c0e6db843564",
                "sha256:c782fd1b83e9e2b2a904c57cb887b59fd58704712ad73452de817abbd2d766a8",
                "sha256:db76afa2e4c2f4c0077d028f37d73a6408cf2fc4bca1b0156225edd02f7e5cbc"
            ]
        },

可以看到這個 docker 是由 5layer)組成的,每一層實際上就是 系統的一個組成部分,包含了文件和目錄,在使用的時候使用 AUFS 掛載 組成了鏡像rootfs 子系統,我們查看這個目錄下有哪些文件:

# pwd
/statics/docker/overlay/f8611219ff61896ca3ac0edc4e1c2207f934da81492c901b7768d115896f8cab/root
# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

總結

容器通過 aufsdocker 創建出了一個完整的 rootfs linux 文件系統,也就是我們說的一個容器鏡像。
而鏡像又通過 layer 層 分層設計,將鏡像的設計變成了增量式的,使得協作的base 變得更小,協作的方式變得更迅捷,而每個人都是用 base 鏡像 ,使得容器 一致性 得以實現。

Namespace做隔離;Cgroups做限制;Rootfs做子系統

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