linux namespace

Linux Namespaces機制提供一種資源隔離方案。PID,IPC,Network等系統資源不再是全局性的,而是屬於特定的Namespace。每個Namespace裏面的資源對其他Namespace都是透明的。要創建新的Namespace,只需要在調用clone時指定相應的flagLinux Namespaces機制爲實現基於容器的虛擬化技術提供了很好的基礎,LXCLinux containers)就是利用這一特性實現了資源的隔離。不同container內的進程屬於不同的Namespace,彼此透明,互不干擾。下面我們就從clone系統調用的flag出發,來介紹各個Namespace

當調用clone時,設定了CLONE_NEWPID,就會創建一個新的PID Namespaceclone出來的新進程將成爲Namespace裏的第一個進程。一個PID Namespace爲進程提供了一個獨立的PID環境,PID Namespace內的PID將從1開始,在Namespace內調用forkvforkclone都將產生一個在該Namespace內獨立的PID。新創建的Namespace裏的第一個進程在該Namespace內的PID將爲1,就像一個獨立的系統裏的init進程一樣。該Namespace內的孤兒進程都將以該進程爲父進程,當該進程被結束時,該Namespace內所有的進程都會被結束。PID Namespace是層次性,新創建的Namespace將會是創建該Namespace的進程屬於的Namespace的子Namespace。子Namespace中的進程對於父Namespace是可見的,一個進程將擁有不止一個PID,而是在所在的Namespace以及所有直系祖先Namespace中都將有一個PID。系統啓動時,內核將創建一個默認的PID Namespace,該Namespace是所有以後創建的Namespace的祖先,因此係統所有的進程在該Namespace都是可見的。

當調用clone時,設定了CLONE_NEWIPC,就會創建一個新的IPC Namespace,clone出來的進程將成爲Namespace裏的第一個進程。一個IPC Namespace有一組System V IPC objects 標識符構成,這標識符有IPC相關的系統調用創建。在一個IPC Namespace裏面創建的IPC object對該Namespace內的所有進程可見,但是對其他Namespace不可見,這樣就使得不同Namespace之間的進程不能直接通信,就像是在不同的系統裏一樣。當一個IPC Namespace被銷燬,該Namespace內的所有IPC object會被內核自動銷燬。

PID NamespaceIPC Namespace可以組合起來一起使用,只需在調用clone時,同時指定CLONE_NEWPID和CLONE_NEWIPC,這樣新創建的Namespace既是一個獨立的PID空間又是一個獨立的IPC空間。不同Namespace的進程彼此不可見,也不能互相通信,這樣就實現了進程間的隔離。

當調用clone時,設定了CLONE_NEWNS,就會創建一個新的mount Namespace。每個進程都存在於一個mount Namespace裏面,mount Namespace爲進程提供了一個文件層次視圖。如果不設定這個flag,子進程和父進程將共享一個mount Namespace,其後子進程調用mountumount將會影響到所有該Namespace內的進程。如果子進程在一個獨立的mount Namespace裏面,就可以調用mountumount建立一份新的文件層次視圖。該flag配合pivot_root系統調用,可以爲進程創建一個獨立的目錄空間。

當調用clone時,設定了CLONE_NEWNET,就會創建一個新的Network Namespace。一個Network Namespace爲進程提供了一個完全獨立的網絡協議棧的視圖。包括網絡設備接口,IPv4IPv6協議棧,IP路由表,防火牆規則,sockets等等。一個Network Namespace提供了一份獨立的網絡環境,就跟一個獨立的系統一樣。一個物理設備只能存在於一個Network Namespace中,可以從一個Namespace移動另一個Namespace中。虛擬網絡設備(virtual network device)提供了一種類似管道的抽象,可以在不同的Namespace之間建立隧道。利用虛擬化網絡設備,可以建立到其他Namespace中的物理設備的橋接。當一個Network Namespace被銷燬時,物理設備會被自動移回init Network Namespace,即系統最開始的Namespace

當調用clone時,設定了CLONE_NEWUTS,就會創建一個新的UTS Namespace。一個UTS Namespace就是一組被uname返回的標識符。新的UTS Namespace中的標識符通過複製調用進程所屬的Namespace的標識符來初始化。Clone出來的進程可以通過相關係統調用改變這些標識符,比如調用sethostname來改變該Namespacehostname。這一改變對該Namespace內的所有進程可見。CLONE_NEWUTSCLONE_NEWNET一起使用,可以虛擬出一個有獨立主機名和網絡空間的環境,就跟網絡上一臺獨立的主機一樣。

以上所有clone flag都可以一起使用,爲進程提供了一個獨立的運行環境。LXC正是通過在clone時設定這些flag,爲進程創建一個有獨立PIDIPCFSNetworkUTS空間的container。一個container就是一個虛擬的運行環境,對container裏的進程是透明的,它會以爲自己是直接在一個系統上運行的。

一個container就像傳統虛擬化技術裏面的一臺安裝了OS的虛擬機,但是開銷更小,部署更爲便捷。

作者曰:Linux Namespaces機制本身就是爲了實現container based virtualizaiton開發的。它提供了一套輕量級、高效率的系統資源隔離方案,遠比傳統的虛擬化技術開銷小,不過它也不是完美的,它爲內核的開發帶來了更多的複雜性,它在隔離性和容錯性上跟傳統的虛擬化技術比也還有差距。


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