容器基础1:进程

1.基础知识:进程

前情提要(docker 通过镜像技术,解决了应用打包的根本性难题)

2.容器本身没有价值,有价值的是"容器编排"

3.容器

容器其实是一种沙盒技术,就像集装箱一样,把应用装起来的技术
应用于应用之间,有了边界而不至于互相干扰
被装进集装箱的应用,可以方便搬来搬去

4.程序,进程

什么是程序?什么是进程?

输入数据保存在文件中,数据被加载到内存待命,操作系统又读取计算加法的指令,需要cpu完成加法操作。而cpu与内存协作进行加法运算,使用寄存器存放数值,内存堆栈保存执行的命令和变量,计算及还有被打开的文件,以及各种IO设备不断调整自己的状态

5.边界

容器和核心功能,通过约束和修改进程的动态表现,从而创造出一个边界
cgroups技术用来制造约束的主要手段,namespace技术用来修改进程视图的主要方法

6.docker run

拉起一个docker,并运行/bin/sh

$ docker run -it busybox /bin/sh
/ #

执行一下ps命令


/ # ps
PID  USER   TIME COMMAND
  1 root   0:00 /bin/sh
  10 root   0:00 ps

/bin/sh 为1号进程,容器里只有2个进程在运行,前面执行的/bin/sh 以及ps,已经被docker隔离在一个跟宿主机完全不同的世界中去了

7.进程映射

宿主机上运行/bin/sh 程序,操作系统分配PID=100的进程,/bin/sh就是PID=100的进程,而1号员工就是比尔盖茨
现在docker把/bin/sh运行在一个容器中,docker给第100号的进程一个“障眼法”,让他永远看不到前面99个员工,更看不到比尔盖茨,这样,他就会错误的认为自己就是公司的第一号员工

说白了:对应用的进程空间做了手脚,使得进程只能看到重新计算过的进程编号,PID=1,实际上在宿主机的操作系统里,还是原来100号的进程

使用的就是linux里面的namespace机制。

8.namespace 命名空间

namespace命名空间,其实只是linux创建进程的一个可选参数。例如fork函数中的系统调用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); 

这个用的就是PID Namespace
这个新进程将会看到一个权限的进程空间,进程空间中,它的PID是1,因为“障眼法”原因,宿主机真实的进程空间里,这个进程的pid还是真实的数值,比如100.

执行多次,就有多个PID Namespace,每个namespace里的应用进程,都会认为自己是容器里的1号进程。他们看不到宿主机的进程空间,也看不到其他pid namespace里的情况,

9.其他namespace

Mount,UTS,IPC,Network和User这些Namespace
用来对各种不同进程上下文进行障眼法操作

10.Mount Namespace

让被隔离进程只能看到当前namespace里的挂载信息

11.Network Namespace

让被隔离进程看到当前Namespace里的网络设备和配置

12.概括

以上就是linux容器最基本的实现原理

容器只是一种特殊的进程而已

13.总结

image

左边是虚拟机工作原理,hypervisor是虚拟机最主要部分,通过硬件虚拟化功能,模拟出了各种硬件,比如cpu,内存,io设备。并且它在这些虚拟硬件上安装了新的操作系统Guset OS
全虚拟化的概念,用户看到的是Guset OS的文件和目录,以及虚拟出来的硬件设备

右边通过Docker Engine的软件替代了Hypervisor。没有docker容器运行在宿主机里面,docker帮助用户启动的还是原来的应用进程,知不是创建这些进程时,docker给他们加上了各种各样的namespace参数
然后进程就会认为自己是1号进程,只能看到各自的Mount Namespace目录和文件,只能访问Network namespace里面的网络设备,仿佛在一个容器里,与世隔绝

其实本质都是障眼法罢了。

posted @ 2021-06-16 21:03  SpecialSpeculator  阅读(306)  评论(0编辑  收藏  举报