Linux namespace之:mount namespace

理解mount namespace

用戶通常使用mount命令來掛載普通文件系統,但實際上mount能掛載的東西非常多,甚至連現在功能完善的Linux系統,其內核的正常運行也都依賴于掛載功能,比如掛載根文件系統/。其實所有的掛載功能和掛載信息都由內核負責提供和維護,mount命令只是發起了mount()系統調用去請求內核。

mount namespace可隔離出一個具有獨立掛載點信息的運行環境,內核知道如何去維護每個namespace的掛載點列表。即「每個namespace之間的掛載點列表是獨立的,各自掛載互不影響」

內核將每個進程的掛載點信息保存在/proc/<pid>/{mountinfo,mounts,mountstats}三個文件中:

$?ls?-1?/proc/$$/mount*
/proc/26276/mountinfo
/proc/26276/mounts
/proc/26276/mountstats

「具有獨立的掛載點信息,意味著每個mnt namespace可具有獨立的目錄層次」,這在容器中起了很大作用:容器可以掛載只屬于自己的文件系統。

當創建mount namespace時,內核將拷貝一份當前namespace的掛載點信息列表到新的mnt namespace中,此后兩個mnt namespace就沒有了任何關系(不是真的毫無關系,參考后文shared subtrees)。

創建mount namespace的方式是使用unshare命令的--mount, -m選項:

#?創建mount+uts?namespace
#?-m或--mount表示創建mount?namespace
#?可同時創建具有多種namespace類型的namespace
unshare?--mount?--uts?<program>

下面做一個簡單的試驗,在root namespace中掛載1.iso文件到/mnt/iso1目錄,在新建的mount+uts namespace中掛載2.iso到/mnt/iso2目錄:

[~]->$?cd
[~]->$?mkdir?iso
[~]->$?cd?iso
[iso]->$?mkdir?-p?iso1/dir1
[iso]->$?mkdir?-p?iso2/dir2??
[iso]->$?mkisofs?-o?1.iso?iso1??#?將iso1目錄制作成鏡像文件1.iso
[iso]->$?mkisofs?-o?2.iso?iso2??#?將iso2目錄制作成鏡像文件2.iso
[iso]->$?ls
1.iso??2.iso??iso1??iso2
[iso]->$?sudo?mkdir?/mnt/{iso1,iso2}
[iso]->$?ls?-l?/proc/$$/ns/mnt
lrwxrwxrwx?1?...?/proc/26276/ns/mnt?->?'mnt:[4026531840]'#?在root?namespace中掛載1.iso到/mnt/iso1目錄
[iso]->$?sudo?mount?1.iso?/mnt/iso1??
mount:?/mnt/iso:?WARNING:?device?write-protected,?mounted?read-only.
[iso]->$?mount?|?grep?iso1
/home/longshuai/iso/1.iso?on?/mnt/iso1?type?iso9660#?創建mount+uts?namespace
[iso]->$?sudo?unshare?-m?-u?/bin/bash
#?雖然這個namespace是mount+uts的namespace
#?但注意mnt?namespace和uts?namespace的inode并不一樣
root@longshuai-vm:/home/longshuai/iso#?ls?-l?/proc/$$/ns
lrwxrwxrwx?...?cgroup?->?'cgroup:[4026531835]'
lrwxrwxrwx?...?ipc?->?'ipc:[4026531839]'
lrwxrwxrwx?...?mnt?->?'mnt:[4026532588]'
lrwxrwxrwx?...?net?->?'net:[4026531992]'
lrwxrwxrwx?...?pid?->?'pid:[4026531836]'
lrwxrwxrwx?...?pid_for_children?->?'pid:[4026531836]'
lrwxrwxrwx?...?user?->?'user:[4026531837]'
lrwxrwxrwx?...?uts?->?'uts:[4026532589]'#?修改主機名為ns1
root@longshuai-vm:/home/longshuai/iso#?hostname?ns1
root@longshuai-vm:/home/longshuai/iso#?exec?$SHELL#?在namespace中,可以看到root?namespace中的掛載信息
root@ns1:/home/longshuai/iso#?mount?|?grep?'iso1'?
/home/longshuai/iso/1.iso1?on?/mnt/iso1?type?iso9660#?namespace中掛載2.iso2
root@ns1:/home/longshuai/iso#?mount?2.iso2?/mnt/iso2/
mount:?/mnt/iso2:?WARNING:?device?write-protected,?mounted?read-only.
root@ns1:/home/longshuai/iso#?mount?|?grep?'iso[12]'
/home/longshuai/iso/1.iso1?on?/mnt/iso1?type?iso9660
/home/longshuai/iso/2.iso2?on?/mnt/iso2?type?iso9660#?在namespace中卸載iso1
root@ns1:/home/longshuai/iso#?umount?/mnt/iso1/
root@ns1:/home/longshuai/iso#?mount?|?grep?'iso[12]'?
/home/longshuai/iso/2.iso2?on?/mnt/iso2?type?iso9660
root@ns1:/home/longshuai/iso#?ls?/mnt/iso1/
root@ns1:/home/longshuai/iso#?ls?/mnt/iso2
dir2####?打開另一個Shell終端窗口
#?iso1掛載仍然存在,且沒有iso2的掛載信息
[iso]->$?mount?|?grep?iso
/home/longshuai/iso/1.iso1?on?/mnt/iso1?type?iso9660
[iso]->$?ls?/mnt/iso2
[iso]->$?ls?/mnt/iso1
dir1

