溫馨提示×

溫馨提示×

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

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

Linux操作系統(tǒng)中Namespace的作用是什么

發(fā)布時(shí)間:2021-07-15 13:54:59 來源:億速云 閱讀:525 作者:Leah 欄目:系統(tǒng)運(yùn)維

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)Linux操作系統(tǒng)中Namespace的作用是什么,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

namespace的概念

namespace 是 Linux 內(nèi)核用來隔離內(nèi)核資源的方式。通過 namespace  可以讓一些進(jìn)程只能看到與自己相關(guān)的一部分資源,而另外一些進(jìn)程也只能看到與它們自己相關(guān)的資源,這兩撥進(jìn)程根本就感覺不到對方的存在。具體的實(shí)現(xiàn)方式是把一個(gè)或多個(gè)進(jìn)程的相關(guān)資源指定在同一個(gè)  namespace 中。

Linux操作系統(tǒng)中Namespace的作用是什么

Linux namespaces 是對全局系統(tǒng)資源的一種封裝隔離,使得處于不同 namespace 的進(jìn)程擁有獨(dú)立的全局系統(tǒng)資源,改變一個(gè)  namespace 中的系統(tǒng)資源只會(huì)影響當(dāng)前 namespace 里的進(jìn)程,對其他 namespace 中的進(jìn)程沒有影響。

namespace的用途

可能絕大多數(shù)的使用者和我一樣,是在使用 docker 后才開始了解 linux 的 namespace 技術(shù)的。實(shí)際上,Linux 內(nèi)核實(shí)現(xiàn)  namespace 的一個(gè)主要目的就是實(shí)現(xiàn)輕量級虛擬化(容器)服務(wù)。在同一個(gè) namespace  下的進(jìn)程可以感知彼此的變化,而對外界的進(jìn)程一無所知。這樣就可以讓容器中的進(jìn)程產(chǎn)生錯(cuò)覺,認(rèn)為自己置身于一個(gè)獨(dú)立的系統(tǒng)中,從而達(dá)到隔離的目的。也就是說 linux  內(nèi)核提供的 namespace 技術(shù)為 docker 等容器技術(shù)的出現(xiàn)和發(fā)展提供了基礎(chǔ)條件。

我們可以從 docker 實(shí)現(xiàn)者的角度考慮該如何實(shí)現(xiàn)一個(gè)資源隔離的容器。比如是不是可以通過 chroot  命令切換根目錄的掛載點(diǎn),從而隔離文件系統(tǒng)。為了在分布式的環(huán)境下進(jìn)行通信和定位,容器必須要有獨(dú)立的  IP、端口和路由等,這就需要對網(wǎng)絡(luò)進(jìn)行隔離。同時(shí)容器還需要一個(gè)獨(dú)立的主機(jī)名以便在網(wǎng)絡(luò)中標(biāo)識自己。接下來還需要進(jìn)程間的通信、用戶權(quán)限等的隔離。運(yùn)行在容器中的應(yīng)用需要有進(jìn)程號(PID),自然也需要與宿主機(jī)中的  PID 進(jìn)行隔離。也就是說這六種隔離能力是實(shí)現(xiàn)一個(gè)容器的基礎(chǔ),讓我們看看 linux 內(nèi)核的 namespace 特性為我們提供了什么樣的隔離能力:

Linux操作系統(tǒng)中Namespace的作用是什么

上表中的前六種 namespace 正是實(shí)現(xiàn)容器必須的隔離技術(shù),至于新近提供的 Cgroup namespace 目前還沒有被 docker  采用。相信在不久的將來各種容器也會(huì)添加對 Cgroup namespace 的支持。

namespace的發(fā)展歷史

