說說linux容器的隔離
- 2020 年 2 月 13 日
- 筆記
前言:
說到docker,大家都懂。但是LXC可能就比較陌生。Docker的起源於LXC。LXC的英文全稱是Linux Container,相比較其他虛擬機而言,是一種輕量級虛擬化技術,它介於Chroot(linux的一個改變根目錄掛載點的機制)和完整開發的虛擬機之間。LXC不使用單獨的內核資源,但是可以創建一個類似的Linux作業系統環境。
Linux Daemon(LXD)是一個輕量級容器管理程式,他是凌駕於LXC之上而衍生的一套外部管理工具。Docker也使用類似技術。LXD使用了LXC API來管理LXC,而且新增RESTful API。
這邊文章通過研究LXC的隔離特徵來說明容器的一些原理。
一、獨立的命名空間
每個容器都有一套獨立的Linux環境命名空間。命名空間的作用是對每一個環境做隔離,使用環境的用戶來看,好像是一個新的機器環境。命名空間是linux內核用來隔離內核資源的方式。通過 namespace 可以讓一些進程只能看到與自己相關的一部分資源,而另外一些進程也只能看到與它們自己相關的資源,這兩撥進程根本就感覺不到對方的存在。具體的實現方式是把一個或多個進程的相關資源指定在同一個 namespace 中。
一套獨立的環境需要做到有用戶id獨立、進程id獨立、root根目錄獨立、網路獨立、UTS(UNIX Time-sharing System 的縮寫,主機名和NIS域名)獨立。
二、用戶和用戶組ID獨立
每個Linux系統要求的uid可選範圍都不一樣,但是uid通常是由32位,也就是最大值可以是2^31-2(範圍:1~4294967295)。路徑/etc/login.defs文件的UID_MIN、UID_MAX限定了用戶useradd新用戶自己設置uid的最小值和最大值,2^31-1是個無效id,實驗測試以下命令不能成功。
useradd -u 4294967296 test
Uid的取值區間範圍作了劃分,不同發行商的Linux系統有不一樣的劃分,但是一般是這麼約定:
- 0-99系統用戶uid:
- 100-500:系統管理管理員程式或者安裝腳本產生的用戶
- 1000-x:用戶uid,系統登錄uid限制於了登錄uid的最小值和最大值
- 網路uid:更偏向於高值
- 6553x:nobody
三、進程ID獨立
每個Linux系統要求的pid可選範圍都不一樣,最大值可以設置到 4194304 (= 222) 。
在64位可以設置到222差不多400w左右。Linux程式碼設計者認為這個數已經足夠了。如果是32位,pid最大值是32768.進程id一旦賦予就不會改變。

每個系統的設置查看cat /proc/sys/kernel/pid_max。
我在ubuntu 16和centos 7分別得到了131072(= 217)和32768(= 215)。
3.1 那如果到達了最大值,會怎麼樣?
Pid是順序產生的。當pid到達最大值,它會從0繼續開始找最近可用的pid,如果都沒有pid,會報錯。
四、UTS(hostname獨立)
以下測試了hostname在每個命名空間是獨立存在的。
unshare --uts --fork bash hostname//查看繼承的原來hostname hostname modified //修改成新的hostname hostname //確認修改成功 eixt //退出 hostname //此時hostname還是原來的hostname

五、網路隔離
在每個容器所需要的最少網卡介面包括默認的lo迴環link(這個有什麼用):
除開lo,一般隔離的網路還有一對veth-pair。除了veth-pair,linux網卡方式還有其他
這個可以使用ip link help查看到。這裡提一下,ip是個很強大的命令,包含但不止於ifconfig和route的功能,是個很強大的工具,link這裡指的是鏈路層。對應的ip addr是網路層。
