Linux Namespace技術(shù)
Namespace簡(jiǎn)介
Linux Namespace是Linux提供的一種內(nèi)核級(jí)別環(huán)境隔離的方法。
Linux Namespaces 機(jī)制提供了一種資源隔離方案。PID、IPC、Network等系統(tǒng)資源不再是全局性的,而是屬于特定的Namespace。
每個(gè)Namespace里面的資源對(duì)其他Namespace都是透明的。要?jiǎng)?chuàng)建新的Namespace,只需要在調(diào)用clone時(shí)指定相應(yīng)的flag。Linux Namespaces機(jī)制為實(shí)現(xiàn)基于容器的虛擬化技術(shù)提供了很好的基礎(chǔ)。


Namespace為Docker容器實(shí)現(xiàn)資源隔離
Docker 和虛擬機(jī)技術(shù)一樣,從操作系統(tǒng)級(jí)上實(shí)現(xiàn)了資源的隔離,它本質(zhì)上是宿主機(jī)上的進(jìn)程(容器進(jìn)程),所以資源隔離主要就是指進(jìn)程資源的隔離。實(shí)現(xiàn)資源隔離的核心技術(shù)就是 Linux namespace。
隔離意味著可以抽象出多個(gè)輕量級(jí)的內(nèi)核(容器進(jìn)程),這些進(jìn)程可以充分利用宿主機(jī)的資源,宿主機(jī)有的資源容器進(jìn)程都可以享有,但彼此之間是隔離的,同樣,不同容器進(jìn)程之間使用資源也是隔離的,這樣,彼此之間進(jìn)行相同的操作,都不會(huì)互相干擾,安全性得到保障。
為了支持這些特性,Linux namespace 實(shí)現(xiàn)了 6 項(xiàng)資源隔離,基本上涵蓋了一個(gè)小型操作系統(tǒng)的運(yùn)行要素,包括主機(jī)名、用戶權(quán)限、文件系統(tǒng)、網(wǎng)絡(luò)、進(jìn)程號(hào)、進(jìn)程間通信
Linux Namespace技術(shù)解決了以下Docker技術(shù)問(wèn)題
怎么保證每個(gè)容器都有不同的文件系統(tǒng)并且能互不影響?
一個(gè)docker主進(jìn)程內(nèi)的各個(gè)容器都是其子進(jìn)程,那怎么實(shí)現(xiàn)同一個(gè)主進(jìn)程下不同類型的子進(jìn)程?
每個(gè)容器怎么解決ip及端口分配的問(wèn)題?
多個(gè)容器的主機(jī)名可以一樣嗎?
每個(gè)容器都要不要有root用戶?
怎么解決賬戶重名問(wèn)題?
查看進(jìn)程有哪些Namespace隔離查看文件 /proc/[pid]/ns (注:該方法僅限于 3.8 版本以后的內(nèi)核)
# ls /proc/1364/ns -l
total 0
lrwxrwxrwx 1 root root 0 Dec 24 02:18 cgroup -> cgroup:[4026531835]
lrwxrwxrwx 1 root root 0 Dec 27 10:54 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 Dec 27 10:54 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 Dec 27 10:54 net -> net:[4026531957]
lrwxrwxrwx 1 root root 0 Dec 27 10:54 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 Dec 27 10:54 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Dec 27 10:54 uts -> uts:[4026531838]</pre>
Namespace 隔離類型
MNT Namespace
MNT Namespace提供磁盤掛載點(diǎn)和文件系統(tǒng)的隔離功能。
每個(gè)容器都要有獨(dú)立的根文件系統(tǒng)和獨(dú)立的用戶空間,以實(shí)現(xiàn)在容器里面啟動(dòng)服務(wù)并且使用容器的運(yùn)行環(huán)境。
例如:一個(gè)宿主機(jī)是ubuntu的服務(wù)器,可以在里面啟動(dòng)一個(gè)centos運(yùn)行環(huán)境的容器并且在容器中啟動(dòng)一個(gè)nginx服務(wù),此Nginx運(yùn)行時(shí)使用的是centos系統(tǒng)目錄的運(yùn)行環(huán)境,但是在容器里面是不能訪問(wèn)宿主機(jī)的資源,宿主機(jī)使用了MNT Namespace技術(shù)把容器鎖定到一個(gè)指定的運(yùn)行目錄里面并將其作為容器的根運(yùn)行環(huán)境。
MNT Namespace是基于對(duì)chroot的不斷改良發(fā)明出來(lái)的。
IPC Namespace
IPC Namespace提供進(jìn)程間通信(信號(hào)量、消息隊(duì)列、共享內(nèi)存)的隔離功能,在一個(gè)IPC Namespace里面創(chuàng)建的IPC object對(duì)該Namespace內(nèi)的所有進(jìn)程可見(jiàn),但是對(duì)其他Namespace不可見(jiàn),這樣就使得不同Namespace之間的進(jìn)程不能直接通信,就像是在不同的系統(tǒng)里一樣。
UTS Namespace
UTS Namespace 提供主機(jī)名、域名隔離功能。
UTS(Unix Timesharing System)包含了運(yùn)行內(nèi)核的名稱、版本、底層體系結(jié)構(gòu)類型等信息,用于系統(tǒng)標(biāo)識(shí),其中包含了主機(jī)名和域名,UTS Namespace使得一個(gè)容器擁有屬于自己的hostname標(biāo)識(shí),這個(gè)hostname標(biāo)識(shí)獨(dú)立于宿主機(jī)系統(tǒng)和其上的其他容器。
PID Namespace
PID Namespace提供進(jìn)程隔離功能
Linux系統(tǒng)中有一個(gè)pid為1的進(jìn)程(init/systemd)是其他所有進(jìn)程的父進(jìn)程,那么在每個(gè)容器內(nèi)也要有一個(gè)父進(jìn)程來(lái)管理其下屬的子進(jìn)程,多個(gè)容器的進(jìn)程通過(guò)PID Namespace實(shí)現(xiàn)進(jìn)程隔離(如PID編號(hào)重復(fù)、容器內(nèi)的主進(jìn)程生成和回收子進(jìn)程等)
Net Namespace
Net Namespace提供網(wǎng)絡(luò)設(shè)備、網(wǎng)絡(luò)棧、端口等隔離功能。
每個(gè)容器都類似于虛擬機(jī)一樣有自己的網(wǎng)卡、監(jiān)聽(tīng)端口、TCP/IP協(xié)議棧等。
Docker使用Network namespace啟動(dòng)一個(gè)vethX接口,這樣容器將擁有它自己的橋接IP地址,通常是docker0,而docker0實(shí)質(zhì)就是linux的虛擬網(wǎng)橋,網(wǎng)橋就是在OSI七層模型的數(shù)據(jù)鏈路層的網(wǎng)絡(luò)設(shè)備,通過(guò)MAC地址對(duì)網(wǎng)絡(luò)進(jìn)程劃分,并且在不同網(wǎng)絡(luò)直接傳遞數(shù)據(jù)。
User Namespace
User Namespace提供用戶、用戶組隔離功能
各個(gè)容器內(nèi)可能會(huì)出現(xiàn)重名的用戶和用戶組名稱,或重復(fù)的UID、GID,那么怎么隔離各個(gè)容器的用戶空間呢?
User Namespace允許宿主機(jī)的各個(gè)容器空間內(nèi)創(chuàng)建相同的用戶名、用戶組及相同的UID、GID,只是會(huì)把用戶的作用范圍限制在每個(gè)容器內(nèi),即A容器和B容器可以有相同的用戶名、UID的賬戶,但此用戶的有效范圍僅限于當(dāng)前容器,不能訪問(wèn)另外一個(gè)容器內(nèi)的文件系統(tǒng),即相互隔離、互不影響、永不相見(jiàn)。
Linux Cgroups技術(shù)
Cgroups是Control groups的縮寫(xiě),是Linux內(nèi)核提供的一種可以限制、記錄、隔離進(jìn)程組(process groups)所使用的物理資源(如:cpu,memory,IO等等)的機(jī)制。
最初由google的工程師提出,后來(lái)被整合進(jìn)Linux內(nèi)核。Cgroups也是LXC為實(shí)現(xiàn)虛擬化所使用的資源管理手段,可以說(shuō)沒(méi)Cgroups就沒(méi)有LXC。
Cgroups 功能
Cgroups最初的目標(biāo)是為資源管理提供的一個(gè)統(tǒng)一的框架,既整合現(xiàn)有的cpuset等子系統(tǒng),也為未來(lái)開(kāi)發(fā)新的子系統(tǒng)提供接口?,F(xiàn)在的cgroups適用于多種應(yīng)用場(chǎng)景,從單個(gè)進(jìn)程的資源控制,到實(shí)現(xiàn)操作系統(tǒng)層次的虛擬化(OS Level Virtualization)。
Cgroups提供了以下功能:
-
限制進(jìn)程組可以使用的資源數(shù)量(Resource limiting )。
- 比如:memory子系統(tǒng)可以為進(jìn)程組設(shè)定一個(gè)memory使用上限,一旦進(jìn)程組使用的內(nèi)存達(dá)到限額再申請(qǐng)內(nèi)存,就會(huì)出發(fā)OOM(out of memory)。
-
進(jìn)程組的優(yōu)先級(jí)控制(Prioritization )。
- 比如:可以使用cpu子系統(tǒng)為某個(gè)進(jìn)程組分配特定cpu share。
-
記錄進(jìn)程組使用的資源數(shù)量(Accounting )。
- 比如:可以使用cpuacct子系統(tǒng)記錄某個(gè)進(jìn)程組使用的cpu時(shí)間
-
進(jìn)程組隔離(Isolation)。
- 比如:使用ns子系統(tǒng)可以使不同的進(jìn)程組使用不同的namespace,以達(dá)到隔離的目的,不同的進(jìn)程組有各自的進(jìn)程、網(wǎng)絡(luò)、文件系統(tǒng)掛載空間。
-
進(jìn)程組控制(Control)。
- 比如:使用freezer子系統(tǒng)可以將進(jìn)程組掛起和恢復(fù)。
查看Linux是否啟動(dòng)了Cgroups
Cgroups在內(nèi)核層默認(rèn)已經(jīng)開(kāi)啟
$ uname -r
4.4.0-210-generic
$ cat /boot/config-4.4.0-210-generic | grep CGROUP
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_CGROUP_WRITEBACK=y
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
$ cat /boot/config-4.4.0-210-generic | grep MEM | grep CG
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
# CONFIG_MEMCG_SWAP_ENABLED is not set
CONFIG_MEMCG_KMEM=y
對(duì)應(yīng)的CGROUP項(xiàng)為“y”代表已經(jīng)打開(kāi)linux cgroups功能。
Cgroups子系統(tǒng)介紹
blkio :這個(gè)子系統(tǒng)為塊設(shè)備設(shè)定輸入/輸出限制,比如物理設(shè)備(磁盤,固態(tài)硬盤,USB 等等)。
cpu :這個(gè)子系統(tǒng)使用調(diào)度程序提供對(duì) CPU 的 cgroup 任務(wù)訪問(wèn)。
cpuacct:這個(gè)子系統(tǒng)自動(dòng)生成 cgroup 中任務(wù)所使用的 CPU 報(bào)告。
cpuset:這個(gè)子系統(tǒng)為 cgroup 中的任務(wù)分配獨(dú)立 CPU(在多核系統(tǒng))和內(nèi)存節(jié)點(diǎn)。
devices:這個(gè)子系統(tǒng)可允許或者拒絕 cgroup 中的任務(wù)訪問(wèn)設(shè)備。
freezer:這個(gè)子系統(tǒng)掛起或者恢復(fù) cgroup 中的任務(wù)。
memory : 這個(gè)子系統(tǒng)設(shè)定 cgroup 中任務(wù)使用的內(nèi)存限制,并自動(dòng)生成由那些任務(wù)使用的內(nèi)存資源報(bào)告。
net_cls: 這個(gè)子系統(tǒng)使用等級(jí)識(shí)別符(classid)標(biāo)記網(wǎng)絡(luò)數(shù)據(jù)包,可允許 Linux 流量控制程序(tc)識(shí)別從具體 cgroup 中生成的數(shù)據(jù)包。
ns:名稱空間子系統(tǒng)。
perf_event:增加了對(duì)每個(gè)cgroup的檢測(cè)跟蹤能力,可以檢測(cè)屬于某個(gè)特定的cgroup的所有線程以及運(yùn)行在特定cpu上的線程