4

为什么建议一个容器中只运行一个进程

 3 years ago
source link: https://www.cnblogs.com/JasonCeng/p/14814888.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在云原生与容器化时代浪潮下,大多数新手的普遍认识是“容器=虚拟机”,既然容器等同于虚拟机,那么在容器中想运行多少个进程就运行多少个进程。

作为从新手村走过来的人,笔者想为这个想法纠偏,避免大家和我走一样的弯路。有两个概念我们要理清:第一,容器不等同于虚拟机;第二,容器中不建议运行多个进程。

本文以Docker容器为主要讨论展开。

为什么说容器不等同于虚拟机呢?#

我们来看一个较为学术的定义:A docker container is not a full virtual machine to run a complete stack of application instances and services. Docker container is the application; or more accurately a service that helps to make up the application. 即,Docker容器不是一个运行完整的应用程序实例和服务堆栈的完整虚拟机。Docker容器是一种应用程序,或更准确地说是一种有助于构建应用程序的服务。

虽然容器不等同于虚拟机,但它们也有相似之处,容器与虚拟机拥有着类似的使命:对应用程序及其关联性进行隔离,从而构建起一套能够随处运行的自容纳单元。此外,容器与虚拟机还摆脱了对物理硬件的直接控制,允许我们更为高效地使用计算资源,从而提升能源效率与成本效益。[1]

那么,容器和虚拟机的不同点究竟在哪呢?笔者在这里做了一个通俗形象的类比。首先,对于物理机、虚拟机和容器在基础架构上的不同,可以类比为独栋别墅、小区楼盘和胶囊式公寓的区别。

物理机#

物理机就像独栋别墅,拥有独立的基础设施,水管、电线、地基等都由自己独享,也就是说,网卡、内存、CPU等硬件都由自身操作系统独占。

物理机上的硬件可以看作是基础设施(Infrastructure),没有基础设施一切都无从谈起,硬件之上则是主操作系统(Host Operating System)。除此之外,还有各类基础软件,如各类硬件配套的驱动软件。

这里还要再重点介绍的是Hypervisor,它(也称为虚拟机监视器或VMM)是创建和运行虚拟机(VM)的软件。虚拟机管理程序通过虚拟共享其资源(例如内存和CPU),使一台主机可以支持多个Guest OS

虚拟机#

虚拟机就像小区楼盘,所有房子共享地基,但房子内部有自己独立了电线、水管,虽然最终也是走的统一水电管网出小区。也就是说,多个虚拟机之间,网卡、内存、CPU等硬件虽然最终是共用一套,但在虚拟机内部是由独立的一套虚拟硬件进行运转的。

前面我们介绍了hypervisorhypervisor是一种虚拟化服务器的软件,这是在物理机及宿主机操作系统上运行虚拟机VM的基础,它帮助我们对硬件进行虚拟化。

虚拟机里的操作系统我们称为Guest OS,这是一个完整的操作系统,只要安装应用程序运行所必需的二进制文件和库,在其之上便可以运行应用程序,且能确保各个虚拟机之间、虚拟机与宿主机之间的环境完全独立、资源相互隔离。

由于虚拟机里运行的是一个完整的操作系统,且需要虚拟出Guest OS运行时所需的所有硬件的虚拟副本,这意味着虚拟机会占用大量系统资源,特别是CPU和内存的资源占用率会比较高,且虚拟机的空间占用可以高达数GB。不过在合理范围内,虚拟机可以利用固有的硬件资源虚拟出多台完整VM,其存在仍然有价值,与单独运行的物理机相比仍然是经济的。

虚拟机是伟大的,它通过抽象来增加并行,服务于多操作系统的使用,并提供业界最好的安全性。但对于隔离,它们相当昂贵。[2]

图1. 虚拟机层级图

容器#

容器就像胶囊式公寓,所有隔间不仅共享地基,连电线、水管也都是共享的,且每个隔间的空间有限,彼此之间也相互隔离。当然,他们是共用大房间里的基础设施,如公共空间。

也就是说,容器是共用物理网卡、内存、CPU的。只有当他们之间需要通信时,才会采用容器层面的网桥docker0,而对于其他硬件,可以简单认为每个容器占有了限定范围内的资源(如RAM、CPU等)。

容器只是运行在宿主机上的一种特殊进程,多个容器之间使用的还是同一个宿主机的操作系统内核。可以认为,容器是一个不依赖于操作系统,运行应用程序的环境。

容器通过Linux的NamespaceCgroups技术对应用程序进程进行隔离和资源限制。