以上是mount namespace的基本內容,只有一個關鍵點:創建mnt namespace時會拷貝當前namespace的掛載點信息,之后兩個namespace就沒有關系了。

mnt namespace: shared subtrees

Linux的每個掛載點都具有一個決定該掛載點「是否共享子掛載點」的屬性,稱為shared subtrees。該屬性以決定某掛載點之下新增或移除子掛載點時,是否同步影響它【副本】掛載點。

簡單說說shared subtrees特性,該特性有什么用呢?以mnt namespace為例來簡單介紹一下shared subtrees特性。

假設基于root namespace創建了一個mnt namespace(ns1),那么ns1將具有當前root namespace的掛載點信息拷貝。如果此時新插入了一塊磁盤并對其分區格式化,然后在root namespace中對其進行掛載,默認情況下,在ns1中將看不到新掛載的文件系統。這種默認行為可以通過修改shared subtrees屬性來改變。

其實,用戶創建namespace,其目的一般是希望創建完全隔離的運行環境,所以默認情況下,拷貝掛載點信息時不會拷貝shared subtrees屬性,而是將mount namespace中的所有掛載點的shared subtrees屬性設置為private。

所以,假如namespace ns1中/mnt/foo是一個掛載點目錄,基于ns1創建了一個mnt namespace ns2,在默認情況下:

  • 如果此時在ns1中新增一個掛載點/mnt/foo/bar,將不會影響到ns2中的/mnt/foo

  • 如果此時在ns2中新增一個掛載點/mnt/foo/baz,也不會影響到ns1中的/mnt/foo

  • 移除掛載點操作也一樣

但這種默認行為可以改變。

unshare有一個選項--propagation private|shared|slave|unchanged可控制創建mnt namespace時掛載點的共享方式。

  • private:表示新創建的mnt namespace中的掛載點的shared subtrees屬性都設置為private,即ns1和ns2的掛載點互不影響

  • shared:表示新創建的mnt namespace中的掛載點的shared subtrees屬性都設置為shared,即ns1或ns2中新增或移除子掛載點都會同步到另一方

  • slave:表示新創建的mnt namespace中的掛載點的shared subtrees屬性都設置為slave,即ns1中新增或移除子掛載點會影響ns2,但ns2不會影響ns1

  • unchanged:表示拷貝掛載點信息時也拷貝掛載點的shared subtrees屬性,也就是說掛載點A原來是shared,在mnt namespace中也將是shared

  • 不指定--progapation選項時,創建的mount namespace中的掛載點的shared subtrees默認值是private

例如:

