欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Docker中關(guān)于Namespace隔離機(jī)制全面解析

 更新時(shí)間:2022年06月21日 11:40:24   作者:飛向星的客機(jī)  
為了更好地理解容器的運(yùn)行原理,本篇文章將會(huì)以?Linux?宿主機(jī)為例,介紹容器的底層技術(shù),包括容器的命名空間、控制組、聯(lián)合文件系統(tǒng)等,需要的朋友可以參考下

?? 前言

Docker 容器能夠在服務(wù)器中高效運(yùn)行,離不開容器底層技術(shù)的支持。
 為了更好地理解容器的運(yùn)行原理,本篇文章將會(huì)以 Linux 宿主機(jī)為例,介紹容器的底層技術(shù),包括容器的命名空間、控制組、聯(lián)合文件系統(tǒng)等。

1. Docker基本架構(gòu)

Docker 目前采用標(biāo)準(zhǔn)的 C/S 架構(gòu),即服務(wù)端—客戶端架構(gòu),服務(wù)端用于管理數(shù)據(jù),客戶端負(fù)責(zé)與用戶交互,將獲取的用戶信息交由服務(wù)器處理,如圖所示??

那么上面的名詞是什么意思呢?我這里重新畫了一幅圖來解析??

服務(wù)器與客戶機(jī)既可以運(yùn)行在同一臺(tái)機(jī)器上,也可以運(yùn)行在不同機(jī)器上,通過 Socket(套接字)或者 RESTful API 進(jìn)行通信。

?? 服務(wù)端

Docker 服務(wù)端也就是 Docker daemon,一般在宿主機(jī)后臺(tái)運(yùn)行,接收來自客戶的請(qǐng)求、并處理這些請(qǐng)求。在設(shè)計(jì)上,Docker 服務(wù)端是一個(gè)模塊化的架構(gòu),通過專門的 Engine 模塊來分發(fā)、管理各個(gè)來自客戶端的任務(wù)。

Docker 服務(wù)端默認(rèn)監(jiān)聽本地的 unix:///var/run/Docker.sock 套接字,只允許本地的 root 用戶或 Docker 用戶組成員訪問,可以通過 -H 參數(shù)來修改監(jiān)聽的方式。

例如,讓服務(wù)器監(jiān)聽本地的 TCP 連接 1234 端口,代碼如下所示:

此外,Docker 還支持通過 HTTPS 認(rèn)證的方式來驗(yàn)證訪問。

Debian/Ubuntu14.04 等使用 upstart 管理啟動(dòng)服務(wù)的系統(tǒng)中,Docker 服務(wù)端的默認(rèn)啟動(dòng)配置文件在 /etc/default/Docker
 在使用 systemd 管理啟動(dòng)服務(wù)的系統(tǒng),配置文件在 /etc/systemd/system/Docker.service.d/Docker.conf。

?? 客戶端

用戶不能與服務(wù)端直接交互,Docker 客戶端為用戶提供一系列可執(zhí)行命令,用戶通過這些命令與 Docker 服務(wù)端進(jìn)行交互。

用戶使用的 Docker 可執(zhí)行命令就是客戶端程序。與 Docker 服務(wù)端不同的是,客戶端發(fā)送命令后,等待服務(wù)端返回信息,收到返回信息后,客戶端立刻執(zhí)行結(jié)束并退出。用戶執(zhí)行新的命令時(shí),需要再次調(diào)用客戶端命令。

同樣,客戶端默認(rèn)通過本地的 unix:///var/run/Docker.sock 套接字向服務(wù)端發(fā)送命令。如果服務(wù)端不在默認(rèn)監(jiān)聽的地址,則需要用戶在執(zhí)行命令時(shí)指定服務(wù)端地址,如圖所示??

例如:假設(shè)服務(wù)端監(jiān)聽本地的 TCP 連接 1234 端口 tcp://127.0.0.1:1234,只有通過 -H 參數(shù)指定了正確的地址信息才能連接到服務(wù)端。

首先,查看 Docker 信息,示例代碼如下:

從以上示例中可以看到,Docker 并沒有連接到服務(wù)端,但 Docker 客戶端仍可以為用戶提供服務(wù)。

然后,通過命令指定正確的地址信息,再次查看 Docker 信息,示例代碼如下:

從以上示例中可以看到,指定了正確的地址信息之后,Docker 順利連接到服務(wù)端。

Docker 服務(wù)端運(yùn)行在主機(jī)上, 通過 Socket 連接從客戶端訪問,服務(wù)端從客戶端接受命令并管理運(yùn)行在主機(jī)上的容器。

