在一个Docker容器中运行多个应用程序

35
这个问题是我对Docker的持续探索的一部分,某种程度上是我之前提出的问题的后续。我现在明白了如何通过链接一堆Docker容器来获得一个完整的应用程序堆栈(实际上是一个迷你VPS)。例如,可以创建一个堆栈,其中包含Apache + PHP5及其扩展程序+ Redis + MemCached + MySQL,所有这些都在Ubuntu上运行,并且可以选择是否使用额外的数据容器来轻松序列化用户数据。
非常不错和优雅。然而,我不禁想知道... 运行那个小VPS需要5个容器(我计算了5个而不是6个,因为Apache + PHP5放在一个容器中)。那么假设我有100个这样的VPS正在运行?那就意味着我有500个容器正在运行!我理解这里的论点-易于组合新的应用程序堆栈,更新堆栈的一个组件等等。但是,以这种方式运作是否存在不必要的开销呢?
假设我这样做了。
  • 将我的所有应用程序放入一个容器中
  • 编写一个小的shell脚本

    !/bin/bash service memcached start service redis-server start .... service apache2 start while: do : done

在我的Dockerfile中,我有

ADD start.sh /usr/local/bin/start.sh
RUN chmod +x /usr/local/bin/start.sh

....
ENTRYPOINT ["/bin/bash"]
CMD ["/usr/local/bin/start.sh"]

然后我启动并运行该容器

docker run -d -p 8080:80 -v /var/droidos/site:/var/www/html -v /var/droidos/logs:/var/log/apache2 droidos/minivps

我现在从事业务工作。当我想要通过编程方式关闭容器时,我可以通过执行单个docker命令来实现。

当人们谷歌这些问题时,可以找到许多类似的问题。除了我上面提到的论点之外,一个常见的为何要采用“一个应用程序每个容器”的方法的原因是:“这就是Docker设计的方式”。我想知道:

  • 运行x100个N个链接容器的缺点是什么 - 在主机上速度,内存使用等方面的权衡?
  • 我这里做错了什么?

1
你可能想看一下这个链接:https://phusion.github.io/baseimage-docker/,因为据开发者说,它可以解决多个应用程序在 Docker 镜像中运行时存在的大部分问题。 - nassim
2个回答

25

容器基本上就是一个进程。在一个足够大的Linux系统上运行500个进程没有技术问题,尽管它们必须共享CPU和内存。

相比于进程,容器的成本是一些额外的内核资源来管理命名空间、文件系统和控制组,以及Docker守护进程中的一些管理结构,特别是处理stdoutstderr的部分。

引入了命名空间来提供隔离,以使一个容器不会干扰其他任何容器。如果你的5个容器组成一个不需要这种隔离的单元,那么可以使用--net=container来共享网络命名空间。目前还没有共享cgroup的功能,据我所知。

你提出的方法有哪些问题:

  • 它不符合“Docker方式”。这对你可能不重要。
  • 你必须维护脚本才能让它正常工作,担心进程重新启动等问题,而不是使用专门为此任务设计的编排器。
  • 你将不得不管理文件系统中的冲突,例如两个进程需要不同版本的库,或者它们都写入同一个输出文件。
  • stdoutstderr将在这五个进程中交织在一起。

谢谢您的回答。我想知道您是否能澄清两件事:1.文档中说:“告诉Docker将此容器的进程放在...并且两个容器上的进程将能够通过环回接口相互连接。”这是否意味着使用--net apache,我将能够访问在另一个容器中运行的memcached,例如在本地主机上?对于每个容器的单应用程序路线,仍然需要编写脚本来启动和链接容器+脚本来关闭和删除所有容器。所以这两种方法都有优缺点吗? - DroidOS
2
是的,当您使用--net=another_container时,它们被放置在相同的网络命名空间中,具有相同的虚拟以太网设备和环回设备。 它们可以彼此通信,但--net=bridge(默认)也是如此。 共享网络的显著之处在于它们共享IP地址和端口。 并且使用稍微少一些的系统资源,这也是您所询问的。 - Bryan
1
  1. 有很多工具可以从外部控制Docker容器 - 参见https://dev59.com/BWMl5IYBdhLWcg3wkn0T#18287169。因此,您不必自己编写太多脚本。请注意,这是一个快速发展的环境。
- Bryan

7
@Bryan的回答很实在,尤其是对于只运行一个进程的容器开销较低的情况。
不过,你至少应该阅读一下https://phusion.github.io/baseimage-docker/中的论点,这里提出了使用具有多个进程的容器的理由。没有它们,Docker对以下内容的支持相对较少:
- 进程监视 - 定时任务 - 系统日志
baseimage-docker运行一个init进程,除了容器中的主要进程外,还启动了一些其他进程。
对于某些目的来说,这是个好主意,但同时也要注意,例如每个容器都有一个cron守护程序和一个syslog守护程序会增加更多的开销。我希望随着Docker生态系统的成熟,我们将看到更好的解决方案,无需使用这种方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接