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



Docker最佳实践指南指出:

"...您应该只在单个容器中运行一个进程...">

Nginx和PHP-FPM应该在不同的容器中运行吗?或者这是否意味着微服务架构只在一个容器中运行一个服务或"应用"?

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

根据用例,您可以在单个容器内运行多个进程,尽管我不建议这样做。

从某种意义上说,在不同的容器中运行它们甚至更简单。保持容器较小、无状态且围绕单个作业,可以更轻松地维护所有容器。让我告诉你我的容器工作流程是如何处于类似情况的。

所以:

  1. 我有一个带有nginx的容器,它暴露在外界(:443,:80(。在此级别,管理配置,tls证书,负载平衡器选项等非常简单。
  2. 应用程序的一个(或多个(容器。在这种情况下,带有应用程序的 php-fpm 容器。Docker 映像是无状态的,容器装载并共享静态文件的卷等。此时,您可以随时销毁并重新创建应用程序容器,使负载均衡器保持正常运行。此外,您可以在同一个代理 (nginx( 后面有多个应用程序,管理其中一个不会影响其他应用程序。
  3. 数据库的一个或多个容器...同样适用福利。
  4. 雷迪斯、内存缓存等。

有了这种结构,部署是模块化的,所以每个"服务"都是分离的,并且在逻辑上独立于系统的其余部分。

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

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

我们发现可以使用 Supervisord 运行多个服务。它使架构变得非常简单,只需要您有一个额外的 supervisor.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"]

作为最佳实践,我们仅在服务受益于一起运行而所有其他容器都是独立的微服务的情况下执行此操作。

最新更新