最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

下面通過一段簡(jiǎn)單的代碼來查看 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)程擁有自己的 PIDMount、User、Net、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創(chuàng)建tomcat容器實(shí)例后無法訪問(HTTP狀態(tài)404)

    Docker創(chuàng)建tomcat容器實(shí)例后無法訪問(HTTP狀態(tài)404)

    本文主要介紹了Docker創(chuàng)建tomcat容器實(shí)例后無法訪問,HTTP狀態(tài)顯示404,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • docker搭建xxl-job的實(shí)現(xiàn)步驟

    docker搭建xxl-job的實(shí)現(xiàn)步驟

    XXL-JOB是一個(gè)輕量級(jí)分布式任務(wù)調(diào)度平臺(tái),通過xxljob,我們可以方便地實(shí)現(xiàn)任務(wù)調(diào)度和任務(wù)執(zhí)行監(jiān)控,本文介紹了docker搭建xxl-job的實(shí)現(xiàn)步驟,感興趣的可以了解一下
    2023-12-12
  • Docker鏡像拉取報(bào)錯(cuò):Error response from daemon: Get https://registry-1.docker.io/v2/的問題解決

    Docker鏡像拉取報(bào)錯(cuò):Error response from daemon: 

    這篇文章主要介紹了Docker鏡像拉取報(bào)錯(cuò):Error response from daemon: Get https://registry-1.docker.io/v2/的問題解決,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • docker容器啟用ipv6地址的方法流程

    docker容器啟用ipv6地址的方法流程

    Docker默認(rèn)不開啟IPv6配置,某些場(chǎng)景我們又需要IPv6網(wǎng)絡(luò)支持,隨著IPv6的普及,以后的使用場(chǎng)景會(huì)越來越多,所以本文給大家介紹了docker容器啟用ipv6地址方法,用ipv6地址訪問容器方法流程、創(chuàng)建一個(gè)nginx容器用ipv6地址訪問測(cè)試流程,需要的朋友可以參考下
    2024-08-08
  • 如何在Docker中設(shè)置容器間通信的權(quán)限和訪問控制策略

    如何在Docker中設(shè)置容器間通信的權(quán)限和訪問控制策略

    文章介紹了使用Docker網(wǎng)絡(luò)進(jìn)行訪問控制的方法,包括自定義Bridge網(wǎng)絡(luò)、基于容器名稱的訪問控制和使用網(wǎng)絡(luò)策略(如Calico)進(jìn)行更精細(xì)的控制
    2024-11-11
  • ubuntu如何完全干凈的卸載docker

    ubuntu如何完全干凈的卸載docker

    這篇文章主要介紹了ubuntu如何完全干凈的卸載docker問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • .NET?6?從0到1使用Docker部署至Linux環(huán)境超詳細(xì)教程

    .NET?6?從0到1使用Docker部署至Linux環(huán)境超詳細(xì)教程

    這篇文章主要介紹了.NET?6?從0到1使用Docker部署至Linux環(huán)境,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • 用Docker安裝Gitlab的方法步驟

    用Docker安裝Gitlab的方法步驟

    這篇文章主要介紹了用Docker安裝Gitlab的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • 詳解基于Harbor搭建Docker私有鏡像倉(cāng)庫(kù)

    詳解基于Harbor搭建Docker私有鏡像倉(cāng)庫(kù)

    這篇文章主要介紹了詳解基于Harbor搭建Docker私有鏡像倉(cāng)庫(kù),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • docker run 運(yùn)行容器自動(dòng)結(jié)束的解決

    docker run 運(yùn)行容器自動(dòng)結(jié)束的解決

    這篇文章主要介紹了docker run 運(yùn)行容器自動(dòng)結(jié)束的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11

最新評(píng)論

龙江县| 环江| 弥渡县| 江油市| 德保县| 深水埗区| 茌平县| 渭源县| 玛纳斯县| 甘洛县| 永兴县| 衡水市| 墨竹工卡县| 阳谷县| 微山县| 扶沟县| 永春县| 黑龙江省| 宁德市| 革吉县| 望江县| 山西省| 岳普湖县| 潞城市| 区。| 沙坪坝区| 扬中市| 罗田县| 新闻| 清原| 休宁县| 泗洪县| 榆社县| 游戏| 灯塔市| 靖安县| 磴口县| 霍城县| 轮台县| 永城市| 金乡县|