linux的6種Namespace介紹

linux一共實現(xiàn)了6種不同類型的Namespace:

Namespace 類型 系統(tǒng)調(diào)用參數(shù) 內(nèi)核版本
Mount Namespace CLONE_NEWNS 2.4.19
UTS Namespace CLONE_NEWUTS 2.6.19
IPC Namespace CLONE_NEWIPC 2.6.19
PID Namespace CLONE_NEWPID 2.6.24
Network Namespace CLONE_NEWNET 2.6.29
User Namespace CLONE_NEWUSER 3.8

Namespace的api主要使用3個系統(tǒng)調(diào)用:

  • clone() 創(chuàng)建新的進程
  • unshare() 將進程移除某個Namespace
  • sents() 將進程加入到Namespace

UTS Namespace

UTS Namespace 主要用來隔離nodename(hostname) 和domainname 兩個系統(tǒng)標識。

在UTS Namespace里面, 每個Namespace 允許有自己的hostname 滔悉。

下面將使用Go 來做一個UTS Namespace 的例子醋安。

package main

import (
    "os/exec"
    "syscall"
    "os"
    "log"
)

func main() {
    cmd := exec.Command("sh")
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags: syscall.CLONE_NEWUTS,
    }
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }

}

解釋一下代碼借杰, exec .Command (“sh” )用來指定被fork 出來的新進程內(nèi)的初始命令斩箫,默認使用s h 來執(zhí)行里伯。下面就是設(shè)置系統(tǒng)調(diào)用參數(shù)含思, 像2.1.l 小節(jié)中講到的一樣崎弃,使用CL ONENE WU TS 這個標識符去創(chuàng)建一個UTS Namespace 。Go 幫我們封裝了對clone() 函數(shù)的調(diào)用含潘,這段代碼執(zhí)行后就會進入到一個s h 運行環(huán)境中饲做。

執(zhí)行
go run main. go 命令,在這個交互式環(huán)境里遏弱,使用pstree -pl 查看一下系統(tǒng)中進程之間的關(guān)系盆均, 如下

sh-4.2# echo $$
23137
sh-4.2# pstree -p| grep 23137
           |-sshd(1291)-+-sshd(21695)---bash(21697)---go(23110)-+-utc(23132)-+-sh(23137)-+-grep(23215)

驗證一下父進程和子進程是否不在同一個UTS Namespace 中, 看到確實不在同一個uts namespace中

sh-4.2# readlink /proc/23137/ns/uts 
uts:[4026532440]
sh-4.2# readlink /proc/23132/ns/uts 
uts:[4026531838]

所以在這個環(huán)境內(nèi)修改hostname 應(yīng)該不影響外部主機漱逸, 下面來做一下實驗:

sh-4.2# hostname -b test
sh-4.2# hostname
test
開啟新的終端查看hostname
[root@DH-PROXY-T01 gofile]# hostname
DH-PROXY-T01

IPC Namespace(消息隊列)

IPC Namespace 用來隔離System V IPC 和POSIX message queues 每一個IPC Namespace都有自己的system v IPC 和POSIX message queue

樣例:

package main

import (
    "os/exec"
    "syscall"
    "os"
    "log"
)

func main() {
    cmd := exec.Command("sh")
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC,
    }
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }

}

查看隊列

[root@DH-PROXY-T01 gofile]# go run ipc.go 
sh-4.2#
sh-4.2# ipcmk -Q
消息隊列 id:0
sh-4.2# ipcs -q

--------- 消息隊列 -----------
鍵        msqid      擁有者  權(quán)限     已用字節(jié)數(shù) 消息      
0xfd247a01 0          root       644        0            0   

切換到另一個shell泪姨,查看,沒有消息證明ipc隔離

sh-4.2# ipcs -q

--------- 消息隊列 -----------
鍵        msqid      擁有者  權(quán)限     已用字節(jié)數(shù) 消息

PIO Namespace

PID Namespace 是用來隔離進程ID 的虹脯。同樣一個進程在不同的PID Namespace 里可以擁有不同的PID 驴娃。這樣就可以理解, 在docker container 里面循集, 使用ps -ef 經(jīng)常會發(fā)現(xiàn)唇敞, 在容器內(nèi), 前臺運行的那個進程PID 是1 , 但是在容器外疆柔,使用ps -ef 會發(fā)現(xiàn)同樣的進程卻有不同的PID 咒精, 這就是PID Namespace 做的事情。

在上一小結(jié)代碼的基礎(chǔ)上旷档, 再修改一下代碼模叙, 添加一個syscall.CLONE_ NEWPID ,代表為fork 出來的子進程創(chuàng)建自己的PID Namespace 鞋屈。