Linux 在很早的版本中就實(shí)現(xiàn)了部分的 namespace,比如內(nèi)核 2.4 就實(shí)現(xiàn)了 mount namespace。大多數(shù)的 namespace  支持是在內(nèi)核 2.6 中完成的,比如 IPC、Network、PID、和 UTS。還有個(gè)別的 namespace 比較特殊,比如 User,從內(nèi)核 2.6  就開始實(shí)現(xiàn)了,但在內(nèi)核 3.8 中才宣布完成。同時(shí),隨著 Linux 自身的發(fā)展以及容器技術(shù)持續(xù)發(fā)展帶來的需求,也會(huì)有新的 namespace  被支持,比如在內(nèi)核 4.6 中就添加了 Cgroup namespace。

Linux 提供了多個(gè) API 用來操作 namespace,它們是 clone()、setns() 和 unshare()  函數(shù),為了確定隔離的到底是哪項(xiàng) namespace,在使用這些 API  時(shí),通常需要指定一些調(diào)用參數(shù):CLONE_NEWIPC、CLONE_NEWNET、CLONE_NEWNS、CLONE_NEWPID、CLONE_NEWUSER、CLONE_NEWUTS  和 CLONE_NEWCGROUP。如果要同時(shí)隔離多個(gè) namespace,可以使用 | (按位或)組合這些參數(shù)。同時(shí)我們還可以通過 /proc  下面的一些文件來操作 namespace。下面就讓讓我們看看這些接口的簡要用法。

查看進(jìn)程所屬的namespace

從版本號為 3.8 的內(nèi)核開始,/proc/[pid]/ns 目錄下會(huì)包含進(jìn)程所屬的 namespace 信息,使用下面的命令可以查看當(dāng)前進(jìn)程所屬的  namespace 信息:

$ ll /proc/$$/ns

Linux操作系統(tǒng)中Namespace的作用是什么

首先,這些 namespace 文件都是鏈接文件。鏈接文件的內(nèi)容的格式為 xxx:[inode number]。其中的 xxx 為 namespace  的類型,inode number 則用來標(biāo)識一個(gè) namespace,我們也可以把它理解為 namespace 的 ID。如果兩個(gè)進(jìn)程的某個(gè) namespace  文件指向同一個(gè)鏈接文件,說明其相關(guān)資源在同一個(gè) namespace 中。

其次,在 /proc/[pid]/ns 里放置這些鏈接文件的另外一個(gè)作用是,一旦這些鏈接文件被打開,只要打開的文件描述符(fd)存在,那么就算該  namespace 下的所有進(jìn)程都已結(jié)束,這個(gè) namespace 也會(huì)一直存在,后續(xù)的進(jìn)程還可以再加入進(jìn)來。

除了打開文件的方式,我們還可以通過文件掛載的方式阻止 namespace 被刪除。比如我們可以把當(dāng)前進(jìn)程中的 uts 掛載到 ~/uts 文件:

$ touch ~/uts $ sudo mount --bind /proc/$$/ns/uts ~/uts

使用 stat 命令檢查下結(jié)果:

Linux操作系統(tǒng)中Namespace的作用是什么

很神奇吧,~/uts 的 inode 和鏈接文件中的 inode number 是一樣的,它們是同一個(gè)文件。

clone函數(shù)

我們可以通過 clone() 在創(chuàng)建新進(jìn)程的同時(shí)創(chuàng)建 namespace。clone() 在 C 語言庫中的聲明如下:

/* Prototype for the glibc wrapper function */ #define _GNU_SOURCE #include <sched.h> int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);