2. Namespace

?? Namespace介紹

Linux 操作系統(tǒng)中,容器用來實(shí)現(xiàn)“隔離”的技術(shù)稱為 Namespace(命名空間)。

Namespace 技術(shù)實(shí)際上修改了應(yīng)用進(jìn)程看待整個(gè)計(jì)算機(jī)的 “視圖”,即應(yīng)用進(jìn)程的 “視線” 被操作系統(tǒng)做了限制,只能 “看到” 某些指定的內(nèi)容,如圖所示??

但對(duì)于宿主機(jī)來說,這些被進(jìn)行“隔離”的進(jìn)程跟其他進(jìn)程并沒有太大區(qū)別。

下面運(yùn)行一個(gè) CentOS 7 容器,示例代碼如下:

從以上示例中可以看到,bash 是這個(gè)容器內(nèi)部的第 1 號(hào)進(jìn)程,即 PID=1,而這個(gè)容器里一共只有兩個(gè)進(jìn)程在運(yùn)行,這就意味著,前面執(zhí)行的 /bin/sh,以及剛剛執(zhí)行的 ps,已經(jīng)被 Docker 隔離在一個(gè)與宿主機(jī)完全不同的空間當(dāng)中。

理論上,每當(dāng)在宿主機(jī)上運(yùn)行一個(gè) /bin/sh 程序,操作系統(tǒng)都會(huì)給它分配一個(gè)進(jìn)程編號(hào),例如,PID=100。這個(gè)編號(hào)是進(jìn)程的唯一標(biāo)識(shí),就像員工的工號(hào)一樣。所以,PID=100,可以粗略地理解為這個(gè) /bin/sh 是公司里的第 100 號(hào)員工。

而現(xiàn)在,要通過 Docker/bin/sh 運(yùn)行在一個(gè)容器當(dāng)中。這時(shí),Docker 就會(huì)在這個(gè)第 100 號(hào)員工入職時(shí)給他施一個(gè) “障眼法” 讓他永遠(yuǎn)看不到前面的其他 99 個(gè)員工,這樣,他就會(huì)以為自己就是公司里的第 1 號(hào)員工。

這種機(jī)制其實(shí)就是對(duì)被隔離應(yīng)用的進(jìn)程空間做了手腳,使這些進(jìn)程只能看到重新計(jì)算過的進(jìn)程號(hào),例如 PID=1??蓪?shí)際上,它們?cè)谒拗鳈C(jī)的操作系統(tǒng)里,還是原來的第 100號(hào) 進(jìn)程,如圖所示??

下面通過宿主機(jī)查看容器進(jìn)程號(hào),示例代碼如下:

在宿主機(jī)中通過容器的 ID 號(hào)查看其進(jìn)程號(hào),可以看出其進(jìn)程號(hào)為 7548,這就是 Linux 里的 Namespace 機(jī)制。
 在 Linux 系統(tǒng)中創(chuàng)建線程調(diào)用是 clone() 函數(shù),例如:int pid = clone(main_function, stack_size, SIGCHLD, NULL); 這個(gè)調(diào)用會(huì)創(chuàng)建一個(gè)新的進(jìn)程,并且返回它的進(jìn)程號(hào)。
 系統(tǒng)調(diào)用 clone() 創(chuàng)建一個(gè)新進(jìn)程時(shí),可以在參數(shù)中指定 CLONE_NEWPID ,例如:int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL); 這時(shí),新創(chuàng)建的這個(gè)進(jìn)程將會(huì) “看到” 一個(gè)全新的進(jìn)程空間,在這空間里,它的進(jìn)程號(hào)是 1。在宿主機(jī)真實(shí)的進(jìn)程空間里,這個(gè)進(jìn)程的真實(shí)進(jìn)程號(hào)不變。
 當(dāng)然,可以多次執(zhí)行上面的 clone() 調(diào)用,這樣就會(huì)創(chuàng)建多個(gè) PID Namespace,而每個(gè) Namespace 里的應(yīng)用進(jìn)程,都會(huì)認(rèn)為自己是當(dāng)前容器里的第 1 號(hào)進(jìn)程,它們既看不到宿主機(jī)里真正的進(jìn)程空間,也看不到其他 PID Namespace 里的具體情況。

?? Namespace的類型

命名空間分為多種類型,對(duì)應(yīng)用程序進(jìn)行不同程度的隔離,下面挨個(gè)介紹。

?? Mount namespace

