Docker原理:Namespace
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发奇怪命令。网桥、虚拟网卡、路由规则。
上图中的物理网卡代表物理机或虚拟机的网卡