1. 程式人生 > 其它 >docker建立一個容器

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 所限定的資源、檔案、裝置、狀態,或者配置。而對於宿主機以及其他不相關的程式,它就完全看不到了。所以說,容器,其實是一種特殊的程序而已。

全世界的程式設計師們聯合起來吧!