Mount Namespace 將一個(gè)文件系統(tǒng)的頂層目錄與另一個(gè)文件系統(tǒng)的子目錄關(guān)聯(lián)起來,使其成為一個(gè)整體。該子目錄稱為掛載點(diǎn),這個(gè)動(dòng)作稱為掛載。

?? UTS namespace

UTSUNIX Time-sharing System,UNIX 分時(shí)系統(tǒng))Namespace 提供主機(jī)名和域名的隔離,使子進(jìn)程有獨(dú)立的主機(jī)名和域名,這一特性在 Docker 容器技術(shù)中被運(yùn)用,使 Docker 容器在網(wǎng)絡(luò)上被視作一個(gè)獨(dú)立的節(jié)點(diǎn),而不僅僅是宿主機(jī)上的一個(gè)進(jìn)程。

?? IPC namespace

IPCInter-Process Communication,進(jìn)程間通信)NamespaceUNIXLinux 下進(jìn)程間通信的一種方式。
 IPC 有共享內(nèi)存、信號(hào)量、消息隊(duì)列等方式。此外,也需要對(duì) IPC 進(jìn)行隔離,如此一來,只有在同一個(gè) Namespace 下的進(jìn)程才能相互通信。
 IPC 需要有一個(gè)全局的 ID,既然是全局的,就意味著 Namespace 需要對(duì)這個(gè) ID 號(hào)進(jìn)行 隔離,不能讓其他 Namespace 的進(jìn)程 “看到”。

?? PID namespace

PID Namespace 用來隔離進(jìn)程的 ID 空間,使不同 PID Namespace 里的進(jìn)程 ID 號(hào)可以重復(fù)且相互之間不影響。
 
PID Namespace 可以嵌套,也就是說有父子關(guān)系。在當(dāng)前 Namespace 里面創(chuàng)建的所有新的 Namespace 都是當(dāng)前 Namespace 的子 Namespace
 
在父 Namespace 里面可以 “看到” 所有子 Namespace 里的進(jìn)程信息,而在子 Namespace 里看不到父 Namespacelode 與其他子 Namespacelode 進(jìn)程信息,如圖所示??

?? Network Namespace

每個(gè)容器擁有獨(dú)立的網(wǎng)絡(luò)設(shè)備,IP 地址,IP 路由表,/proc/net 目錄,端口號(hào)等。這也使得一個(gè) host 上多個(gè)容器內(nèi)的網(wǎng)絡(luò)設(shè)備都是互相隔離的。

?? User namespace

User Namespace 用來隔離 User 權(quán)限相關(guān)的 Linux 資源,包括 User IDsGroup IDs。
 這是目前實(shí)現(xiàn)的 Namespace 中最復(fù)雜的一個(gè),因?yàn)?User 和權(quán)限息息相關(guān),而權(quán)限又關(guān)聯(lián)著容器的安全問題。
 在不同的 User Namespace 中,同樣一個(gè)用戶的 User IDGroup ID 可以不一樣。也就是說,一個(gè)用戶可以在父 User Namespace 中是普通用戶,在子 User Namespace 中是超級(jí)用戶。

?? 深入理解Namespace

下面通過一段簡單的代碼來查看 Namespace 是如何實(shí)現(xiàn)的,示例代碼如下:

在以上示例中,代碼段通過 clone() 調(diào)用,傳入各個(gè) Namespace 對(duì)應(yīng)的 clone flag,創(chuàng)建了一個(gè)新的子進(jìn)程,該進(jìn)程擁有自己的 Namespace。根據(jù)以上代碼可知,該進(jìn)程擁有自己的 PID、Mount、UserNet、IPC 以及 UTS Namespace。

所以,Docker 在創(chuàng)建容器進(jìn)程時(shí),指定了這個(gè)進(jìn)程所需要啟動(dòng)的一組 Namespace 參數(shù)。這樣,容器就只能 “看到” 當(dāng)前 Namespace 所限定的資源、文件、設(shè)備、狀態(tài)、配置信息等。至于宿主機(jī)以及其他不相關(guān)的程序,它就完全看不到了。容器,其實(shí)是 Linux 系統(tǒng)中一種特殊的進(jìn)程。

LinuxDocker 創(chuàng)建的隔離空間雖然是看不見摸不著,但是一個(gè)進(jìn)程的 Namespace 信息在宿主機(jī)上是真實(shí)存在的,并且是以文件的方式存在,因?yàn)樵?Linux 操作系統(tǒng)中,一切皆文件。

一個(gè)進(jìn)程可以選擇加入到某個(gè)進(jìn)程已有的 Namespace 當(dāng)中,從而達(dá)到 “進(jìn)入” 這個(gè)進(jìn)程所在容器的目的,這正是 docker exec 的實(shí)現(xiàn)原理。