package main

import (
    "os/exec"
    "syscall"
    "os"
    "log"
)

func main() {
    cmd := exec.Command("sh")
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID,
    }
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }

}

要打開兩個shell 范咨。首先在宿主機上看一下進程樹,找一下進程的真實PID

[root@DH-PROXY-T01 gofile]# go run ipc.go 
sh-4.2# echo $$
1
[root@DH-PROXY-T01 gofile]# pstree -p | grep ipc
           |-sshd(1291)-+-sshd(13183)-+-bash(13185)---go(13409)-+-ipc(13431)-+-sh(13436)

可以看到厂庇,該操作打印了當(dāng)前Namespace 的PID 渠啊, 其值為1 。也就是說权旷,這個13431 的PID 被映射到Namespace 里后PID 為1替蛉。這里還不能使用ps 來查看, 因為ps 和top 等命令會使用/proc 內(nèi)容拄氯,具體內(nèi)容在下面的Mount Namespace 部分會進行講解躲查。

Mount Namespace

Mount Namespace 用來隔離各個進程看到的掛載點視圖。在不同Names pace 的進程中译柏, 看到的文件系統(tǒng)層次是不一樣的镣煮。在Mount Namespace 中調(diào)用mount()和umount() 僅僅只會影響當(dāng)前Namespace 內(nèi)的文件系統(tǒng),而對全局的文件系統(tǒng)是沒有影響的艇纺≡蹙玻看到這里, 也許就會想到chroot()黔衡。它也是將某一個子目錄變成根節(jié)點蚓聘。但是, MountNames pace 不僅能實現(xiàn)這個功能盟劫,而且能以更加靈活和安全的方式實現(xiàn)夜牡。Mount Namespace 是Linux 第一個實現(xiàn)的Names pace 類型, 因此侣签,它的系統(tǒng)調(diào)用參數(shù)是NEWNS ( New Namespace 的縮寫)塘装。

增加了NEWNS 標識,如下

package main

import (
    "os/exec"
    "syscall"
    "os"
    "log"
)

func main() {
    cmd := exec.Command("sh")
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS,
    }
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }

}

運行影所,執(zhí)行命令蹦肴,此時的/proc 還是宿主機的,執(zhí)行ps -ef 無法正常運行

sh-4.2# ls /proc/
1      consoles   driver       iomem     key-users   mdstat   net       self      sysrq-trigger  version
acpi       cpuinfo    execdomains  ioports   kmsg    meminfo  pagetypeinfo  slabinfo  sysvipc    vmallocinfo
buddyinfo  crypto     fb       irq       kpagecount  misc     partitions    softirqs  timer_list     vmstat
bus    devices    filesystems  kallsyms  kpageflags  modules  sched_debug   stat      timer_stats    zoneinfo
cgroups    diskstats  fs       kcore     loadavg     mounts   schedstat swaps     tty
cmdline    dma        interrupts   keys      locks   mtrr     scsi      sys   uptime
sh-4.2# ps -ef
Error, do this: mount -t proc proc /proc

掛在后再執(zhí)行猴娩,發(fā)現(xiàn)sh的pid為1阴幌,因為ps -ef是獲取的proc的內(nèi)容勺阐,所以當(dāng)前的mount namespace和外部的空間是隔離的,proc 是一個文件系統(tǒng)矛双,提供額外的機制渊抽,可以通過內(nèi)核和內(nèi)核模塊將信息發(fā)送給進程。

sh-4.2# mount -t proc proc /proc
sh-4.2# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 09:26 pts/0    00:00:00 sh
root         7     1  0 09:30 pts/0    00:00:00 ps -ef

User Namespace

User N amespace 主要是隔離用戶的用戶組ID 议忽。也就是說懒闷, 一個進程的User ID 和GroupID 在User Namespace 內(nèi)外可以是不同的。比較常用的是栈幸,在宿主機上以一個非root 用戶運行創(chuàng)建一個User Namespace 愤估, 然后在User Namespace 里面卻映射成root 用戶。這意味著侦镇, 這個進程在User Namespace 里面有root 權(quán)限灵疮,但是在User Namespace 外面卻沒有root 的權(quán)限织阅。從Linux Kernel 3 . 8 開始壳繁, 非root 進程也可以創(chuàng)建User Namespace , 并且此用戶在N amespace 里面可以被映射成root 荔棉, 且在Namespace 內(nèi)有root 權(quán)限闹炉。下面,繼續(xù)以一個例子來描述润樱, 代碼如下渣触。

package main

import (
    "log"
    "os"
    "os/exec"
    "syscall"
)

