Docker原理之Namespaces

命名空間(namespaces)是 Linux 為我們提供的用于分離進程樹、網絡接口、掛載點以及進程間通信等資源的方法。

一、Namespaces

3.png

在日常使用 Linux 或者 macOS 時,我們并沒有運行多個完全分離的服務器的需要,但是如果我們在服務器上啟動了多個服務,這些服務其實會相互影響的,每一個服務都能看到其他服務的進程,也可以訪問宿主機器上的任意文件,這是很多時候我們都不愿意看到的,我們更希望運行在同一臺機器上的不同服務能做到完全隔離,就像運行在多臺不同的機器上一樣。

在這種情況下,一旦服務器上的某一個服務被入侵,那么入侵者就能夠訪問當前機器上的所有服務和文件,這也是我們不想看到的,而 Docker 其實就通過 Linux 的 Namespaces 對不同的容器實現了隔離。

Linux 的命名空間機制提供了以下六種不同的命名空間,包括 pid 命名空間、net 命名空間、ip c命名空間、m n t命名空間、UTS 命名空間、user 命名空間,通過這六個選項我們能在創建新的進程時設置新進程應該在哪些資源上與宿主機器進行隔離。

namespace隔離的內容系統調用參數
UTS主機名與域名CLONE_NEWUTS
IPC信號量、消息隊列和共享內容CLONE_NEWIPC
PID進程編號CLONE_NEWPID
Network網絡設備、網絡棧、端口CLONE_NEWNTE
Mount文件系統CLONE_NEWNS
User用戶和用戶組CLONE_NEWUSER

1、pid 命名空間(進程ID)

不同用戶的進程就是通過 pid 命名空間隔離開的,且不同命名空間中可以有相同 pid。所有的 LXC 進程在 Docker 中的父進程為Docker進程,每個 LXC 進程具有不同的命名空間。同時由于允許嵌套,因此可以很方便的實現嵌套的 Docker 容器。

2、net 命名空間(網絡)

有了 pid 命名空間, 每個命名空間中的 pid 能夠相互隔離,但是網絡端口還是共享 host 的端口。網絡隔離是通過 net 命名空間實現的, 每個 net 命名空間有獨立的 網絡設備, IP 地址, 路由表, /proc/net 目錄。這樣每個容器的網絡就能隔離開來。Docker 默認采用 veth 的方式,將容器中的虛擬網卡同 host 上的一 個Docker 網橋 docker0 連接在一起。

3、ipc 命名空間(進程間通信)

容器中進程交互還是采用了 Linux 常見的進程間交互方法(interprocess communication - IPC), 包括信號量、消息隊列和共享內存等。然而同 VM 不同的是,容器的進程間交互實際上還是 host 上具有相同 pid 命名空間中的進程間交互,因此需要在 IPC 資源申請時加入命名空間信息,每個 IPC 資源有一個唯一的 32 位 id。

4、mnt 命名空間(掛載文件系統)

類似 chroot,將一個進程放到一個特定的目錄執行。mnt 命名空間允許不同命名空間的進程看到的文件結構不同,這樣每個命名空間 中的進程所看到的文件目錄就被隔離開了。同 chroot 不同,每個命名空間中的容器在 /proc/mounts 的信息只包含所在命名空間的 mount point。

5、UTS 命名空間(主機名/域名)

UTS(“UNIX Time-sharing System”) 命名空間允許每個容器擁有獨立的 hostname 和 domain name, 使其在網絡上可以被視作一個獨立的節點而非 主機上的一個進程

6、user 命名空間(用戶)

每個容器可以有不同的用戶和組 id, 也就是說可以在容器內用容器內部的用戶執行程序而非主機上的用戶。

二、掛載點

雖然我們已經通過 Linux 的命名空間解決了進程和網絡隔離的問題,在 Docker 進程中我們已經沒有辦法訪問宿主機器上的其他進程并且限制了網絡的訪問,但是 Docker 容器中的進程仍然能夠訪問或者修改宿主機器上的其他目錄,這是我們不希望看到的。

在新的進程中創建隔離的掛載點命名空間需要在 clone 函數中傳入 CLONE_NEWNS,這樣子進程就能得到父進程掛載點的拷貝,如果不傳入這個參數子進程對文件系統的讀寫都會同步回父進程以及整個主機的文件系統。

