Docker在当下很火,那么,当我们谈Docker,谈容器的时候,我们在谈什么?
或者说,你对Docker,对容器了解吗?容器,到底是怎么一回事儿?
这篇文章着重来讲一下Linux容器,为什么强调Linux容器,而不是Docker,是因为Docker是基于虚拟化技术来实现的,但是这篇文章涉及到Linux容器的核心实现方面,两者不同,所以着重强调一下.
容器其实是一种沙盒技术.顾名思义,沙盒就是能够像一个集装箱一样,把你的应用装起来.这样,应用与应用之间就有了边界而不会相互干扰;同时装在沙盒里面的应用,也可以很方便的被搬来搬去,这也是PaaS想要的最理想的状态.
但是说起来容易,等到真正实现起来的时候,就会有难度.
因为容器是运行在宿主机上面的,当它运行起来的时候,需要加载到内存中,需要CPU完成加法操作等等.也就是说,如果想要实现真正意义上的容器,就要解决这样的问题,但现实中这样的问题还没办法解决.
那么我们所说的容器,又是说什么呢?容器的核心功能又是什么呢?
其实容器的核心功能,就是通过约束和修改进程的动态表现,从而创造出一个"边界".对于Docker等大多数Linux容器来说,Cgroup技术是用来制造约束的主要手段,而Namespace技术则是用来修改进程视图的主要方法.
我们都知道,进程在静态状态下就是程序,只是磁盘上的二进制文件.而当它运行起来时,才成为进程.所以,当我们开始运行程序时,操作系统都会为进程分配一个进程编号,这个编号就是进程的唯一标识.假设我们开始运行了一个程序,它的PID=100.也就是说这个程序是第100个进程,在它前面还有99个进程.而现在,如果我们通过Docker把这个程序运行在一个容器当中,那么Docker就会在第100个进程创建时,给它施一个"障眼法",让它永远看不到其他99个进程,这样这个程序就会误以为自己是第1个进程
这种机制,其实就是对被隔离应用的进程空间做了手脚,使得这些进程只能看到重新计算过的进程编号,比如上面的第100个进程,经过Docker的"障眼法"之后,误以为自己是第1个进程,但是实际上在宿主机的操作系统中,它还是原来的第100个进程.
而这种技术,就是Linux里的Namespace机制.
这种机制,使得容器隔离成为了可能.
接下来我们来谈谈容器限制.
- blkio:为块设备设定I/O限制,一般用于磁盘等设备;
- cpuset:为进程分配单独的CPU核和对应的内存节点;
- memory:为进程设定内存使用的限制;
Linux Cgroups的设计还是比较易用的,它就是一个子系统目录加上一组资源限制文件的组合.对于Docker等Linux容器项目来说,它们只需要在每个子系统下面,为每个容器创建一个控制组(即创建一个新目录),然后在启动容器进程之后,把这个进程的PID填写到对应控制组的tasks文件中就可以了.
至于在这些控制组下面的资源文件里填什么值,就由用户执行docker run时的参数指定.
经过以上分析,我们可以了解到,容器这个听起来玄而又玄的概念,实际上是一种特殊的进程而已.
所以,容器本身并没有价值,有价值的是"容器编排".
当我们在谈容器的时候,其实我们在谈如何更好的去编排容器.这也是为什么当下k8s这么火的原因.
以上内容来自我学习<深入剖析Kubernetes>专栏文章之后的一些见解,有偏颇之处,还望指出.
感谢您的阅读~