func main() {
    cmd := exec.Command("sh")
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID |
            syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER,
    }
    cmd.SysProcAttr.Credential = &syscall.Credential{
        Uid: uint32(1), Gid: uint32(1)}
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }
    os.Exit(-1)
}

本例在原來的基礎(chǔ)上增加了syscall.CLONE_NEWUSER 。首先壹若,以root 來運行這個程序嗅钻,運行前在宿主機上看一下當(dāng)前的用戶和用戶組, 顯示如下:

root@iZ254rt8xflZ :~/gocode/src/book# id
uid=O(root) gid=O(root ) groups=O(root )

可以看到我們是root 用戶店展,接下來運行一下程序养篓。
root@iZ254rt8xflZ : ~/ gocode/src/book# go run main.go

$ id
uid=65534 (nobody ) gid=65534(nogroup) groups=65534(nogroup)

可以看到, 它們的UID 是不同的赂蕴,因此說明User Namespace 生效了柳弄。

Network Namespace

Network Namespace 是用來隔離網(wǎng)絡(luò)設(shè)備、IP 地址端口等網(wǎng)絡(luò)械的Namespace 概说。NetworkNamespace 可以讓每個容器擁有自己獨立的(虛擬的)網(wǎng)絡(luò)設(shè)備碧注,而且容器內(nèi)的應(yīng)用可以綁定到自己的端口,每個Namespace 內(nèi)的端口都不會互相沖突糖赔。在宿主機上搭建網(wǎng)橋后萍丐,就能很方便地實現(xiàn)容器之間的通信,而且不同容器上的應(yīng)用可以使用相同的端口放典。同樣逝变,在2.1.6 小節(jié)的代碼的基礎(chǔ)上增加syscall.CLONE_ NEWNET 標識符船万,如下:

package main

import (
    "log"
    "os"
    "os/exec"
    "syscall"
)

func main() {
    cmd := exec.Command("sh")
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID |
            syscall.CLONE_NEWNS | syscall.CLONE_NEWNET,
    }
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }
    os.Exit(-1)
}

進入程序查看網(wǎng)絡(luò)

[root@DH-PROXY-T01 gofile]# go run main.go 
sh-4.2# ifconfig 
sh-4.2# mount -t proc proc /proc
sh-4.2# ifconfig 
sh-4.2# 

返回宿主機查看網(wǎng)絡(luò)

[root@DH-PROXY-T01 gofile]# ifconfig
ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.50.133.98  netmask 255.255.255.0  broadcast 10.50.133.255
        ether 00:50:56:b2:47:aa  txqueuelen 1000  (Ethernet)

我們發(fā)現(xiàn), 在Namespace 里面什么網(wǎng)絡(luò)設(shè)備都沒有骨田。這樣就能斷定Network Namespace 與宿主機之間的網(wǎng)絡(luò)是處于隔離狀態(tài)了耿导。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市态贤,隨后出現(xiàn)的幾起案子舱呻,更是在濱河造成了極大的恐慌,老刑警劉巖悠汽,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件箱吕,死亡現(xiàn)場離奇詭異,居然都是意外死亡柿冲,警方通過查閱死者的電腦和手機茬高,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來假抄,“玉大人怎栽,你說我怎么就攤上這事∷薇ィ” “怎么了熏瞄?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谬以。 經(jīng)常有香客問我强饮,道長,這世上最難降的妖魔是什么为黎? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任邮丰,我火速辦了婚禮,結(jié)果婚禮上铭乾,老公的妹妹穿的比我還像新娘剪廉。我一直安慰自己,他們只是感情好片橡,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布妈经。 她就那樣靜靜地躺著,像睡著了一般捧书。 火紅的嫁衣襯著肌膚如雪吹泡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天经瓷,我揣著相機與錄音爆哑,去河邊找鬼。 笑死舆吮,一個胖子當(dāng)著我的面吹牛揭朝,可吹牛的內(nèi)容都是我干的队贱。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼潭袱,長吁一口氣:“原來是場噩夢啊……” “哼柱嫌!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起屯换,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤编丘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后彤悔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嘉抓,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年晕窑,在試婚紗的時候發(fā)現(xiàn)自己被綠了抑片。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡杨赤,死狀恐怖敞斋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情望拖,我是刑警寧澤渺尘,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站说敏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏丢郊。R本人自食惡果不足惜盔沫,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枫匾。 院中可真熱鬧架诞,春花似錦、人聲如沸干茉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽角虫。三九已至沾谓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間戳鹅,已是汗流浹背均驶。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留枫虏,地道東北人妇穴。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓爬虱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親腾它。 傳聞我的和親對象是個殘疾皇子跑筝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容