1. 程式人生 > 實用技巧 >docker的namespace深入理解

docker的namespace深入理解

理論:https://blog.csdn.net/qq_37133717/article/details/86359947

當談論docker時,常常會聊到docker的實現方式。很多開發者都知道,docker容器本質上是宿主機的程序,Docker通過namespace實現了資源隔離,通過cgroups實現了資源限制,通過寫時複製機制(copy-on-write)實現了高效的檔案操作。當進一步深入namespace和cgroups等技術細節時,大部分開發者都會感到茫然無措。尤其是接下來解釋libcontainer的工作原理時,我們會接觸大量容器核心知識。所以在這裡,希望先帶領大家走進linux核心,瞭解namespa和cgroups的技術細節。

namespace資源隔離

linux核心提拱了6種namespace隔離的系統呼叫,如下圖所示,但是真正的容器還需要處理許多其他工作。

namespace系統呼叫引數隔離內容
UTS CLONE_NEWUTS 主機名或域名
IPC CLONE_NEWIPC 訊號量、訊息佇列和共享記憶體
PID CLONE_NEWPID 程序編號
Network CLONE_NEWNET 網路裝置、網路戰、埠等
Mount CLONE_NEWNS 掛載點(檔案系統)
User CLONE_NEWUSER 使用者組和使用者組

實際上,linux核心實現namespace的主要目的,就是為了實現輕量級虛擬化技術服務。在同一個namespace下的程序合一感知彼此的變化,而對外界的程序一無所知。這樣就可以讓容器中的程序產生錯覺,彷彿自己置身一個獨立的系統環境中,以達到隔離的目的。

需要注意的是,本文所討論的namespace實現針對的是linux核心3.8及以後版本。

1.docker run

[root@localhost ~]# docker run -it --name my-busybox2 docker.io/busybox  /bin/sh
/ # 

另啟一個視窗在宿主機上

[root@localhost proc]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
cb465fa71b06        docker.io
/busybox "/bin/sh" 37 seconds ago Up 36 seconds my-busybox2 9b8c4b4cce0d docker.io/busybox "/bin/sh" 28 hours ago Up 6 minutes my-busybox1 [root@localhost proc]# docker top my-busybox2 UID PID PPID C STIME TTY TIME CMD root 2117 2101 0 06:09 pts/4 00:00:00 /bin/sh [root@localhost proc]# ##進入2117容器程序,pid的namespace的id為4026532746

2.docker exec

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
cb465fa71b06        docker.io/busybox   "/bin/sh"           10 minutes ago      Up 10 minutes                           my-busybox2
9b8c4b4cce0d        docker.io/busybox   "/bin/sh"           28 hours ago        Up 16 minutes                           my-busybox1
[root@localhost ~]# docker exec -it my-busybox2 /bin/sh
/ # 

主機上檢視一下,docker-run 的程序2117和docker exec程序2354 在同一個namespace (pid對應的namespace的id 是一樣)

所以在兩個程序中看到的內容是一樣的

在兩個視窗中執行top

在docker exec中執行ping命令

在宿主機上檢視namespace,發現ping和docker run 及docker exec及top都在同一個namespace中

[root@localhost ns]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
cb465fa71b06        docker.io/busybox   "/bin/sh"           27 minutes ago      Up 27 minutes                           my-busybox2
9b8c4b4cce0d        docker.io/busybox   "/bin/sh"           29 hours ago        Up 33 minutes                           my-busybox1
[root@localhost ns]# docker top my-busybox2
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                2117 (docker exec)               2101                0                   06:09               pts/4               00:00:00            /bin/sh
root                2354(docker run)                2340                0                   06:20               pts/5               00:00:00            /bin/sh
root                2519(docker run 中執行的top)       2354                0                   06:33               pts/5               00:00:00            top
root                2536 (docker exec中執行的ping命令)  2117                0                   06:35               pts/4               00:00:00            ping www.baidu.com
[root@localhost ns]# cd ../../2536/ns
[root@localhost ns]# ll
total 0
lrwxrwxrwx 1 root root 0 Aug 16 06:37 cgroup -> cgroup:[4026531835]
lrwxrwxrwx 1 root root 0 Aug 16 06:37 ipc -> ipc:[4026532745]
lrwxrwxrwx 1 root root 0 Aug 16 06:37 mnt -> mnt:[4026532743]
lrwxrwxrwx 1 root root 0 Aug 16 06:37 net -> net:[4026532748]
lrwxrwxrwx 1 root root 0 Aug 16 06:37 pid -> pid:[4026532746]
lrwxrwxrwx 1 root root 0 Aug 16 06:37 pid_for_children -> pid:[4026532746]
lrwxrwxrwx 1 root root 0 Aug 16 06:37 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Aug 16 06:37 uts -> uts:[4026532744]
[root@localhost ns]# pwd
/proc/2536/ns
[root@localhost ns]#