#參考https://www.junmajinlong.com/linux/mount_bind/
# root namespace:ns0
$?sudo?mount?--bind?foo?bar
$?sudo?mount?--make-shared?bar????#?掛載點設置為shared#?創建mnt namespace:ns1,且也拷貝shared屬性
$?PS1="ns1$?"?sudo?unshare?-m?-u?--propagation?unchanged?sh
[ns1]$?grep?'foo'?/proc/self/mountinfo?
944?682?8:5?foo?bar?rw,relatime?shared:1#?在ns1中bar掛載點下新增子掛載點,子掛載點將同步到ns0
#?因為foo和bar已綁定,且bar的屬性是shared,所以還會同步到foo目錄下
[ns1]$?sudo?mount?--bind?baz?bar/subfoo
[ns1]$?tree?foo?bar?
foo
└──?subfoo└──?subbaz
bar
└──?subfoo└──?subbaz
[ns1]$?grep?'foo'?/proc/self/mountinfo
944?682?8:5?foo?bar?rw,relatime?shared:1
945?944?8:5?baz?bar/subfoo?rw,relatime?shared:1
947?682?8:5?baz?foo/subfoo?rw,relatime?shared:1#?第二個窗口會話中查看ns0的掛載點信息
#?已經同步過來了
$?grep?'foo'?/proc/self/mountinfo
622?29?8:5??foo?bar?rw,relatime?shared:1
948?622?8:5?baz?bar/subfoo?rw,relatime?shared:1
946?29?8:5??baz?foo/subfoo?rw,relatime?shared:1
$?tree?foo?bar?
foo
└──?subfoo└──?subbaz
bar
└──?subfoo└──?subbaz

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/535444.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/535444.shtml
英文地址,請注明出處:http://en.pswp.cn/news/535444.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux namespace之:network namespace

理解network namespace network namespace用來隔離網絡環境&#xff0c;「在network namespace中&#xff0c;網絡設備、端口、套接字、網絡協議棧、路由表、防火墻規則等都是獨立的」。 因network namespace中具有獨立的網絡協議棧&#xff0c;因此每個network namespace中都…

Kubernetes 的原理

kubernetes 已經成為容器編排領域的王者&#xff0c;它是基于容器的集群編排引擎&#xff0c;具備擴展集群、滾動升級回滾、彈性伸縮、自動治愈、服務發現等多種特性能力。 本文將帶著大家快速了解 kubernetes &#xff0c;了解我們談論 kubernetes 都是在談論什么。 kuberne…

Zookeeper:實現“分布式鎖”的 Demo

Zookeeper 能保證數據的強一致性&#xff0c;用戶任何時候都可以相信集群中每個節點的數據都是相同的。一個用戶創建一個節點作為鎖&#xff0c;另一個用戶檢測該節點&#xff0c;如果存在&#xff0c;代表別的用戶已經鎖住&#xff0c;如果不存在&#xff0c;則可以創建一個節…

JavaIO流:案例

java.io 包下需要掌握的流有 16 個&#xff0c;本篇內容包括&#xff1a;java.io包下需要掌握的流、Java IO 案例。 文章目錄一、java.io包下需要掌握的流二、Java IO 案例1、Demo 1&#xff08;FileInputStream&#xff09;2、Demo 2&#xff08;FileInputStream&#xff09;3…

比對excel數據

#!/usr/bin/env pythonimport openpyxl from openpyxl.styles import PatternFill from openpyxl.styles import colors from openpyxl.styles import Font, Color aD:/測算單位設置/比對/吉林/tmp001.xlsx bD:/測算單位設置/比對/吉林/國網吉林電力.xlsx cD:/測算單位設置/比對…

CPU 是如何執行任務的

前言 你清楚下面這幾個問題嗎&#xff1f; 有了內存&#xff0c;為什么還需要 CPU Cache&#xff1f; CPU 是怎么讀寫數據的&#xff1f; 如何讓 CPU 能讀取數據更快一些&#xff1f; CPU 偽共享是如何發生的&#xff1f;又該如何避免&#xff1f; CPU 是如何調度任務的&a…

Ansible 的自動化運維

1、Ansible 特點 Ansible 自 2012 年發布以來&#xff0c;很快在全球流行&#xff0c;其特點如下&#xff1a; Ansible 基于 Python 開發&#xff0c;運維工程師對其二次開發相對比較容易&#xff1b; Ansible 豐富的內置模塊&#xff0c;幾乎可以滿足一切要求&#xff1b; …

Shell 信號發送與捕捉

1、Linux信號類型 信號&#xff08;Signal&#xff09;&#xff1a;信號是在軟件層次上對中斷機制的一種模擬&#xff0c;通過給一個進程發送信號&#xff0c;執行相應的處理函數。 進程可以通過三種方式來響應一個信號&#xff1a; 1&#xff09;忽略信號&#xff0c;即對信…

運維面試題總結

集群相關 簡述 ETCD 及其特點&#xff1f; etcd 是 CoreOS 團隊發起的開源項目&#xff0c;是一個管理配置信息和服務發現&#xff08;service discovery&#xff09;的項目&#xff0c;它的目標是構建一個高可用的分布式鍵值&#xff08;key-value&#xff09;數據庫&#x…

詳解設計模式:建造者模式