Namespace的作用是环境隔离,它让应用程序只看到该Namespace内的世界。而Cgroups 的作用是限制分配给进程的宿主机资源。不过,对于宿主机来说,这些被“隔离”了的进程跟其他进程并没有太大区别。

对于Namespace技术,这里做一个稍微深入一点的解读。通过Mount Namespace,容器可以修改进程对自己的文件系统“挂载点”的认知。在容器进程启动之前重新挂载它的整个根目录"/",这个挂载在容器根目录上、用来为容器进程提供隔离后执行环境的文件系统,就是所谓的“容器镜像”。它还有一个更为专业的名字,叫作:rootfs(根文件系统)。rootfs只是一个操作系统所包含的文件、配置和目录,并不包括操作系统内核。同一台机器上的所有容器,都共享宿主机操作系统的内核。[3]

Linux CGroup全称Linux Control Group,是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)。Cgroup可让您为系统中所运行任务(进程)的用户定义组群分配资源—比如CPU时间、系统内存、网络带宽或者这些资源的组合。您可以监控您配置的Cgroup,拒绝Cgroup访问某些资源,甚至在运行的系统中动态配置您的Cgroup。[4]

回过头来谈谈操作系统内核,由于同一台宿主机上的所有容器都共享宿主机的操作系统内核,那么如果有一个容器里的应用程序需要配置内核参数,跟内核进行直接交互,则这些参数对所有容器来说就像一个“全局变量”,牵一发而动全身。

这也是容器劣势的主要原因,正是因为容器共享宿主机操作系统内核,因此不能像虚拟机一样模拟出完整的硬件机器充当沙盒,从而实现完全隔离。也就是说,容器是进程级的隔离,它可以通过影响宿主机操作系统内核来影响其他容器。

但容器还是有很多优势。首先,容器的空间占用比虚拟机小很多,甚至可以小到10MB,和虚拟机动则数GB相比十分小巧;其次,容器能轻松限制内存和CPU使用率,相比虚拟机采用hypervisor来实现虚拟化更加轻量;同时,正是由于容器体积小、采用的技术(Containerzation Engine)更轻量,使得它启动十分迅速,这十分有利于快速扩展。

值得一提的是,在DevOps理念日益流行的时代,容器对于持续集成和持续部署(CI/CD)实施也是极好的选择,它使得开发人员更容易构建、分发以及快速部署他们的应用程序。

图2. 容器层级图

为什么说容器中不建议运行多个进程呢?#

聊过虚拟机与容器的区别之后,让我们暂时忘记架构和软件工程哲学。在前面的讨论中我们已经知道,容器其实是应用程序抽象出来的可相互隔离的线程。尽管单个容器中确实可以运行多个应用程序,但出于实际原因,您可能需要考虑遵循“每个容器一个应用程序”的经验法则。

1、每个容器中只运行一个应用程序,则水平伸缩将变得十分容易。例如,当你需要一个Tomcate容器,可以从现有的容器再扩展出一个,但如果你的这个容器中不仅有Tomcate,还有MySQL等其他应用程序,事情就会变得复杂起来。

2、每个容器中只运行一个应用程序,可以轻松地将其重新用于其他项目或目的,极大增加复用度。

3、每个容器中只运行一个应用程序,出现故障时开发人员能方便地对该故障容器进行问题排查,而不必对整个系统的各个部分进行排查,这也使得其更具有可移植性和可预测性。

4、每个容器中只运行一个应用程序,升级程序时能够将影响范围控制再更小的粒度,极大增加应用程序生命周期管理的灵活性,避免在升级某个服务时中断相同容器中的其他进程。

5、每个容器中只运行一个应用程序,从安全性和隔离性角度来看,能够提供更安全的服务和应用程序间的隔离,以保持强大的安全状态或遵守PCI之类的规定。[5]

话说回来,容器本身的设计,就是希望容器和服务/应用能够具备相同的生命周期。即:一个容器对应一个进程。这样,才能够最好地应用容器编排来管理好容器和服务。

综上,建议单个容器中只运行一个独立的进程。

参考#

[1] https://blog.csdn.net/qq_24624539/article/details/103445229

[2] http://dockone.io/article/723

[3] https://zhuanlan.zhihu.com/p/157749762

[4] https://coolshell.cn/articles/17049.html

[5] https://devops.stackexchange.com/questions/447/why-it-is-recommended-to-run-only-one-process-in-a-container

(全文完)

更多关于大数据、分布式、存储、区块链、Linux相关文章请关注微信公众号:asympTech渐进线实验室

Github、知乎、博客园、CSDN、简书全网唯一id:JasonCeng

技术人,不白嫖,如果您觉得文章对您有帮助,帮忙点个推荐吧~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK