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

我正在与我自己讨论如何考虑和使用Docker容器。

从文献和例子看来,容器似乎应该提供一个服务,或者是一个堆栈的一部分。 例如一个容器可能运行MySQL,Apache或Redis,或其他。 我可以理解为什么这是好的,干净的,是有道理的。

在我们的场景中,我们希望在同一台服务器上托pipe多个完全独立的Web应用程序(电子商务商店,WordPress网站,静态网站,node.js应用程序),并且我们希望使用Docker。 因此对于我来说,每个容器都是完全自我容纳的,整个堆栈本身就是比较有意义的,例如,我的每个可能的几个正在运行的wordpress容器都会有自己的LAMP安装。

在这个场景中应用单容器一服务模型似乎是非常复杂的 – 每个应用程序将依赖于系统中的其他容器,而这些容器将依次被其他事物所依赖。 而如果你需要多个版本的特定服务。

虽然这似乎是要走的路,但它似乎也可能是非常低效的? 我不是LXC如何工作的专家,但即使所有东西都是容器化的,实际上系统上运行的所有apache2工作者和mysqlds,以及所有相关的开销 – 是否会出现性能问题?

有人有想法吗?

我更喜欢每个应用程序一个容器 。 如果你把每一个服务放在一个图像/容器中,你有一些优点:

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

由于LXC和Docker似乎非常高效,我不介意使用多个容器。 这就是Docker的devise目的。 我想你会有一个合理的数字,可以说<100个容器。 所以这不应该是一个问题。

我同意@Thomasleveil,而且我想提到FLOSS每周330集 ,原来的Docker的作者和现在的首席技术官指出了同样的事实, Docker只是一个构build块 。 教育自己,并使用它,只要它符合您的需求。 很多人都使用Docker两种方式 – 按容器处理每个容器和应用程序。 两种方式都有其优点和缺点。

但是我也想警告不要使用Supervisor作为PID1进程来pipe理容器中的多个进程。 如果你打开supervisord.org ,你会看到的第一件事情是:

与其中一些程序不同,[Supervisor]并不意味着作为init的替代品而被运行为“进程ID 1”。 相反,它是用来控制与项目或客户相关的过程,并且意味着在启动时像任何其他程序一样启动。

这意味着与主pipe你将有僵尸进程问题描述由phusion和minit的作者 。 此外,主pipe只pipe理前台进程,因为它产生了它们的孩子,并没有pipe理孩子的孩子。 因此,忘记/etc/init.d/mysql start并找出如何在前台运行一切。

我设法解决这个问题与上述minit和Monit 。 因为Monit也无法担当PID1的angular色(但计划在2015年,见#176 )。 Monit是很好的,因为它允许expression受监视的服务依赖(也就是说,不要启动应用程序,直到数据库没有启动),并且可以按照原样处理守护进程,监视内存,CPU,并且具有Web UI以查看正在发生的事情。 这里除了我在Debain Wheezy上使用这个方法的dockerfile外:

 # 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"] 

这里是webapp.confwebapp.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 

Docker只是一个工具,使用它,因为它最适合您的需求。

没有什么能阻止你在一个Docker容器中运行多个进程。 一种方法是按照这个Docker文章中的描述,用supervisord启动进程。

你也可以看看Phusions的这个用例的方法 。 他们强调在Docker容器中运行多个进程时会出现什么问题,并提供一个Docker镜像( Phusion / baseimage )来帮助正确设置事物。