實(shí)際上,clone() 是在 C 語言庫中定義的一個(gè)封裝(wrapper)函數(shù),它負(fù)責(zé)建立新進(jìn)程的堆棧并且調(diào)用對編程者隱藏的 clone()  系統(tǒng)調(diào)用。Clone() 其實(shí)是 linux 系統(tǒng)調(diào)用 fork() 的一種更通用的實(shí)現(xiàn)方式,它可以通過 flags 來控制使用多少功能。一共有 20 多種  CLONE_ 開頭的 falg(標(biāo)志位) 參數(shù)用來控制 clone 進(jìn)程的方方面面(比如是否與父進(jìn)程共享虛擬內(nèi)存等),下面我們只介紹與 namespace  相關(guān)的 4 個(gè)參數(shù):

  • fn:指定一個(gè)由新進(jìn)程執(zhí)行的函數(shù)。當(dāng)這個(gè)函數(shù)返回時(shí),子進(jìn)程終止。該函數(shù)返回一個(gè)整數(shù),表示子進(jìn)程的退出代碼。

  • child_stack:傳入子進(jìn)程使用的??臻g,也就是把用戶態(tài)堆棧指針賦給子進(jìn)程的 esp 寄存器。調(diào)用進(jìn)程(指調(diào)用 clone()  的進(jìn)程)應(yīng)該總是為子進(jìn)程分配新的堆棧。

  • flags:表示使用哪些 CLONE_ 開頭的標(biāo)志位,與 namespace  相關(guān)的有CLONE_NEWIPC、CLONE_NEWNET、CLONE_NEWNS、CLONE_NEWPID、CLONE_NEWUSER、CLONE_NEWUTS  和 CLONE_NEWCGROUP。

  • arg:指向傳遞給 fn() 函數(shù)的參數(shù)。

在后續(xù)的文章中,我們主要通過 clone() 函數(shù)來創(chuàng)建并演示各種類型的 namespace。

setns函數(shù)

通過 setns() 函數(shù)可以將當(dāng)前進(jìn)程加入到已有的 namespace 中。setns() 在 C 語言庫中的聲明如下:

#define _GNU_SOURCE #include <sched.h> int setns(int fd, int nstype);

和 clone() 函數(shù)一樣,C 語言庫中的 setns() 函數(shù)也是對 setns() 系統(tǒng)調(diào)用的封裝:

  • fd:表示要加入 namespace 的文件描述符。它是一個(gè)指向 /proc/[pid]/ns  目錄中文件的文件描述符,可以通過直接打開該目錄下的鏈接文件或者打開一個(gè)掛載了該目錄下鏈接文件的文件得到。

  • nstype:參數(shù) nstype 讓調(diào)用者可以檢查 fd 指向的 namespace 類型是否符合實(shí)際要求。若把該參數(shù)設(shè)置為 0 表示不檢查。

前面我們提到:可以通過掛載的方式把 namespace 保留下來。保留 namespace 的目的是為以后把進(jìn)程加入這個(gè) namespace 做準(zhǔn)備。在  docker 中,使用 docker exec 命令在已經(jīng)運(yùn)行著的容器中執(zhí)行新的命令就需要用到 setns() 函數(shù)。為了把新加入的 namespace  利用起來,還需要引入 execve() 系列的函數(shù)(筆者在 《Linux 創(chuàng)建子進(jìn)程執(zhí)行任務(wù)》一文中介紹過 execve()  系列的函數(shù),有興趣的同學(xué)可以前往了解),該函數(shù)可以執(zhí)行用戶的命令,比較常見的用法是調(diào)用 /bin/bash 并接受參數(shù)運(yùn)行起一個(gè) shell。

unshare函數(shù)和命令

通過 unshare 函數(shù)可以在原進(jìn)程上進(jìn)行 namespace 隔離。也就是創(chuàng)建并加入新的 namespace 。unshare() 在 C  語言庫中的聲明如下:

#define _GNU_SOURCE #include <sched.h> int unshare(int flags);

和前面兩個(gè)函數(shù)一樣,C 語言庫中的 unshare() 函數(shù)也是對 unshare() 系統(tǒng)調(diào)用的封裝。調(diào)用 unshare()  的主要作用就是:不啟動(dòng)新的進(jìn)程就可以起到資源隔離的效果,相當(dāng)于跳出原先的 namespace 進(jìn)行操作。

系統(tǒng)還默認(rèn)提供了一個(gè)叫 unshare 的命令,其實(shí)就是在調(diào)用 unshare() 系統(tǒng)調(diào)用。下面的 demo 使用 unshare 命令把當(dāng)前進(jìn)程的  user namespace 設(shè)置成了 root:

Linux操作系統(tǒng)中Namespace的作用是什么

上述就是小編為大家分享的Linux操作系統(tǒng)中Namespace的作用是什么了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

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

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

AI