學習Docker?
我家是搞養殖的,養了幾十頭羊,有的瘦小,有的強壯。之前,所有羊在一個食槽里吃飼料,強壯的羊會擠兌瘦小的,不讓其吃。結果就是強壯的愈加強壯,瘦小的愈加瘦小。為了解決這個問題,我為每頭羊分配了一個食槽,每頭羊只能在屬于它的食槽吃飼料,去其他食槽吃就會挨打,一段時間后,每頭羊便可以吃到為其分配的飼料,羊的長勢也就比較均衡了。
有人的地方就有江湖,羊也一樣。強壯的羊經常欺負瘦小的羊,導致瘦小的羊受傷,為了解決這個問題,我們將經常欺負弱小的羊單獨圈起來,這樣,對于它來說世界就只有它一頭羊了,精力無處發泄,只能撞墻了。原先的羊圈,欺負弱小的情形還在繼續發生,理想的方法是為每頭羊準備一個單獨的羊圈,我將方法提出后,被家里以成本過高為由否決了。
我們以進程類比羊,以操作系統類比羊圈,以資源類比飼料。
進程A為了運行流暢,可能會無限申請內存及CPU時間,擠壓了其他進程的資源,導致其他進程運行卡頓,用戶就會認為其他軟件用戶體驗差,進而卸載,這是非常不公平的。操作系統的解決方法是可為每個進程分配固定的資源(內存、CPU運行時間等),進程不能使用額外的資源。這就相當于為每頭羊分配了一個食槽,里面放適合它的飼料。在計算機中,這種技術叫CGroups。
進程是可以看到其他進程的,也可以看到其他進程產生的文件。進程可調用kill、rm殺死其他進程或刪除屬于其他進程的文件。通過權限機制可緩解此問題,但是更好的方法是,進程只能看到屬于自己的資源,進程想作惡,都不知道如何下手。在計算機中,這種技術叫做Namespace,將進程放在一個獨立的Namespace中,進程就只能看到屬于它的資源了,相當于為每頭羊準備一個單獨的羊圈。
通過CGroups和Namespace技術,進程只能使用固定的資源,并認為自己獨享操作系統,這就是容器虛擬化技術。
容器虛擬化技術是操作系統級虛擬化。文件系統屬于Namespace的一種,通過容器虛擬化技術,進程A使用Ubuntu16.04的文件系統,進程B使用Ubuntu22.04的文件系統,雖然二者使用的內核是同一個,但應用軟件的行為(由軟件、依賴庫、配置文件等決定)分別與Ubuntu16.04和Ubuntu22.04一致,就可以認為,分別虛擬出了Ubuntu16.04和Ubuntu22.04操作系統。
Docker整合了上述虛擬化技術,并提供了一系列工具,簡化并自動化容器虛擬化技術使用流程。風云際會,掀開了云原生時代的序幕。
我寫了一個稱作docker.sh 的小項目,該項目旨在通過一系列的實驗使用戶對docker的底層技術,如Namespace、CGroups、rootfs、聯合加載等有一個感性的認識。在此過程中,我們還將通過Shell腳本一步一步地實現一個簡易的docker,以期使讀者在使用docker的過程中知其然知其所以然。該項目的倉庫地址如下:
https://github.com/pandengyang/docker.sh.git
https://gitee.com/pandengyang/docker.sh.git
可用于學習 Docker 原理,里面有Namespace、CGroups的原理及示例的介紹。