建造者模式&#xff08;Builder Pattern&#xff09;也叫做生成器模式&#xff0c;是 GoF 的 23 種設計模式的一種&#xff0c;它將一個復雜對象的構建與它的表示分離&#xff0c;使得同樣的構建過程可以創建不同的表示。 當我們需要實列化一個復雜的類&#xff0c;以得到不同結…

圖文并茂 VLAN 詳解,讓你看一遍就理解 VLAN

一、為什么需要VLAN 1.1、什么是VLAN? VLAN(Virtual LAN)&#xff0c;翻譯成中文是“虛擬局域網”。LAN可以是由少數幾臺家用計算機構成的網絡&#xff0c;也可以是數以百計的計算機構成的企業網絡。VLAN所指的LAN特指使用路由器分割的網絡——也就是廣播域。 在此讓我們先復習…

認識VLAN,并學會VLAN的劃分和網絡配置實例

VLAN的劃分和網絡的配置實例 1、VLAN基礎知識 VLAN&#xff08;Virtual Local Area Network&#xff09;的中文名為&#xff1a;“虛擬局域網”&#xff0c;注意和VPN&#xff08;虛擬專用網&#xff09;進行區分。 VLAN是一種將局域網設備從邏輯上劃分&#xff08;不是從物…

VLAN劃分及配置注意事項

VLAN&#xff08;Virtual Local Area Network&#xff09;即虛擬局域網&#xff0c;是將一個物理的LAN在邏輯上劃分成多個廣播域的通信技術。VLAN內的主機間可以直接通信&#xff0c;而VLAN間不能直接通信&#xff0c;從而將廣播報文限制在一個VLAN內。VLAN之間的通信是通過第3…

Docker原理剖析

一、簡介 1、了解Docker的前生LXC LXC為Linux Container的簡寫。可以提供輕量級的虛擬化&#xff0c;以便隔離進程和資源&#xff0c;而且不需要提供指令解釋機制以及全虛擬化的其他復雜性。相當于C中的NameSpace。容器有效地將由單個操作系統管理的資源劃分到孤立的組中&#…

獲取Linux內存、cpu、磁盤IO等信息

#!/bin/bash # 獲取要監控的本地服務器IP地址 IPifconfig | grep inet | grep -vE inet6|127.0.0.1 | awk {print $2} echo "IP地址&#xff1a;"$IP# 獲取cpu總核數 cpu_numgrep -c "model name" /proc/cpuinfo echo "cpu總核數&#xff1a;"$c…

Docker容器網絡解析

Docker 容器網絡的發展歷史 在 Dokcer 發布之初&#xff0c;Docker 是將網絡、管理、安全等集成在一起的&#xff0c;其中網絡模塊可以為容器提供橋接網絡、主機網絡等簡單的網絡功能。 從 1.7 版本開始&#xff0c;Docker正是把網絡和存儲這兩部分的功能都以插件化形式剝離出來…

將指定excel的一列數據提取到另一個excel的指定列

#!/usr/bin/env python import openpyxl bjD:/地市縣公司/西藏臺賬數據分析-設備臺帳分析.xlsx wb openpyxl.load_workbook (bj) get_sheets wb.sheetnames #print(get_sheets) TA01TA01 TA02TA02 TA03TA03 TE01TE01 YG201YG201 YG202YG202 YG203YG203 YG204YG204 YG205YG205…

Docker 數據管理介紹

默認容器的數據是保存在容器的可讀寫層&#xff0c;當容器被刪除時其上的數據也會丟失&#xff0c;所以為了實現數據的持久性則需要選擇一種數據持久技術來保存數據。官方提供了三種存儲方式&#xff1a;Volumes、Bind mounts和tmpfs。前面還介紹了&#xff1a;Docker 服務終端…

Docker 數據持久化的三種方案

容器中的數據可以存儲在容器層。但是將數據存放在容器層存在以下問題&#xff1a; 數據不是持久化。意思是如果容器刪除了&#xff0c;這些數據也就沒了 主機上的其它進程不方便訪問這些數據 對這些數據的I/O會經過存儲驅動&#xff0c;然后到達主機&#xff0c;引入了一層間…

Git 存儲原理及相關實現

Git 是目前最流行的版本控制系統&#xff0c;從本地開發到生產部署&#xff0c;我們每天都在使用 Git 進行我們的版本控制&#xff0c;除了日常使用的命令之外&#xff0c;如果想要對 Git 有更深一步的了解&#xff0c;那么研究下 Git 的底層存儲原理將會對理解 Git 及其使用非…