Docker容器:服务与完整应用程序

Docker容器:服务与完整应用程序,docker,Docker,关于如何思考和使用Docker容器,我正在和自己进行一场持续的辩论 从文献和示例来看,容器似乎真的应该提供服务或堆栈的一部分。例如,一个容器可能运行MySQL、Apache、redis或任何东西。我能理解为什么这是好的,干净的,有意义的 在我们的场景中,我们希望在同一台服务器上托管多个完全独立的web应用程序(电子商务商店、wordpress网站、静态网站、node.js应用程序),并且我们希望使用Docker。因此,对我来说,每个容器都是完全独立的容器更为合理,整个堆栈都在其中,例如,我可能运

关于如何思考和使用Docker容器,我正在和自己进行一场持续的辩论

从文献和示例来看,容器似乎真的应该提供服务或堆栈的一部分。例如,一个容器可能运行MySQL、Apache、redis或任何东西。我能理解为什么这是好的,干净的,有意义的

在我们的场景中,我们希望在同一台服务器上托管多个完全独立的web应用程序(电子商务商店、wordpress网站、静态网站、node.js应用程序),并且我们希望使用Docker。因此,对我来说,每个容器都是完全独立的容器更为合理,整个堆栈都在其中,例如,我可能运行的几个wordpress容器中的每个都有自己的灯安装

将一个容器一个服务模型应用于此场景似乎非常复杂-每个应用程序都将依赖于系统中的其他容器,而这些容器又将被其他事物所依赖。如果您需要特定服务的多个版本,该怎么办

虽然这似乎是一条路要走,但它似乎也可能是非常低效的?我不是LXCs工作原理方面的专家,但即使所有东西都是集装箱化的,系统上确实运行着所有apache2 Worker和MySQLD,以及所有相关的开销——是否会出现性能问题


有人有什么想法吗?

我更喜欢每个应用程序一个容器的方法。如果将每个服务放在一个映像/容器中,则有一些优势:

  • 您可以轻松地编写新的堆栈,使用Apache而不是Nginx
  • 您可以重用组件,例如,我使用每个应用程序部署相同的日志存储映像来收集日志
  • 您可以使用Docker索引(现在称为Docker Hub)中的预定义服务。如果需要设置Memcached服务,只需拉取映像即可
  • 您可以控制每项服务,例如停止或更新服务。如果你想更新你的应用程序,你只需要重建一个图像,只需要上传/下载一个图像

因为LXC和Docker似乎非常高效,所以我不介意使用多个容器。这就是Docker的设计宗旨。我想你会有一个合理的数字,比如说,Docker只是一个工具,使用它,因为它最适合你的需要

没有什么可以阻止您在Docker容器中运行多个进程。 一种方法是使用supervisord启动流程,如中所述


您还可以查看该用例的详细信息。它们突出了在Docker容器中运行多个进程时可能出现的问题,并提供了一个Docker映像(),有助于正确地进行设置。

我同意@thomaslevel,而且我想指出,Docker最初的作者和现在的CTO指出了同样的事实,Docker只是一个构建块。对它进行自我教育,只要它符合你的需要就使用它。许多人使用Docker的方式有两种——每个容器处理一个进程和每个容器应用程序。这两种方法都有其利弊

但我还想警告不要将Supervisor用作PID1进程来管理容器中的多个进程。如果打开,首先会看到的是:

与这些程序中的某些程序不同,it[Supervisor]并不是作为“进程id 1”的init的替代品运行的。相反,它是用来控制与项目或客户相关的流程,并像任何其他程序一样在启动时启动

这意味着与主管一起,您将遇到和描述的僵尸过程问题。此外,Supervisor只管理前台进程,因为它将它们作为子进程生成,而不管理子进程的子进程。所以,忘掉
/etc/init.d/mysql start
,想想如何在前台运行一切

我设法用上面提到的和解决了这个问题<需要code>minit,因为Monit也无法充当PID1的角色(但计划在2015年使用,请参阅)。Monit很好,因为它允许表示受监控的服务依赖关系(比如,在数据库未启动之前不要启动应用程序),并且可以按原样处理守护进程、监控内存、CPU,并具有web UI以查看发生了什么。除了我用这种方法治疗Debain哮喘病外:

# installing the rest of dependencies

RUN apt-get install --no-install-recommends -qy monit

WORKDIR /etc/monit/conf.d
ADD webapp.conf ./
RUN echo "set httpd port 2812 and allow localhost" >> /etc/monit/monitrc

ADD minit /usr/bin/minit
RUN mkdir /etc/minit
RUN echo '#!/bin/bash\n  /etc/init.d/monit start; monit start all' \
  > /etc/minit/startup
RUN echo '#!/bin/bash\n \
  monit stop all; while monit status | grep -q Running; do sleep 1; done; \
  /etc/init.d/monit stop' > /etc/minit/shutdown
RUN chmod u+x /etc/minit/*
ENTRYPOINT ["/usr/bin/minit"]
下面是Monit的
webapp.conf

check process webapp with pidfile /var/run/webapp/webappd.pid
  start program = "/etc/init.d/webapp start"
  stop program  = "/etc/init.d/webapp stop"

  if failed host 127.0.0.1 port 8080 for 2 cycles then restart
  if totalmem > 64 MB for 10 cycles then restart

  depends mysql, nginx
  group server

check process mysql with pidfile /var/run/mysqld/mysqld.pid
  start program = "/etc/init.d/mysql start"
  stop program = "/etc/init.d/mysql stop"

  group database

check process nginx with pidfile /var/run/nginx.pid
  start program = "/etc/init.d/nginx start"
  stop program  = "/etc/init.d/nginx stop"

  group server

我同意控制的水平,但这不也会使事情变得不必要的复杂吗?为了在另一台机器上运行应用程序,必须为应用程序复制10个容器,这听起来不是一件有趣的工作,Docker首先要解决的问题是什么?