下面通過示例進(jìn)行詳細(xì)講解,首先運(yùn)行一個(gè) CentOS 容器,示例代碼如下:

以上示例中在運(yùn)行 Docker 容器的命令中添加了參數(shù) -d,表示使容器在后臺(tái)運(yùn)行。

查看當(dāng)前正在運(yùn)行 Docker 容器的進(jìn)程號(hào),示例代碼如下:

查看宿主機(jī)的 /proc 文件,可以看到這個(gè) 8589 進(jìn)程所有 Namespace 對(duì)應(yīng)的文件,示例代碼如下:

可以看到,一個(gè)進(jìn)程的每種 Namespace 都在它對(duì)應(yīng)的 /proc/[進(jìn)程號(hào)]/ns 下有一個(gè)對(duì)應(yīng)的虛擬文件,并且鏈接到一個(gè)真實(shí)的 Namespace 文件。

有了這樣的文件,就可以對(duì) Namespace 做一些實(shí)質(zhì)性的操作。例如,將進(jìn)程加入到一個(gè)已經(jīng)存在的 Namespace 當(dāng)中。

這個(gè)操作依賴一個(gè)名為 setns()Linux 系統(tǒng)調(diào)用,示例代碼如下:

上述代碼共接收了兩個(gè)參數(shù)。

arvg[1],即當(dāng)前進(jìn)程要加入的 Namespace 文件的路徑,如 /proc/8589/ns/net。用戶要在這個(gè) Namespace 里運(yùn)行的進(jìn)程,如 /bin/bash。

代碼的核心操作則是通過 open() 打開指定的 Namespace 文件,并把這個(gè)文件的描述符 fd 交給 setns() 使用。在 setns() 執(zhí)行后,當(dāng)前進(jìn)程就加入了這個(gè)文件對(duì)應(yīng)的 Namespace 當(dāng)中。

?? Namespace的劣勢(shì)

強(qiáng)大的 Namespace 機(jī)制可以實(shí)現(xiàn)容器間的隔離,是容器底層技術(shù)中非常重要的一項(xiàng),但也有不可否認(rèn)的不足。

下面總結(jié)基于 Namespace 的隔離機(jī)制相對(duì)于虛擬化技術(shù)的不足之處,以便在生產(chǎn)環(huán)境中設(shè)法克服。

?? 隔離不徹底

容器只是運(yùn)行在宿主機(jī)上的一種特殊的進(jìn)程,多個(gè)容器之間使用的是同一個(gè)宿主機(jī)的操作系統(tǒng)內(nèi)核。
 盡管可以在容器中通過 Mount Namespace 單獨(dú)掛載其他版本的操作系統(tǒng)文件,如 CentOS 或者 Ubuntu,但這并不能改變它們共享宿主機(jī)內(nèi)核的事實(shí)。
 在 Windows 宿主機(jī)上運(yùn)行 Linux 容器,或者在低版本的 Linux 宿主機(jī)上運(yùn)行高版本的 Linux 容器,都是行不通的。
 相比之下,擁有硬件虛擬化技術(shù)和獨(dú)立 Guest OS 的虛擬機(jī)就要好用得多。最極端的例子是 Microsoft 的云計(jì)算平臺(tái) Azure,它就是運(yùn)行在 Windows 服務(wù)器集群上的,但這并不妨礙用戶在上面創(chuàng)建各種 Linux 虛擬機(jī)。

?? 有些資源和對(duì)象不能被Namespace化

如果容器中的程序調(diào)用 settimeofday() 修改了時(shí)間,整個(gè)宿主機(jī)的時(shí)間都會(huì)被修改。相較于在虛擬機(jī)里面可以任意做修改,在容器里部署應(yīng)用時(shí),需要用戶的操作上更加謹(jǐn)慎。

?? 安全問題

因?yàn)楣蚕硭拗鳈C(jī)內(nèi)核,容器中的應(yīng)用暴露出來的攻擊面很大。
 盡管生產(chǎn)實(shí)踐中可以使用 seccomp 等技術(shù),對(duì)容器內(nèi)部發(fā)起的所有系統(tǒng)調(diào)用進(jìn)行過濾和甄別來進(jìn)行安全加固,但這類方法因?yàn)槎嗔艘粚訉?duì)系統(tǒng)調(diào)用的過濾,會(huì)拖累容器的性能。
 通常情況下,也不清楚到底該開啟哪些系統(tǒng)調(diào)用,禁止哪些系統(tǒng)調(diào)用。

