容器基础(一)之进程的隔离
什么是进程?
磁盘上的“程序”一旦被执行起来,它就从磁盘上的二进制文件,变成了计算机内存中的数据、寄存器里的值、堆栈中的指令、被打开的文件,以及各种设备的状态信息的一个集合。像这样一个程序运行起来后的计算机执行环境的总和,就是我们今天的主角:进程。所以,对于进程来说,它的静态表现就是程序,平常都安安静静地待在磁盘上;而一旦运行起来,它就变成了计算机里的数据和状态的总和,这就是它的动态表现。
容器技术的核心功能,就是通过约束和修改进程的动态表现,从而为其创造出一个“边界”。
Namespace机制:类似障眼法,使得运行在宿主机上的容器被Docker隔离在一个跟宿主机完全不同的世界中
Namepace使用方式:它其实是Linux创建新进程的一个可选参数。在Linux中创建进程的系统调用是clone(),比如:
int pid = clone(main_function, stack_size, SIGCHLD, NULL);
这个系统调用就会为我们创建一个新的进程,并且返回它的pid,而当我们用clone()系统调用创建一个新进程时,就可以在参数中指定CLONE_NEWPID 参数,比如:
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
这时,我们还可以多次执行上面的clone()调用,这样就会创建多个PID Namespace,而每个Namespace里的应用进程,都会认为自己是当前容器的第1号进程,他们即看不到宿主机里真正的进程空间,也看不到其他PID Namespace里的具体情况。
而除了我们刚刚用到的PID Namespace,Linux操作系统还提供了Mount、UTS、IPC、Network和User这些Namespace,用来对各种不同的进程上下文进行障眼法操作。
这,就是Linux容器最基本的实现原理了。
所以,Docker容器,实际上是在创建容器进程时,指定了这个进程所需要启用的一组Namespace参数。这样,容器就只能看到当前Namespace所限定的资源、文件、设备、状态,或者配置值。而对于宿主机以及其他不相关的程序,它就完全看不到了。
所以说,容器,其实是一种特殊的进程。