docker創建一個容器


而容器技術的核心功能,就是通過約束和修改進程的動態表現,從而為其創造出一個“邊界”。

對於 Docker 等大多數 Linux 容器來說,Cgroups 技術是用來制造約束的主要手段,而 Namespace 技術則是用來修改進程視圖的主要方法。

你可能會覺得 Cgroups 和 Namespace 這兩個概念很抽象,

別擔心,接下來我們一起動手實踐一下,你就很容易理解這兩項技術了。假設你已經有了一個 Linux 操作系統上的 Docker 項目在運行,比如我的環境是 Ubuntu 16.04 和 Docker CE 18.05。

接下來,讓我們首先創建一個容器來試試。$ docker run -it busybox /bin/sh/ #這個命令是 Docker 項目最重要的一個操作,即大名鼎鼎的 docker run。

而 -it 參數告訴了 Docker 項目在啟動容器后,需要給我們分配一個文本輸入 / 輸出環境,也就是 TTY,跟容器的標准輸入相關聯,這樣我們就可以和這個 Docker 容器進行交互了。

而 /bin/sh 就是我們要在 Docker 容器里運行的程序。所以,上面這條指令翻譯成人類的語言就是:請幫我啟動一個容器,在容器里執行 /bin/sh,並且給我分配一個命令行終端跟這個容器交互。

這樣,我的 Ubuntu 16.04 機器就變成了一個宿主機,而一個運行着 /bin/sh 的容器,就跑在了這個宿主機里面

。上面的例子和原理,如果你已經玩過 Docker,一定不會感到陌生

。此時,如果我們在容器里執行一下 ps 指令,就會發現一些更有趣的事情:/ # psPID USER TIME COMMAND 1 root 0:00 /bin/sh 10 root 0:00

ps可以看到,我們在 Docker 里最開始執行的 /bin/sh,就是這個容器內部的第 1 號進程(PID=1),而這個容器里一共只有兩個進程在運行。

這就意味着,前面執行的 /bin/sh,以及我們剛剛執行的 ps,已經被 Docker 隔離在了一個跟宿主機完全不同的世界當中。

這究竟是怎么做到的呢?本來,每當我們在宿主機上運行了一個 /bin/sh 程序,操作系統都會給它分配一個進程編號,比如 PID=100。這個編號是進程的唯一標識,就像員工的工牌一樣。所以 PID=100

這種技術,就是 Linux 里面的 Namespace 機制。而 Namespace 的使用方式也非常有意思:它其實只是 Linux 創建新進程的一個可選參數。

我們知道,在 Linux 系統中創建進程的系統調用是 clone(),比如:int pid = clone(main_function, stack_size, SIGCHLD, NULL); 這個系統調用就會為我們創建一個新的進程,並且返回它的進程號 pid。

而當我們用 clone() 系統調用創建一個新進程時,就可以在參數中指定 CLONE_NEWPID 參數,比如:int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);

這時,新創建的這個進程將會“看到”一個全新的進程空間,在這個進程空間里,它的 PID 是 1。之所以說“看到”,是因為這只是一個“障眼法”,在宿主機真實的進程空間里,這個進程的 PID 還是真實的數值,比如 100。

當然,我們還可以多次執行上面的 clone() 調用,這樣就會創建多個 PID Namespace,而每個 Namespace 里的應用進程,都會認為自己是當前容器里的第 1 號進程,

它們既看不到宿主機里真正的進程空間,也看不到其他 PID Namespace 里的具體情況。而除了我們剛剛用到的 PID Namespace,Linux 操作系統還提供了 Mount、UTS、IPC、Network 和 User 這些 Namespace,

用來對各種不同的進程上下文進行“障眼法”操作。比如,Mount Namespace,用於讓被隔離進程只看到當前 Namespace 里的掛載點信息;Network Namespace,

用於讓被隔離進程看到當前 Namespace 里的網絡設備和配置。這,就是 Linux 容器最基本的實現原理了。所以,Docker 容器這個聽起來玄而又玄的概念,

實際上是在創建容器進程時,指定了這個進程所需要啟用的一組 Namespace 參數。

這樣,容器就只能“看”到當前 Namespace 所限定的資源、文件、設備、狀態,或者配置。而對於宿主機以及其他不相關的程序,它就完全看不到了。所以說,容器,其實是一種特殊的進程而已。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM