鏡像[容器培訓(xùn)專題]

因?yàn)檎腥瞬豁樌脑?,開始在公司內(nèi)做容器及K8S開發(fā)的系統(tǒng)性培訓(xùn),從容器基礎(chǔ)開始也是對自己知識結(jié)構(gòu)的總結(jié),有興趣加入我們的小伙伴,請私信或留言,坐標(biāo)重慶。

鏡像部分

概念

  • bootfs
  • rootfs
  • layer
  • union file system

bootfs(boot file system)

主要包含bootloader和kernel, bootloader主要是引導(dǎo)加載kernel, Linux剛啟動時會加載bootfs文件系統(tǒng),在Docker鏡像的最底層是bootfs。這一層與我們典型的Linux/Unix系統(tǒng)是一樣的,包含boot加載器和內(nèi)核。當(dāng)boot加載完成之后整個內(nèi)核就都在內(nèi)存中了,此時內(nèi)存的使用權(quán)已由bootfs轉(zhuǎn)交給內(nèi)核,此時系統(tǒng)也會卸載bootfs。

rootfs

rootfs 是掛載在容器根目錄上、用來為容器進(jìn)程提供隔離后執(zhí)行環(huán)境的文件系統(tǒng),這個文件系統(tǒng)是一個操作系統(tǒng)的完整文件系統(tǒng)。需要明確的是,rootfs 只是一個操作系統(tǒng)所包含的文件、配置和目錄,并不包括操作系統(tǒng)內(nèi)核。在 Linux 操作系統(tǒng)中,這兩部分是分開存放的,操作系統(tǒng)只有在開機(jī)啟動時才會加載指定版本的內(nèi)核鏡像。

長這樣。

$ ls /
bin dev etc home lib lib64 mnt opt proc root run sbin sys tmp usr var

容器的本質(zhì)

  1. 啟用 Linux Namespace 配置;
  2. 設(shè)置指定的 Cgroups 參數(shù);
  3. 切換進(jìn)程的根目錄(優(yōu)先使用 pivot_root 系統(tǒng)調(diào)用, 如果系統(tǒng)不支持,使用Change Root)。

思考?:rootfs 可以看做一個最基礎(chǔ)的操作系統(tǒng)。此時如果要運(yùn)行java程序,就需要在這個基礎(chǔ)的操作系統(tǒng)里安裝jre。rootfs 就被污染了,成為了jre 特定的基礎(chǔ)操作系統(tǒng),如果另一個人需要運(yùn)行python 程序怎么辦?重新制作rootfs?

Layer

如果修改都基于一個基礎(chǔ)的 rootfs,而將變更做成增量,所有人都只需要維護(hù)相對于 base rootfs 修改的增量內(nèi)容,而不是每次修改都制造一個“fork”。

docker 的創(chuàng)新在于用戶制作鏡像的每一步操作,都會生成一個層,也就是一個增量。


image.png

我們可以通過 docker image inspect 來查看鏡像的層

root@ubuntudev ~# docker image inspect golang:1.16

...
  "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:688e187d6c79c46e8261890f0010fd5d178b8faa178959b0b46b2635aa1eeff3",
                "sha256:00bcea93703b384ab61d2344d6e721c75b0e47198b7912136a86759d8d885711",
                "sha256:ccb9b68523fdb47816f2a15d7590d06ff3d897dfdb3e0733e9c06a2bb79ebfc7",
                "sha256:685934357c8993799eda4a6d71c2bb2d2c54b1138d6e037f675eeeeffc719f2d",
                "sha256:9d52e952d0a781ee401640f2a7a9155f313c927ba5b3880959e055619a3391a9",
                "sha256:762eb5b089c5c496c946d1ffb5d8088a4b3b4648635fd46e8e4c82ee36c33687",
                "sha256:c92e53084342a99bee2b3d5a410f5f6d4df192eff4a8381c5c558cb0f150646d"
            ]
        },
...

每一層的變更,都存放在/var/lib/docker/overlay2/<sha256>

層的可讀寫性
image.png

容器(container)的定義和鏡像(image)幾乎一模一樣,也是一堆層的統(tǒng)一視角,唯一區(qū)別在于容器的最上面那一層是可讀可寫的。

思考:bin etc 這些操作系統(tǒng)目錄被拉平到根目錄下,如何還能正常工作?

Union File System

就是用來解決這樣一個問題。
UnionFS (聯(lián)合文件系統(tǒng)) 是一種分層、輕量級并且高性能的文件系統(tǒng),它支持對文件系統(tǒng)的修改作為一’ 次提交來一層層的疊加,同時可以將不同月錄掛載到同一個虛擬文件系統(tǒng)下(unite several directories into a single virtual filesystem)。Union 文件系統(tǒng)是Docker鏡像的基礎(chǔ)。鏡像可以通過分層來進(jìn)行繼承,基于基礎(chǔ)鏡像(沒有父鏡像),可以制作各種具體的應(yīng)用鏡像。

特性:一次同時加載多個文件系統(tǒng),但從外面看起來,只能看到一個文件系統(tǒng),聯(lián)合加載會把各層文件系統(tǒng)疊加起來,這樣最終的文件系統(tǒng)會包含所有底層的文件和目錄

感受一下

cd /tmp
mkdir a b c
echo "aaa" > a/a.txt
echo "bbb" > b/b.txt
mount -v -t aufs -o br=/tmp/a:/tmp/b none /tmp/c
ls /tmp/c

解釋下mount命令各參數(shù)含義:

  • -t aufs 指定文件系統(tǒng)類型為aufs
  • -o 后面是掛載選項,指定我們要掛載哪些目錄
  • none 說明我們掛載的不是設(shè)備文件,因?yàn)檫@里我們是直接掛載目錄的

AUFS的檢測級別可以通過udba指定

udba有三種級別:none、reval、inotify,對性能的影響依次增加,當(dāng)然安全性也有所增強(qiáng)。

  • None: 這種檢測是最快的,但可能導(dǎo)致錯誤的數(shù)據(jù),例如在原始目錄修改文件,在aufs中讀取,不完全保證正確

  • reval:aufs會訪問重新原始目錄,如果文件有更新,在會反映在aufs中

  • Notify: 會在所有原始目錄中的所有目錄上注冊notify事件,這會嚴(yán)重的影響性能,不建議使用。

mount -v -t aufs -o br=/tmp/a:/tmp/b -o udba=none none /tmp/c

設(shè)置讀寫

mount -v -t aufs -o br=/tmp/a=rw:/tmp/b=ro -o udba=none none /tmp/c

參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容