溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Linux的命名空間如何理解

發(fā)布時(shí)間:2022-01-26 09:33:22 來(lái)源:億速云 閱讀:347 作者:kk 欄目:建站服務(wù)器

小編今天帶大家了解Linux的命名空間如何理解,文中知識(shí)點(diǎn)介紹的非常詳細(xì)。覺(jué)得有幫助的朋友可以跟著小編一起瀏覽文章的內(nèi)容,希望能夠幫助更多想解決這個(gè)問(wèn)題的朋友找到問(wèn)題的答案,下面跟著小編一起深入學(xué)習(xí)“Linux的命名空間如何理解”的知識(shí)吧。

一、基本概念

??命名空間(Linux namespace)是linux內(nèi)核針對(duì)實(shí)現(xiàn)容器虛擬化映入的一個(gè)特性。我們創(chuàng)建的每個(gè)容器都有自己的命名空間,運(yùn)行在其中的應(yīng)用都像是在獨(dú)立的操作系統(tǒng)中運(yùn)行一樣,命名空間保證了容器之間互不影響。

??Linux的命名空間機(jī)制提供了一種資源隔離的解決方案。PID,IPC,Network等系統(tǒng)資源不再是全局性的,而是屬于特定的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)有影響。

??傳統(tǒng)上,在Linux以及其他衍生的UNIX變體中,許多資源是全局管理的。例如,系統(tǒng)中的所有進(jìn)程按照慣例是通過(guò)PID標(biāo)識(shí)的,這意味著內(nèi)核必須管理一個(gè)全局的PID列表。而且,所有調(diào)用者通過(guò)uname系統(tǒng)調(diào)用返回的系統(tǒng)相關(guān)信息(包括系統(tǒng)名稱和有關(guān)內(nèi)核的一些信息)都是相同的。用戶ID的管理方式類似,即各個(gè)用戶是通過(guò)一個(gè)全局唯一的UID號(hào)標(biāo)識(shí)。

??全局ID使得內(nèi)核可以有選擇地允許或拒絕某些特權(quán)。雖然UID為0的root用戶基本上允許做任何事,但其他用戶ID則會(huì)受到限制。例如UID為n的用戶,不允許殺死屬于用戶m的進(jìn)程( m≠ n)。但這不能防止用戶看到彼此,即用戶n可以看到另一個(gè)用戶m也在計(jì)算機(jī)上活動(dòng)。只要用戶只能操縱他們自己的進(jìn)程,這就沒(méi)什么問(wèn)題,因?yàn)闆](méi)有理由不允許用戶看到其他用戶的進(jìn)程。

??但有些情況下,這種效果可能是不想要的。如果提供Web主機(jī)的供應(yīng)商打算向用戶提供Linux計(jì)算機(jī)的全部訪問(wèn)權(quán)限,包括root權(quán)限在內(nèi)。傳統(tǒng)上,這需要為每個(gè)用戶準(zhǔn)備一臺(tái)計(jì)算機(jī),代價(jià)太高。使用KVM或VMWare提供的虛擬化環(huán)境是一種解決問(wèn)題的方法,但資源分配做得不是非常好。計(jì)算機(jī)的各個(gè)用戶都需要一個(gè)獨(dú)立的內(nèi)核,以及一份完全安裝好的配套的用戶層應(yīng)用。

??命名空間提供了一種不同的解決方案,所需資源較少。在虛擬化的系統(tǒng)中,一臺(tái)物理計(jì)算機(jī)可以運(yùn)行多個(gè)內(nèi)核,可能是并行的多個(gè)不同的操作系統(tǒng)。而命名空間則只使用一個(gè)內(nèi)核在一臺(tái)物理計(jì)算機(jī)上運(yùn)作,前述的所有全局資源都通過(guò)命名空間抽象起來(lái)。這使得可以將一組進(jìn)程放置到容器中,各個(gè)容器彼此隔離。隔離可以使容器的成員與其他容器毫無(wú)關(guān)系。但也可以通過(guò)允許容器進(jìn)行一定的共享,來(lái)降低容器之間的分隔。例如,容器可以設(shè)置為使用自身的PID集合,但仍然與其他容器共享部分文件系統(tǒng)。

