說說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一旦賦予就不會改變。

圖1、進程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
圖2、hostname獨立

五、網路隔離

在每個容器所需要的最少網卡介面包括默認的lo迴環link(這個有什麼用):

除開lo,一般隔離的網路還有一對veth-pair。除了veth-pair,linux網卡方式還有其他

這個可以使用ip link help查看到。這裡提一下,ip是個很強大的命令,包含但不止於ifconfig和route的功能,是個很強大的工具,link這裡指的是鏈路層。對應的ip addr是網路層。

圖3、網路連接type