到此這篇關(guān)于Docker中關(guān)于Namespace隔離機(jī)制的奧秘的文章就介紹到這了,更多相關(guān)Docker Namespace隔離機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Docker掛載的三種方法及使用場景分析

    Docker掛載的三種方法及使用場景分析

    在Docker容器中,持久化存儲(chǔ)和數(shù)據(jù)共享是非常重要的功能,Docker提供了三種主要的方法來實(shí)現(xiàn)宿主機(jī)和容器之間的數(shù)據(jù)掛載,本文將詳細(xì)介紹這三種方法的基本語法,并探討它們各自的使用場景,需要的朋友可以參考下
    2024-05-05
  • docker?update?命令及用法詳解

    docker?update?命令及用法詳解

    docker?update?命令動(dòng)態(tài)更新容器配置,您可以使用此命令來防止容器消耗?Docker?主機(jī)的過多資源,本文給大家介紹docker?update?命令及用法,感興趣的朋友一起看看吧
    2023-08-08
  • Docker容器日志查看與清理的方法(親測有效)

    Docker容器日志查看與清理的方法(親測有效)

    這篇文章主要介紹了Docker容器日志查看與清理的方法(親測有效),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • Docker中關(guān)于Namespace隔離機(jī)制全面解析

    Docker中關(guān)于Namespace隔離機(jī)制全面解析

    為了更好地理解容器的運(yùn)行原理,本篇文章將會(huì)以?Linux?宿主機(jī)為例,介紹容器的底層技術(shù),包括容器的命名空間、控制組、聯(lián)合文件系統(tǒng)等,需要的朋友可以參考下
    2022-06-06
  • Docker使用Dockerfile來創(chuàng)建鏡像

    Docker使用Dockerfile來創(chuàng)建鏡像

    本篇文章主要介紹了Docker使用Dockerfile來創(chuàng)建鏡像,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • 使用Docker開發(fā)python Web 應(yīng)用

    使用Docker開發(fā)python Web 應(yīng)用

    本文給大家詳細(xì)講解了如何使用Docker開發(fā)python應(yīng)用,特別是WEB應(yīng)用的步驟,Docker本質(zhì)上提供了非常輕量化的VMs,我們可以使用其創(chuàng)建一個(gè)高標(biāo)準(zhǔn)隔離并能大大減少失配的開發(fā)和產(chǎn)品環(huán)境。
    2016-10-10
  • Docker版FFmpeg安裝部署的詳細(xì)步驟

    Docker版FFmpeg安裝部署的詳細(xì)步驟

    項(xiàng)目組開發(fā)過程用因?yàn)橐褂靡纛l格式轉(zhuǎn)換功能,FFmpeg是常見的音視頻處理工具,本文就來介紹一下Docker版FFmpeg安裝部署的詳細(xì)步驟,感興趣的可以了解一下
    2023-10-10
  • Docker安裝Nacos容器并根據(jù)Nginx實(shí)現(xiàn)負(fù)載均衡

    Docker安裝Nacos容器并根據(jù)Nginx實(shí)現(xiàn)負(fù)載均衡

    本文主要介紹了Docker安裝Nacos容器并根據(jù)Nginx實(shí)現(xiàn)負(fù)載均衡,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • 創(chuàng)建的docker容器時(shí)間顯示錯(cuò)誤/date錯(cuò)誤/時(shí)區(qū)錯(cuò)誤

    創(chuàng)建的docker容器時(shí)間顯示錯(cuò)誤/date錯(cuò)誤/時(shí)區(qū)錯(cuò)誤

    這篇文章主要介紹了創(chuàng)建的docker容器時(shí)間顯示錯(cuò)誤/date錯(cuò)誤/時(shí)區(qū)錯(cuò)誤的處理方法,一起看看吧
    2017-06-06
  • docker<容器數(shù)據(jù)卷-v>對(duì)容器內(nèi)數(shù)據(jù)持久化詳解(備份)

    docker<容器數(shù)據(jù)卷-v>對(duì)容器內(nèi)數(shù)據(jù)持久化詳解(備份)

    容器的數(shù)據(jù)持久化主要是指宿主機(jī)與容器,以及容器與容器之間進(jìn)行數(shù)據(jù)交互,下面這篇文章主要給大家介紹了關(guān)于docker<容器數(shù)據(jù)卷-v>對(duì)容器內(nèi)數(shù)據(jù)持久化的相關(guān)資料,需要的朋友可以參考下
    2023-03-03

最新評(píng)論