二、實(shí)現(xiàn)

??命名空間的實(shí)現(xiàn)需要兩個(gè)部分:每個(gè)子系統(tǒng)的命名空間結(jié)構(gòu),將此前所有的全局組件包裝到命名空間中;將給定進(jìn)程關(guān)聯(lián)到所屬各個(gè)命名空間的機(jī)制。

??子系統(tǒng)此前的全局屬性現(xiàn)在封裝到命名空間中,每個(gè)進(jìn)程關(guān)聯(lián)到一個(gè)選定的命名空間。每個(gè)可以感知命名空間的內(nèi)核子系統(tǒng)都必須提供一個(gè)數(shù)據(jù)結(jié)構(gòu),將所有通過(guò)命名空間形式提供的對(duì)象集中起來(lái)。 struct nsproxy用于匯集指向特定于子系統(tǒng)的命名空間包裝器的指針。在文件nsproxy.h中有:

/*
 * A structure to contain pointers to all per-process
 * namespaces - fs (mount), uts, network, sysvipc, etc.
 *
 * The pid namespace is an exception -- it's accessed using
 * task_active_pid_ns.  The pid namespace here is the
 * namespace that children will use.
 *
 * 'count' is the number of tasks holding a reference.
 * The count for each namespace, then, will be the number
 * of nsproxies pointing to it, not the number of tasks.
 *
 * The nsproxy is shared by tasks which share all namespaces.
 * As soon as a single namespace is cloned or unshared, the
 * nsproxy is copied.
 */struct nsproxy {
	atomic_t count;
	struct uts_namespace *uts_ns;
	struct ipc_namespace *ipc_ns;
	struct mnt_namespace *mnt_ns;
	struct pid_namespace *pid_ns_for_children;
	struct net 	     *net_ns;
	struct time_namespace *time_ns;
	struct time_namespace *time_ns_for_children;
	struct cgroup_namespace *cgroup_ns;};

??當(dāng)前內(nèi)核的以下范圍可以感知到命名空間

??1、 UTS命名空間包含了運(yùn)行內(nèi)核的名稱、版本、底層體系結(jié)構(gòu)類型等信息。 UTS是UNIXTimesharing System的簡(jiǎn)稱。

??2、保存在struct ipc_namespace中的所有與進(jìn)程間通信( IPC)有關(guān)的信息。

??3、 已經(jīng)裝載的文件系統(tǒng)的視圖,在struct mnt_namespace中給出。

??4、 有關(guān)進(jìn)程ID的信息,由struct pid_namespace提供。

??5、 struct user_namespace保存的用于限制每個(gè)用戶資源使用的信息。

??6、struct net_ns包含所有網(wǎng)絡(luò)相關(guān)的命名空間參數(shù)。

??當(dāng)我討論相應(yīng)的子系統(tǒng)時(shí),會(huì)介紹各個(gè)命名空間容器的內(nèi)容。在由于在創(chuàng)建新進(jìn)程時(shí)可使用fork建立一個(gè)新的命名空間,因此必須提供控制該行為的適當(dāng)?shù)臉?biāo)志。每個(gè)命名空間都有一個(gè)對(duì)應(yīng)的標(biāo)志,在sched.h文件內(nèi):

#define CLONE_NEWCGROUP		0x02000000	/* New cgroup namespace */
#define CLONE_NEWUTS		0x04000000	/* New utsname namespace */
#define CLONE_NEWIPC		0x08000000	/* New ipc namespace */
#define CLONE_NEWUSER		0x10000000	/* New user namespace */
#define CLONE_NEWPID		0x20000000	/* New pid namespace */
#define CLONE_NEWNET		0x40000000	/* New network namespace */

??不同類型的命名空間的作用:

??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ī)名

??每個(gè)進(jìn)程都關(guān)聯(lián)到自身的命名空間視圖,在任務(wù)定義的結(jié)構(gòu)體task_struct中有如下定義:

struct task_struct {.../* 命名空間 */struct nsproxy *nsproxy;...}

