Docker最佳实践:容器的单个进程

Docker 最佳实践指南指出:

“…你应该只在单个容器中运行一个进程…”

Nginx和PHP-FPM应该在不同的容器中运行吗? 或者这是否意味着微服务体系结构只在一个容器中运行一个服务或“应用程序”?

将这些服务放在一个容器中似乎更容易部署和维护。

根据使用情况,您可以在一个容器中运行多个进程,但我不会建议这样做。

从某种意义上说,在不同的容器中运行它们更加简单。 保持容器小而无状态,并且围绕一个工作使得容易维护所有的容器。 让我告诉你我的容器工作流程是如何处于类似的情况。

所以:

  1. 我有一个容器暴露在外面的nginx(:443,:80)。 在这个级别上,管理配置,证书,负载均衡器等是很简单的。
  2. 一个(或多个)容器与应用程序。 在这种情况下,与应用程序的php-fpm容器。 Docker镜像是无状态的,容器会为静态文件安装和共享卷等等。 此时,您可以随时销毁并重新创建应用程序容器,保持负载均衡器正常运行。 另外,您可以在同一个代理(nginx)后面有多个应用程序,管理其中的一个不会影响其他应用程序。
  3. 一个或多个数据库容器…适用同样的好处。
  4. Redis,Memcache等

有了这个结构,部署就是模块化的,所以每一个“服务”都是独立的,在逻辑上与系统其余部分无关。

作为副作用,在这种特殊情况下,您可以对应用程序执行零宕机时间部署 (更新)。 这背后的想法很简单。 当你必须做一个更新时,你使用更新后的应用程序创建一个docker镜像,运行容器,运行所有的测试和维护脚本,如果一切顺利,你将新创建的容器添加到链(负载均衡器)轻轻地杀死旧的。 就是这样,你有更新的应用程序,用户甚至没有注意到它。

这意味着在Linux / Unix意义上的过程。 也就是说,没有什么能阻止你在一个容器中运行多个进程,这不是一个推荐的范例。

我们发现我们可以使用Supervisord运行多个服务。 它使得这个架构非常简单,只需要你有一个额外的supervisor.conf文件。 例如:

supervisord.conf

[supervisord] nodaemon=true [program:apache2] command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND" [program:udpparser] command=bin/bash -c "exec /usr/bin/php -f /home/www-server/services/udp_parser.php" 

从Dockerfile:

 FROM ubuntu:14.04 RUN apt-get update RUN apt-get install -y apache2 supervisor php5 php5-mysql php5-cli RUN mkdir -p /var/lock/apache2 /var/run/apache2 /var/log/supervisor RUN a2enmod rewrite RUN a2enmod ssl COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf ADD 000-default.conf /etc/apache2/sites-enabled/ ADD default-ssl.conf /etc/apache2/sites-enabled/ ADD apache2.conf /etc/apache2/ ADD www-server/ /home/www-server/ EXPOSE 80 443 30089 CMD ["/usr/bin/supervisord"] 

作为一个最佳实践,我们只有在所有其他容器都是独立的微服务的情况下,服务才能从中受益,才能做到这一点。