日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Docker原理之Namespaces

發(fā)布時間:2025/3/8 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Docker原理之Namespaces 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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

一、Namespaces

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

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

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

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

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

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

2、net 命名空間(網絡)

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

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

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

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

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

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

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

6、user 命名空間(用戶)

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

二、掛載點

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

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

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

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

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

// 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("/");

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

總結

以上是生活随笔為你收集整理的Docker原理之Namespaces的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。