??因?yàn)槭褂昧酥羔?,多個(gè)進(jìn)程可以共享一組子命名空間。這樣,修改給定的命名空間,對(duì)所有屬于該命名空間的進(jìn)程都是可見(jiàn)的。
??init_nsproxy定義了初始的全局命名空間,其中維護(hù)了指向各子系統(tǒng)初始的命名空間對(duì)象的指針。在kernel/nsproxy.c文件內(nèi)有

struct nsproxy init_nsproxy = {
	.count			= ATOMIC_INIT(1),
	.uts_ns			= &init_uts_ns,#if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC)
	.ipc_ns			= &init_ipc_ns,#endif
	.mnt_ns			= NULL,
	.pid_ns_for_children	= &init_pid_ns,#ifdef CONFIG_NET
	.net_ns			= &init_net,#endif#ifdef CONFIG_CGROUPS
	.cgroup_ns		= &init_cgroup_ns,#endif#ifdef CONFIG_TIME_NS
	.time_ns		= &init_time_ns,
	.time_ns_for_children	= &init_time_ns,#endif};

三、UTS命名空間

??UTS命名空間幾乎不需要特別的處理,因?yàn)樗恍枰?jiǎn)單量,沒(méi)有層次組織。所有相關(guān)信息都匯集到下列結(jié)構(gòu)的一個(gè)實(shí)例中。在utsname.h文件內(nèi):

struct uts_namespace {
	struct new_utsname name;
	struct user_namespace *user_ns;
	struct ucounts *ucounts;
	struct ns_common ns;} __randomize_layout;

??uts_namespace所提供的屬性信息本身包含在struct new_utsname中:

struct oldold_utsname {
	char sysname[9];
	char nodename[9];
	char release[9];
	char version[9];
	char machine[9];};#define __NEW_UTS_LEN 64struct old_utsname {
	char sysname[65];
	char nodename[65];
	char release[65];
	char version[65];
	char machine[65];};struct new_utsname {
	char sysname[__NEW_UTS_LEN + 1];
	char nodename[__NEW_UTS_LEN + 1];
	char release[__NEW_UTS_LEN + 1];
	char version[__NEW_UTS_LEN + 1];
	char machine[__NEW_UTS_LEN + 1];
	char domainname[__NEW_UTS_LEN + 1];}

??各個(gè)字符串分別存儲(chǔ)了系統(tǒng)的名稱( Linux…)、內(nèi)核發(fā)布版本、機(jī)器名,等等。使用uname工具可以取得這些屬性的當(dāng)前值,也可以在/proc/sys/kernel/中看到

z@z-virtual-machine:~$ cat /proc/sys/kernel/ostype
Linux
z@z-virtual-machine:~$ cat /proc/sys/kernel/osrelease5.3.0-40-generic

??初始設(shè)置保存在init_uts_ns中,在init/version.c文件內(nèi):

struct uts_namespace init_uts_ns = {
	.ns.count = REFCOUNT_INIT(2),
	.name = {
		.sysname	= UTS_SYSNAME,
		.nodename	= UTS_NODENAME,
		.release	= UTS_RELEASE,
		.version	= UTS_VERSION,
		.machine	= UTS_MACHINE,
		.domainname	= UTS_DOMAINNAME,
	},
	.user_ns = &init_user_ns,
	.ns.inum = PROC_UTS_INIT_INO,#ifdef CONFIG_UTS_NS
	.ns.ops = &utsns_operations,#endif};

什么是Linux系統(tǒng)

Linux是一種免費(fèi)使用和自由傳播的類UNIX操作系統(tǒng),是一個(gè)基于POSIX的多用戶、多任務(wù)、支持多線程和多CPU的操作系統(tǒng),使用Linux能運(yùn)行主要的Unix工具軟件、應(yīng)用程序和網(wǎng)絡(luò)協(xié)議。

感謝大家的閱讀,以上就是“Linux的命名空間如何理解”的全部?jī)?nèi)容了,學(xué)會(huì)的朋友趕緊操作起來(lái)吧。相信億速云小編一定會(huì)給大家?guī)?lái)更優(yōu)質(zhì)的文章。謝謝大家對(duì)億速云網(wǎng)站的支持!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI