Linux的命名空間機(jī)制提供了一種資源隔離的解決方案。PID,IPC,Network等系統(tǒng)資源不再是全局性的还蹲,而是屬于特定的Namespace爹耗。Linux Namespace機(jī)制為實(shí)現(xiàn)基于容器的虛擬化技術(shù)提供了很好的基礎(chǔ),LXC(Linux containers)就是利用這一特性實(shí)現(xiàn)了資源的隔離谜喊。不同Container內(nèi)的進(jìn)程屬于不同的Namespace潭兽,彼此透明,互不干擾锅论。
Namespace是對(duì)全局系統(tǒng)資源的一種封裝隔離讼溺,使得處于不同namespace的進(jìn)程擁有獨(dú)立的全局系統(tǒng)資源楣号,改變一個(gè)namespace中的系統(tǒng)資源只會(huì)影響當(dāng)前namespace里的進(jìn)程最易,對(duì)其他namespace中的進(jìn)程沒(méi)有影響。
Linux查看進(jìn)程的命名空間
Linux內(nèi)核支持的namespace類型
目前炫狱,Linux內(nèi)核里面實(shí)現(xiàn)了7種不同類型的namespace藻懒。
名稱 宏定義 隔離內(nèi)容
Cgroup CLONE_NEWCGROUP Cgroup root directory (since Linux 4.6)
IPC CLONE_NEWIPC System V IPC, POSIX message queues (since Linux 2.6.19)
Network CLONE_NEWNET Network devices, stacks, ports, etc. (since Linux 2.6.24)
Mount CLONE_NEWNS Mount points (since Linux 2.4.19)
PID CLONE_NEWPID Process IDs (since Linux 2.6.24)
User CLONE_NEWUSER User and group IDs (started in Linux 2.6.23 and completed in Linux 3.8)
UTS CLONE_NEWUTS Hostname and NIS domain name (since Linux 2.6.19)
下面簡(jiǎn)要介紹一個(gè)以上不同類型的命名空間的作用:
IPC:用于隔離進(jìn)程間通訊所需的資源( System V IPC, POSIX message queues),PID命名空間和IPC命名空間可以組合起來(lái)用视译,同一個(gè)IPC名字空間內(nèi)的進(jìn)程可以彼此看見(jiàn)嬉荆,允許進(jìn)行交互,不同空間進(jìn)程無(wú)法交互
Network:Network Namespace為進(jìn)程提供了一個(gè)完全獨(dú)立的網(wǎng)絡(luò)協(xié)議棧的視圖酷含。包括網(wǎng)絡(luò)設(shè)備接口鄙早,IPv4和IPv6協(xié)議棧,IP路由表椅亚,防火墻規(guī)則限番,sockets等等。一個(gè)Network Namespace提供了一份獨(dú)立的網(wǎng)絡(luò)環(huán)境呀舔,就跟一個(gè)獨(dú)立的系統(tǒng)一樣弥虐。
Mount:每個(gè)進(jìn)程都存在于一個(gè)mount Namespace里面,mount Namespace為進(jìn)程提供了一個(gè)文件層次視圖媚赖。如果不設(shè)定這個(gè)flag霜瘪,子進(jìn)程和父進(jìn)程將共享一個(gè)mount Namespace,其后子進(jìn)程調(diào)用mount或umount將會(huì)影響到所有該Namespace內(nèi)的進(jìn)程惧磺。如果子進(jìn)程在一個(gè)獨(dú)立的mount Namespace里面颖对,就可以調(diào)用mount或umount建立一份新的文件層次視圖。
PID::linux通過(guò)命名空間管理進(jìn)程號(hào)磨隘,同一個(gè)進(jìn)程缤底,在不同的命名空間進(jìn)程號(hào)不同布讹!進(jìn)程命名空間是一個(gè)父子結(jié)構(gòu),子空間對(duì)于父空間可見(jiàn)训堆。
User:用于隔離用戶
UTS:用于隔離主機(jī)名
命名空間相關(guān)的API
與命名空間相關(guān)的API主要有三個(gè):clone描验,setns和unshare,這三個(gè)API都是針對(duì)一個(gè)進(jìn)程來(lái)操作的坑鱼。
clone
clone方法會(huì)創(chuàng)建一個(gè)新的子進(jìn)程膘流,然后讓子進(jìn)程加入新的namespace,而當(dāng)前進(jìn)程保持不變鲁沥。
int clone(int (*child_func)(void *), void *child_stac, int flags, void *arg);
這兒的flag用于指明將要?jiǎng)?chuàng)建的新的namespace的類型呼股。
關(guān)于clone的具體例子請(qǐng)參考文章:http://blog.csdn.net/weifenghai/article/details/52836109
setns
setns方法用于將當(dāng)前進(jìn)程加入到已有的namespace中。
int setns(int fd, int nstype);
fd:
指向/proc/[pid]/ns/目錄里相應(yīng)namespace對(duì)應(yīng)的文件画恰,
表示要加入哪個(gè)namespace
nstype:
指定namespace的類型(上面的任意一個(gè)CLONE_NEW*):
1. 如果當(dāng)前進(jìn)程不能根據(jù)fd得到它的類型彭谁,如fd由其他進(jìn)程創(chuàng)建,
并通過(guò)UNIX domain socket傳給當(dāng)前進(jìn)程允扇,
那么就需要通過(guò)nstype來(lái)指定fd指向的namespace的類型
2. 如果進(jìn)程能根據(jù)fd得到namespace類型缠局,比如這個(gè)fd是由當(dāng)前進(jìn)程打開的,
那么nstype設(shè)置為0即可
unshare
unshare方法使當(dāng)前進(jìn)程退出指定類型的namespace考润,并加入到新創(chuàng)建的namespace(相當(dāng)于創(chuàng)建并加入新的namespace)
int unshare(int flags);
flags:
指定一個(gè)或者多個(gè)namespace的類型
關(guān)于unshare的具體例子請(qǐng)參考:http://blog.csdn.net/liumiaocn/article/details/52549978
總結(jié)
- namespace的本質(zhì)就是把原來(lái)所有進(jìn)程全局共享的資源拆分成了很多個(gè)一組一組進(jìn)程共享的資源
- 當(dāng)一個(gè)namespace里面的所有進(jìn)程都退出時(shí)狭园,namespace也會(huì)被銷毀,所以拋開進(jìn)程談namespace沒(méi)有意義
- UTS namespace就是進(jìn)程的一個(gè)屬性糊治,屬性值相同的一組進(jìn)程就屬于同一個(gè)namespace唱矛,跟這組進(jìn)程之間有沒(méi)有親戚關(guān)系無(wú)關(guān)
- UTS namespace沒(méi)有嵌套關(guān)系,即不存在說(shuō)一個(gè)namespace是另一個(gè)namespace的父namespace