如果一個容器需要啟動,那么它一定需要提供一個根文件系統(rootfs),容器需要使用這個文件系統來創建一個新的進程,所有二進制的執行都必須在這個根文件系統中。

10.png

想要正常啟動一個容器就需要在 rootfs 中掛載以上的幾個特定的目錄,除了上述的幾個目錄需要掛載之外我們還需要建立一些符號鏈接保證系統 IO 不會出現問題。

11.png

為了保證當前的容器進程沒有辦法訪問宿主機器上其他目錄,我們在這里還需要通過 libcotainer 提供的 pivor_root 或者 chroot 函數改變進程能夠訪問個文件目錄的根節點。

// pivor_root
put_old = mkdir(...);
pivot_root(rootfs, put_old);
chdir("/");
unmount(put_old, MS_DETACH);
rmdir(put_old);// chroot
mount(rootfs, "/", NULL, MS_MOVE, NULL);
chroot(".");
chdir("/");

到這里我們就將容器需要的目錄掛載到了容器中,同時也禁止當前的容器進程訪問宿主機器上的其他目錄,保證了不同文件系統的隔離。

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

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

相關文章

mysql 快速插入(insert)多條記錄

方法1: INSERT INTO table(col_1, col_2,col_3) VALUES(1,11,111); INSERT INTO table(col_1, col_2,col_3)   VALUES(2,22,222); INSERT INTO table(col_1, col_2,col_3)   VALUES(3,33,333); 有沒有更快捷的辦法呢?答案是有(見方法2) 方法2: INSERT INTO table(col…

Docker原理之CGroups

控制組(cgroups)是 Linux 內核的一個特性,主要用來對共享資源進行隔離、限制、審計 等。只有能控制分配到容器的資源,才能避免當多個容器同時運行時的對系統資源的競爭。控制組技術最早是由 Google 的程序員 2006 年起提出&#x…

Mysql中的轉義字符

字符串是多個字符組成的一個字符序列,由單引號( “”) 或雙引號 ( “"”) 字符包圍。(但在 ANSI 模式中運行時只能用單引號)。 例如: a string"another string"在一個字符串中,如果某個序列具有特殊的含義,每個序…

Docker原理之UnionFS

一、UnionFS Linux 的命名空間和控制組分別解決了不同資源隔離的問題,前者解決了進程、網絡以及文件系統的隔離,后者實現了 CPU、內存等資源的隔離,但是在 Docker 中還有另一個非常重要的問題需要解決 - 也就是鏡像。 鏡像到底是什么&#…

教你精確編寫高質量高性能的MySQL語法

在應用系統開發初期,由于開發數據庫數據比較少,對于查詢SQL語句,復雜視圖的編寫,剛開始不會體會出SQL語句各種寫法的性能優劣,但是如果將應用系統提交實際應用后,隨著數據庫中數據的增加,系統的…

Docker使用-Hello World

1、docker pull hello-world 拉去docker遠程倉庫中的Hello World的鏡像 [rootCarlota2 ~]# docker pull hello-world Using default tag: latest latest: Pulling from library/hello-world 0e03bdcc26d7: Pull complete Digest: sha256:7f0a9f93b4aa3022c3a4c147a449bf11e09…

Mysql數據庫引擎快速指南

如果你是個賽車手并且按一下按鈕就能夠立即更換引擎而不需要把車開到車庫里去換,那會是怎么感覺呢? MySQL 數據庫為開發人員所做的就好像是按按鈕換引擎;它讓你選擇數據庫引擎,并給你一條簡單的途徑來切換它。 MySQL的自帶引擎肯…

Docker使用-構建MySQL

拉取官方鏡像(我們這里選擇5.7,如果不寫后面的版本號則會自動拉取最新版) docker pull mysql:5.7 # 拉取 mysql 5.7 docker pull mysql # 拉取最新版mysql鏡像MySQL文檔地址 檢查是否拉取成功 $ sudo docker images一般來說數據庫容…

Java集合:什么是Java集合?

一、集合的由來 通常,我們的Java程序需要根據程序運行時才知道創建了多少個對象。但若非程序運行,程序開發階段,我們根本不知道到底需要多少個數量的對象,甚至不知道它的準確類型。為了滿足這些常規的編程需要,我們要…

Mysql截取中英數混合的字符串

在 mysql中截取字符串我們用 LEFT函數 LEFT(str,len) 返回從字符串str 開始的len 最左字符。 mysql> SELECT LEFT(foobarbar, 5); -> fooba 手冊上只介紹了截取英文字符串的方法,中文或者中英文的怎么辦呢?以下是截取中英混合的字符串(中國人…

Java集合:Collection接口

Collection是一個接口,繼承自Iterable。我們先看一下Iterable接口的源碼 一、Iterable package java.lang;import java.util.Iterator; import java.util.Objects; import java.util.Spliterator; import java.util.Spliterators; import java.util.function.Cons…

Java集合:List集合

List集合 List集合類中元素有序、且可重復,集合中的每個元素都有其對應的順序索引。 List容器中的元素都對應一個整數型的序號記載其在容器中的位置,可以根據序號存取容器中的元素。 JDK API中List接口的實現類常用的有:ArrayList、LinkList和…

MySQL為什么要set names

大家都知道SET NAMES x相當于SET character_set_client x;SET character_set_results x;SET character_set_connection x; 以下從MySQL5.0官方文檔上摘錄了相關內容,并翻譯,說明了相關系統變量的用處: What character set is the statem…

MySql日期處理系列-常用的日期推算處理

以下都是我平時用的一些日期推算處理方法,方法并不一定是最有效率的.全部均通過測試!轉載請注明來自[phpchina.com] #title: 常用的日期推算處理#auther: 小強(占卜師) #date: 2007-12-25 #取得當前日期set dtCURDATE();select dt; #當前日期這個月的第一天selec…

Java集合:Set集合

一、Set接口的特點 一個不包含重復元素的collection。更確切地講,Set不包含滿足e1.equals(e2)的元素對 e1和e2,并且最多包含一個null元素。 Set集合由Set接口和Set接口的實現類組成,Set接口繼承了Collection接口,因此包含了Coll…

談談我對MYSQL亂碼的解決辦法

經常更換虛擬主機,而各個服務商的MYSQL版本不同,當導入數據后,總會出現亂碼等無法正常顯示的問題,查了好多資料,總結出自己的一點技巧: WINDOWS 下導入應該這樣使用MYSQL的命令在DOS命令下進入mysql的bin目錄下,輸入mysql -uroot -p密碼 數據庫名稱<要恢復的數據庫, 例如我們…

Java集合:Map集合

一、簡述 public interface Map<K,V>將鍵映射到值的對象。一個映射不能包含重復的鍵&#xff1b;每個鍵最多只能映射到一個值。 注意&#xff1a;Map中的集合不能包含重復的鍵&#xff0c;值可以重復。每個鍵只能對應一個值。 Map集合是鍵值對形式存儲值的&#xff0c…

用離線編輯器Zoundry寫zblog日志

Zoundry是免費的離線網志發布工具&#xff0c;由于家里的網絡很差&#xff0c;寫了一半的日志經常因為掉線而丟失&#xff0c;這樣一款軟件的確是很必要的。今天下載試用了一下&#xff0c;感覺的確不錯。使用起來也很簡單&#xff1a; 1.下載并安裝zoundry軟件&#xff1a;現…

MySQL:基本命令

一、數據庫操作 1、查詢數據庫&#xff0c;命令如下: SHOW DATABASES;2、我們可以在登陸 MySQL 服務后&#xff0c;使用 create 命令創建數據庫&#xff0c;命令格式: CREATE DATABASE 數據庫名;3、使用 drop 命令刪除數據庫&#xff0c;命令格式&#xff1a; drop databas…

CentOS 5打造全功能Web服務器

轉&#xff1a;主要做為歷史記錄&#xff0c;以后用。另外很少見這么好的編譯的文章&#xff0c;其實我不推薦用編譯安裝。但這個文章不錯.V3.0 2007年11月11日 將搭建教程劃分階段以適應不同需要。加入程序優化&#xff0c;程序安全&#xff0c;加入memcache&#xff0c;squid…