为什么存在此规则?一个容器中的所有进程都需要所有进程才能工作?
博客文章中提到了此规则:
推荐用于Docker应用程序的设计模式。“
” Docker仅用于创建单进程或单服务容器。“
”最好在每个容器中使用一个进程“
”运行单个服务作为容器“
”每个容器一个进程“
”每个容器一个进程“
#1 楼
让我们暂时忘记高层的建筑和哲学争论。虽然在某些情况下单个容器中的多个功能可能有意义,但出于非常实际的原因,您可能需要考虑遵循“每个容器一个功能”的经验法则:如果将容器隔离为一个功能,则可以更轻松地水平缩放容器。需要另一个apache容器吗?在其他地方旋转一个。但是,如果我的apache容器也装有我的DB,cron和其他碎块,这会使事情变得复杂。
每个容器具有一个功能,可以轻松地将该容器重新用于其他项目或用途。
它还使开发人员能够更轻松,更可预测地从生产中撤下组件以进行本地故障排除,而不是整个应用程序环境进行故障排除。更孤立和可控的方式。杂乱地处理容器中的多个点和鲍勃不仅可以放大图像,而且可以将这些组件捆绑在一起。为什么只需要关闭应用程序X和Y即可升级Z?
以上对于代码部署和回滚也是如此。
将功能拆分到多个容器可以从安全性和隔离性角度提供更大的灵活性。您可能希望(或要求)在网络级别上(物理上或在覆盖网络内)隔离服务,以保持强大的安全状态或遵守PCI之类的规定。
其他一些较小的因素,例如处理stdout / stderr以及将日志发送到容器日志,将容器保持短暂状态等。该语言已过时。官方docker文档已从说“一个过程”转变为建议每个容器“关注一个问题”。
评论
仍然,针对线程的低级争论似乎适合这里... web.stanford.edu/~ouster/cgi-bin/papers/threads.pdf
– jeffmcneill
17年11月19日在17:50
很棒的综合答案!
–罗伯·韦尔斯
19年1月19日在12:58
这个问题在操作系统意义上不是真的意味着“过程”吗?码头工人和相关著作使用了不同的术语,现在已经通过改用“功能”一词来加以澄清?因为否则,虽然我承认这是公认的且评分最高的答案,但我认为它不能回答所提出的问题。
–汤姆
19年4月30日在19:27
顾虑不一定总是与过程1:1对应。如果我有专职工作要对我的服务进行整理,该怎么办?作业并非独立于服务。但是我知道人们在不作弊的情况下为每个unix过程制造一个垃圾容器。并且他们不断高喊一个过程=一个容器的口头禅作为这样做的理由。在我看来有些事。
–盖尔曼
19-10-30在12:43
#2 楼
几天前杀死了一个“两个进程”容器,这让我有些痛苦,这使我使用了两个容器而不是启动两个进程的python脚本:擅长识别崩溃的容器。当主进程看起来不错时,它就无法做到这一点,但是其他一些进程却死于惨死。当然,您可以手动监视您的进程,但是为什么要重新实现呢?
当多个进程将它们的日志喷射到控制台时,docker日志的作用就大大降低了。同样,您可以将进程名称写入日志,但是docker也可以这样做。
对容器的测试和推理变得非常困难。
评论
这应该是公认的答案。
–ClintM
18年1月15日在19:07
同意尽管还有一些其他的答案,但重点是关于docker对PID 1的处理。
–布雷特·瓦格纳(Brett Wagner)
18 Mar 6 '18 at 17:09
这和乔恩接受的答案是正确的答案。我终于真正明白了为什么一个过程或功能或PID是正确的选择。以上理论和实践在这里。我不会全力以赴。谢谢你们俩。
–迈克尔·麦加拉(Michael McGarrah)
19年12月1日1:00
#3 楼
该建议来自于操作系统级虚拟化的目标和设计。容器被设计为通过为其他进程提供自己的用户空间和文件系统来隔离其他进程。
chroot
的逻辑演进是提供一个隔离的文件系统,下一步是将进程与其他进程隔离,以避免内存覆盖,并允许多个进程使用相同的资源(例如TCP端口8080)而没有冲突。 将容器包装为过程所需的库而无需担心版本冲突的主要兴趣。文件系统,您必须为每个进程至少调整LDPATH,以便首先找到正确的库,并且某些库无法以这种方式进行调整,因为它们的路径在编译时已在可执行文件中进行了硬编码,请参见此问题有关更多详细信息。
在网络级别,您必须配置每个进程以避免使用相同的端口。
在同一个容器中运行多个进程需要进行大量调整,如果无法在同一个用户空间中运行多个进程,共享相同的文件系统和网络资源,那么为什么不在主机本身上运行它们呢?
以下是我可以想到的大量调整/陷阱的不完整列表:
处理日志
无论是已装入卷还是在stdout上交错存取,都会带来一些管理。如果使用已安装的卷,则容器应在主机上拥有自己的“位置”,否则两个相同的容器将争夺相同的资源。如果无法轻松识别源,则在stdout上进行交织以利用
docker logs
时,可能成为分析的噩梦。如果容器中的某个进程崩溃了,那么超级用户可能无法清理处于僵尸状态的子进程,并且主机初始化将永远不会继承它们。一旦用尽了可用的pid数(2 ^ 22大约为400万),一堆事情就会失败。两个分离的东西,例如同一容器中的apache服务器和logstash,可以简化日志处理,但是您必须关闭apache来更新logstash。 (实际上,您应该使用Docker的日志记录驱动程序)是否可以优雅地停止等待当前会话结束?如果这是一个轻松的停止,则可能需要一段时间才能推出新版本。如果您执行了杀死操作,则会影响用户的日志发送程序,因此应避免使用恕我直言。使用硬件虚拟化的案例听起来更符合这种需求。
评论
我认为这些论点令人信服。具有多个容器的进程与在主机上运行的进程之间存在巨大差异。尽管解释容器的初衷有些相关,但避免多进程容器并不是一个令人信服的理由。 IOW,您正在用“为什么”回答“为什么不”,这并不是那么有用。在同一个容器中运行多个进程可能非常方便-这就是为什么。为什么不还有待解释。
–阿萨夫·拉维(Assaf Lavie)
17 Mar 9 '17 at 13:51
您尚未详细说明自己要进行的调整。而且,您并没有说过这种调整比设置多个容器要花更多的时间。让我们举一个具体的例子:您经常看到打包好的docker映像,这些映像监督了一些主进程和一些辅助进程的运行。这很容易设置;可以说与分离容器一样容易。例如应用和日志的发货人。因此,我相信,您有责任争论为什么事实并非如此。
–阿萨夫·拉维(Assaf Lavie)
17 Mar 9 '17 at 15:58
顺便说一句,我确实相信有反对多进程容器的有效论据,但您没有提及其中的任何一个。但是无论如何,这都不是一个明确的案例。在某些情况下,允许多个过程是完全可以接受的。哎呀,一些非常受欢迎的图像会产生几个子过程-那个邪恶吗?我的意思是要权衡取舍,而您的回答只能描绘出缺乏细微差别和细节的单方面图片。
–阿萨夫·拉维(Assaf Lavie)
17 Mar 9 '17在16:00
有趣的……听起来我们对此有类似(相同)的看法。在这种情况下,也许您应该不理会它,因为它来自某个想获得评论家徽章的人,并决定滥用您的答案来获得该徽章...
– Pierre.Vriens♦
17年3月13日在15:55
我不会“急于”得出结论……我只是建议您忽略它。但是“您”无法改变自己对谁是答案的匿名拒绝者的看法。无论如何,时间继续前进...
– Pierre.Vriens♦
17年3月13日在20:49
#4 楼
在大多数情况下,这不是全部或全部。 “每个容器一个过程”的指导源于容器应用于不同目的的想法。例如,容器不应同时是Web应用程序和Redis服务器。在某些情况下,在一个容器中运行多个进程是有意义的,只要两个进程都支持一个,模块化功能。
#5 楼
我将这里称为服务的过程称为1个容器〜1个服务,如果我的服务中的任何一个失败,那么我将仅旋转相应的容器,然后在几秒钟内一切又恢复正常。因此,服务之间不会有任何依赖关系。最佳做法是使容器大小小于200 MB,最大小于500 MB(Windows本机容器的例外大于2 GB),否则,它与虚拟机类似,但不完全相同,但性能足够。另外,还要考虑一些参数,例如扩展,如何使服务具有弹性,自动部署等。,这纯粹是您的电话,您需要如何使您的架构模式像微服务在polygot环境中使用最适合您的环境的容器技术,并将为您实现自动化。
评论
但是-拥有一个非常“胖”的容器并包含数十个进程,以便分阶段推出和运行仍无法使用Docker的企业服务器,可以吗?@ J.Doe可能不行。容器与虚拟机不同,即使对于小型应用程序,也存在多个小问题-对于企业推出,将是一个为期两年的项目,首先要使其全部在容器中运行。