.. _run_multiple_processes_in_a_container:
=======================================
在单一容器中运行多个进程
=======================================
之前我 :ref:`ubuntu_tini_image` 等实践中,都采用了 ``tini`` 来作为初始化进程管理器,通过脚本来启动多个进程。不过,这种方式需要自己手写启动脚本,相应带来了维护成本。
按照Docker官方文档 `Run multiple processes in a container `_ ,确实可以通过脚本包装方式来启动多个进程(先启动的进程通过 ``&`` 放到后台),但是脚本包装不如进程管理器,所以需要选择一个轻量级的进程管理器。按照官方文档,推荐的是 ``supervisor`` ,所以我现在改进维护,使用 ``supervisor`` 来替代早先选择的 ``tini`` ,带来如下优势:
- ``supervisor`` 是一个相对规范的启动管理器,通过配置文件来管理多个进程
- 无需编写脚本
- 提供了稳定的进程管理功能,包括自动重启服务,管理继承祖以及使用 ``supervisorctl`` 进行交互管理
如果不需要 ``supervisor`` 提供的全面的多进程管理,而遵循容器设计的单进程架构,多进程的调度完全采用 ``Docker Compose`` 或 :ref:`kubernetes` ,那么就不需要使用 ``supervisor`` ,采用 ``tini`` 来解决进程管理更为轻量级且推荐。
.. _supervisor:
``supervisor``
==================
``supervisor`` 是一个 client/server 系统,用于监控一系列进程,有点类似 ``launchd`` , ``daemontools`` 和 ``runit`` 。不过, ``supervisor`` 并不是仅仅作为 ``process id 1`` 启动的 ``init`` ,而是用于控制和一个项目或用户相关的进程,这意味着 ``supervisor`` 实际上可以在启动时类似其他程序一样启动(来管理一组进程)。
在Docker容器中,需要安装 ``supervisor`` 并复制配置文件到进行中,这样一旦启动了 ``supervisord`` 服务,就能够管理一组程序进程。
.. note::
我发现在 :ref:`alpine_linux` 中安装 ``supervisor`` 需要依赖安装 **25个** 软件包,让我实在有点震撼。为了能够更轻量级,我后续在 :ref:`alpine_docker_image` 将继续使用 ``tini`` 。
仅在 :ref:`ubuntu_linux` 等重量级容器中尝试实践 ``supervisor`` ,仅作为技术积累备用
- 修订 :ref:`debian_tini_image` 的 Dockerfile ,将tini替换成 ``supervisor``
.. literalinclude:: run_multiple_processes_in_a_container/Dockerfile
:caption: 在镜像中加入 ``supervisor``
- 配套提供 ``supervisord.conf`` :
.. literalinclude:: run_multiple_processes_in_a_container/supervisord.conf
:caption: 配置 ``supervisord.conf`` 同时启动nginx和sshd
- 创建镜像:
.. literalinclude:: run_multiple_processes_in_a_container/build_debian-ssh-supervisor_image
:caption: 创建镜像
- 运行容器
.. literalinclude:: run_multiple_processes_in_a_container/run_debian-ssh-supervisor_container
:caption: 运行容器(注意这里将Lima从Host主机映射的目录再绑定到容器内部,这样就能够从容器访问Host主机目录)
参考
=======
- `Run multiple processes in a container `_
- `Supervisor: A Process Control System `_ ``supervisor`` 官方文档