Namespace
Linux Namespace 是Linux提供的一種內核級別環境隔離的方法,提供了對UTS、IPC、mount、PID、network、User等的隔離機制。
一句話總結,Namespae解決環境隔離問題。
分類 | 系統調用參數 |
---|---|
Mount namespaces | CLONE_NEWNS |
UTS namespaces | CLONE_NEWUTS |
IPC namespaces | CLONE_NEWIPC |
PID namespaces | CLONE_NEWPID |
Network namespaces | CLONE_NEWNET |
User namespaces | CLONE_NEWUSER |
主要會用到三個系統調用
- clone() – 實現線程的系統調用,用來創建一個新的進程,並可以通過設計上述參數達到隔離。
- unshare() – 使某進程脫離某個namespace
- setns() – 把某進程加入到某個namespace
UTS Namespae
/*啓用CLONE_NEWUTS Namespace隔離 */
int container_pid = clone(container_main, container_stack+STACK_SIZE,
CLONE_NEWUTS | SIGCHLD, NULL);
IPC全稱 Inter-Process Communication,是Unix/Linux下進程間通信的一種方式,IPC有共享內存、信號量、消息隊列等方法。IPC隔離後,只有在同一個Namespace下的進程才能相互通信。
int container_pid = clone(container_main, container_stack+STACK_SIZE,
CLONE_NEWUTS | CLONE_NEWIPC | SIGCHLD, NULL);
PID Namespace
/*啓用PID namespace - CLONE_NEWPID*/
int container_pid = clone(container_main, container_stack+STACK_SIZE,
CLONE_NEWUTS | CLONE_NEWPID | SIGCHLD, NULL);
Mount Namespace
文件系統隔離
/* 啓用Mount Namespace - 增加CLONE_NEWNS參數 */
int container_pid = clone(container_main, container_stack+STACK_SIZE,
CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS | SIGCHLD, NULL);
通過CLONE_NEWNS創建mount namespace後,父進程會把自己的文件結構複製給子進程中。而子進程中新的namespace中的所有mount操作都隻影響自身的文件系統,而不對外界產生任何影響。
User Namespace
設置後,內部看到的UID和GID已經與外部不同了,默認顯示爲65534。那是因爲容器找不到其真正的UID,所以設置上了最大的UID。
把容器中的uid和真實系統的uid給映射在一起,需要修改 /proc/
Network Namespace
用ip命令的部分,docker用raw socket發奇怪命令。網橋、虛擬網卡、路由規則。
上圖中的物理網卡代表物理機或虛擬機的網卡