自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Docker內(nèi)核技術(shù)原理之Mount Namespace

云計(jì)算
容器里面每個(gè)容器都可以單獨(dú)掛載存儲(chǔ),這就需要掛載隔離。Mount Namespace是Linux最早支持的命名空間,支持在不同的Namespace中可以看到不同的掛載視圖。

[[411078]]

上一篇文章介紹了UTS Namespace,容器里面每個(gè)容器都可以單獨(dú)掛載存儲(chǔ),這就需要掛載隔離。Mount Namespace是Linux最早支持的命名空間,支持在不同的Namespace中可以看到不同的掛載視圖。

 

我們可以通過(guò)unshare分離出一個(gè)新的掛載空間,然后在這個(gè)新的mount空間內(nèi)將/usr/bin目錄掛載到/mnt目錄下面,當(dāng)exit退回后,mount失效了。如下所示。

  1. # unshare --mount 
  2. # mount --bind /usr/bin/ /mnt/ 
  3. # ls /mnt/cp 
  4. /mnt/cp 
  5. # exit 
  6. # ls /mnt/cp 
  7. ls: 無(wú)法訪問(wèn)'/mnt/cp': 沒(méi)有那個(gè)文件或目錄 

其實(shí),unshare --mount的本質(zhì)就是clone的時(shí)候指定flag為CLONE_NEWNS,后續(xù)Demo原理類似。

內(nèi)核原理

要理解Mount Namespace必須先了解mount原理,mount可以將一個(gè)文件系統(tǒng)掛載到另外一個(gè)文件系統(tǒng)下面。下圖是將一個(gè)文件系統(tǒng)掛載到根文件系統(tǒng)的”/home“路徑下面,mount的關(guān)系通過(guò)一個(gè)內(nèi)核結(jié)構(gòu)體 mount標(biāo)識(shí),mount結(jié)構(gòu)體中核心的就是mnt_mountpoint指向掛載的目標(biāo)路徑,在圖中就是根文件系統(tǒng)的/home路徑。

 

上圖中home有兩個(gè)dentry,一個(gè)是根文件系統(tǒng)下的dentry,它是目標(biāo)掛載點(diǎn),另外一個(gè)dentry是被掛載文件系統(tǒng)的dentry。譬如將一個(gè)掛載盤格式EXT4文件系統(tǒng),那么這個(gè)dentry就掛載盤的根文件系統(tǒng)dentry。通過(guò)mount struct就可以將外部文件系統(tǒng)掛載到根文件系統(tǒng)上面。

每個(gè)mount struct里面都有一個(gè)mnt_namespace,它是一個(gè)指向掛載命令空間的指針,之前命名空間概述文章中介紹的ns_proxy也是指向這個(gè)mnt_namespace。這樣進(jìn)程和它的掛載空間就可以關(guān)聯(lián)起來(lái)了。

Mount Namespace還有一個(gè)特殊的地方就是掛載傳播(mount propagation),掛載傳播是指由一個(gè)掛載對(duì)象的狀態(tài)變化導(dǎo)致的其它掛載對(duì)象的掛載與解除掛載動(dòng)作的事件。針對(duì)容器這個(gè)場(chǎng)景就是,如果Docker內(nèi)執(zhí)行了一次掛載后,宿主機(jī)上是否能看到這個(gè)掛載,反過(guò)來(lái),如果宿主機(jī)執(zhí)行了某個(gè)掛載,容器內(nèi)是否能看見(jiàn)。常見(jiàn)的有三種掛載方式:

共享關(guān)系(share relationship),如果兩個(gè)掛載對(duì)象具有共享關(guān)系,那么一個(gè)掛載對(duì)象中的掛載事件會(huì)傳播到另一個(gè)掛載對(duì)象,反之亦然。也就是說(shuō)容器和宿主機(jī)的掛載會(huì)互相可見(jiàn)。

從屬關(guān)系(slave relationship),如果兩個(gè)掛載對(duì)象形成從屬關(guān)系,那么一個(gè)掛載對(duì)象中的掛載事件會(huì)傳播到另一個(gè)掛載對(duì)象,但是反過(guò)來(lái)不行;在這種關(guān)系中,從屬對(duì)象是事件的接收者。也就是說(shuō)主機(jī)掛載容器可見(jiàn),反過(guò)來(lái)不行。

私有關(guān)系(private relationship),之間互相不傳播,相互獨(dú)立。也就是說(shuō)相互不可見(jiàn)。

實(shí)戰(zhàn)DEMO

在上面的程序中添加CLONE_NEWNS便可以創(chuàng)建一個(gè)新的Mount Namespace。代碼還是基于之前PID的代碼,加上CLONE_NEWNS。

  1. package main 
  2. import ( 
  3.     "fmt" 
  4.     "os" 
  5.     "os/exec" 
  6.     "syscall" 
  7. func main() { 
  8.     cmd := exec.Command("/bin/sh"
  9.  
  10.     cmd.Stdin = os.Stdin 
  11.     cmd.Stdout = os.Stdout 
  12.     cmd.Stderr = os.Stderr 
  13.  
  14.     cmd.Env = []string{"PS1=-[ns-process]- # "
  15.  
  16.     cmd.SysProcAttr = &syscall.SysProcAttr{ 
  17.         Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS, 
  18.     } 
  19.  
  20.     if err := cmd.Run(); err != nil { 
  21.         fmt.Printf("Error running the /bin/sh command - %s\n", err) 
  22.         os.Exit(1) 
  23.     } 

通過(guò)go run 直接運(yùn)行后,執(zhí)行文章最開(kāi)始unshare的Demo。你會(huì)發(fā)現(xiàn)

[[411079]]

 

因?yàn)槟J(rèn)情況下掛載傳播是share共享,所以當(dāng)我們?cè)谛碌腗ount Namespace執(zhí)行掛載后,也會(huì)傳播到主機(jī)上面。我們可以在主機(jī)上面先將根目錄調(diào)整到私有掛載,這樣容器內(nèi)的掛載就不會(huì)傳播到主機(jī)上面了。

  1. # mount --make-rprivate / 

 

上面的Demo也可以正常運(yùn)行了。

 

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2021-07-10 08:29:13

Docker內(nèi)核Namespace

2018-06-26 08:27:21

DRDS內(nèi)核 列式存儲(chǔ)

2016-09-20 21:32:16

DockerLinux Names

2016-09-20 22:04:55

Docker Linux Names

2009-03-22 21:29:11

多核技術(shù)

2016-06-20 16:10:11

無(wú)內(nèi)核技術(shù)Node.js

2023-08-10 14:02:15

2010-04-01 09:29:14

2020-11-17 09:09:55

Unity技術(shù)大會(huì)

2018-08-27 16:41:07

KPI技術(shù)人

2017-01-12 19:15:03

Linux內(nèi)核調(diào)試自構(gòu)proc

2021-02-20 20:51:24

工具內(nèi)核kprobe

2025-01-02 11:06:22

2009-08-06 18:12:06

2018-10-08 09:00:58

考核技術(shù)人KPI

2019-06-11 09:30:04

PKI密鑰網(wǎng)絡(luò)安全

2019-12-12 10:58:37

Docker容器引擎

2009-03-22 21:36:34

多核架構(gòu)質(zhì)變

2009-03-18 13:10:59

多核服務(wù)器MIPS

2023-09-27 23:19:04

Linuxmount
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)