在windows操作系统中,如果我们需要查看当前的所有进程,我们需要按下如下的命令来查看当前在系统中运行的进程信息

命令:tasklist

容器和镜像_云原生

这些进程之间可以相互进行通信,对于OS来说,能够通过PCB块中的pid来管理系统中的所有的进程。

在同一台计算机的操作系统中,进程所处理的文件是在当前系统上的同一个文件系统,他们可以对同一个文件进行读写(不能同时写),因此,对于其他资源来说,这些进程共享了操作系统的所有资源。

由于存在上面的特性,会为我们的进程带来一系列的问题。

由于在操作系统中,进程会根据运行者的组、权限或者是当前进程所处ring级的不同来决定进程的权限,而具有高级权限的进程能够管理低级权限的进程,又因为高级权限的进程通过os提供的接口,能够看到低级权限的进程并且能够相互的进行通信,那么高级权限的进程就可能会攻击低级权限的进程。

因为进程之前都是用的同一个文件系统,那么这些进程可能会对已有的数据进行修改,高级进程可能会破坏其他进程的正常运行,进程之前的依赖关系可能会被破坏,那么就会对系统的运维产生很大的难度。

而且,由于资源的不隔离性,多个进程之前很有可能出现资源的抢占问题,这些问题都需要我们为一个进程来提供一个独立的运行环境。

在linux系统中,能够使用chrooot来更改子目录变为根目录,实现视图级别的资源隔离,这是针对文件系统的,而进程在chroot的帮组下,可以成为一个具有独立的文件系统,那么这个针对这个文件系统的操作是不会影响到其他进程相对于自己的chroot的资源的增删改查的。

使用Namespace技术能够实现进程在资源的视图上的隔离,在chroot和namespace技术的帮助下,进程相对于其他进程就能够拥有一个独立的进程视图和一个独立的文件系统的视图。

关于chroot

Chroot作用于正在运行的进程和它的子进程,改变它外显的根目录。如果一个进程使用chroot指定了他的根目录,那么对于进程而言,该目录就是根目录,该进程所有的能够对资源进程操作的目录将全部是基于该根目录的,对于根目录之外的其他目录,该进程没有访问的权限,因此能够实多个进程的文件资源的隔离。

但是所谓的使用chroot命令改变根目录,也只是简单的改变进程中taskstruct中的fs结构体中的root字段,来实现不同的根目录的查询功能,但是仅仅依靠chroot是无法完成安全的环境隔离的。

关于Namespace实现进程资源隔离:

Namespace是Linux内核中用于隔离内核资源的方式,它是对全局系统资源的封装和隔离。处在不同的Namespace的进程拥有独立的全局系统资源。改变一个namespace中的系统资源只会影响当前namespace里的进程。对于其他namespace中的进程的资源是没有任何影响的。

因此,每个namespace下的资源对于其他namespace下的资源是透明的、不可见的。

因此从操作系统的角度来看,系统中可能会出现两个pid相同的进程,但是由于他们处于不同的namespace中,所以这些进程之前不会出现冲突的问题。

对于用户来说,用户受限于访问控制权限,只能看到自己所属的namespace下的进程,那么就能有效的实现进程资源的隔离。

但是仅仅依靠chroot和namespace技术是无法控制进程对于资源的使用量的,如果无法控制资源的使用量,我们就没有办法来实现对于一个进程的性能扩充和弹性的扩展,那么我们需要引入一个cgourps机制。

关于cgroups机制

cgroups是Linux下控制进程的资源限制机制,全称是control groups,可以对cpu、内存等资源做精细化控制,再使用chroot和namespace技术建立一个文件系统资源和进程资源全部和其他进程隔离的情况下的进程时,我们通过cgroups为其分配一个特定的硬件资源,那么在视图上,这就是一台轻量化的虚拟机了。

而我们把一组需要维护系统本身运行和程序运行的环境变量放在一个进程组中,那么我们就得到了一个容器,这个容器实现了视图隔离(namespace技术)、资源限制(cgroups)、独立的文件系统(chroot)的进程集合。

而容器的镜像就是能够部署上列所说的文件系统、进程系统资源的集合,这个集合能够满足容器运行时所需要的所有资源。

而目前docker hub上有很多公开的镜像、开发者也可以通过docker命令来上传、打包自己的镜像,或者是使用dockerfile来构建自己的镜像,dockerfile能够帮助我们很好的描述我们构建镜像的每一个步骤,这每一个步骤都是对我们隔离视图中的chroot后的文件系统资源进行操作,那么这就带来了本地文件系统的变化,这种变化就是所谓的changeset。我们把所有的changeset联合起来,那么就产生了我们的镜像。

Changeset的分层和服用特点能够提高我们的镜像分发效率,并且,由于程序 = 数据 + 指令,而指令由我们的镜像所提供,那么我们只需要提供数据就能实现容器的复制,避免在复制过程中由于镜像环境的问题导致无法运行的情况。而数据可以通过数据卷和数据卷映像PVC机制来联合实现,那么就让我们的开发变得更加的便捷。

而当我们构建好了dockerfile文件以后,我们就可以使用docker build命令来构建我们的引用系统,构建的系统将会建立在我们的chroot后的目录后,那么当我们部署应用的时候,我们只需要从docker registry中拉取镜像或者通过docker push把我们的镜像上传到云上,就可以很方便的实现云上的环境部署。

容器和虚拟机的区别

但是容器和虚拟机还是有一定的区别的,虚拟机时使用Hypervisor虚拟化技术来模拟CPU、内存等硬件资源,通过在宿主机上建立一个Guest OS来实现一个虚拟机的安装。因此每一个虚拟机都有一个独立的内核,这样就能够有一个较好的隔离效果,因为每个应用都是相互独立的,但是这对硬件资源的开销将会比较大,而且需要占用大量的磁盘空间。

而容器是进程级别的,不需要Guest OS的加持,只需要一个独立的文件系统就能够实现,但是文件的隔离也是进程级别的,所以不需要额外的虚拟化技术来实现虚拟机的实现,隔离效果比VMware的效果差很多。但是因为他的轻量级,启动时间快、资源利用率小,所以被很多企业所使用。