docker 停止后,Monit 不再使用 bash 脚本启动

Monit doesn't start again with a bash script after docker stop

我有一个 docker 容器,它使用 monit 来启动一些服务,例如 mongodb、nginx。我有一个 bash 脚本,docker 使用它来启动 monit。以下是文件的内容:

#!/bin/bash

# Monit will start all apps
/usr/bin/monit -c /etc/monitrc &

# Stay up for container to stay alive
while [ 1 ] ; do
  if !(pgrep monit)
  then /usr/bin/monit -c /etc/monitrc &
  fi
  sleep 5m
done

问题是当我 运行 docker create 命令创建容器时,bash 脚本 运行 正确并且 monit 启动了所有服务,但是如果我停止容器并再次启动它,有时 monit 不会启动,或者即使它启动了,它也不会启动服务。任何人都可以验证我的 bash 脚本是否正常。我使用了以下参考 https://blog.deimos.fr/2016/01/13/docker-why-you-should-use-monit-instead-of-supervisord/

要运行容器中的多个进程,请使用支持运行在Docker中作为PID 1的init系统,如s6 via s6-overlay or supervisord。在两者之间添加自定义脚本只会在服务链中添加额外的 link,并可能将问题引入系统。

信号和Docker

A docker stop sends a SIGTERM signal 到容器进程,然后在默认的 10 秒后发送一个 SIGKILL,这将终止容器和其中的任何东西 运行ning。

docker 下的进程 运行ning 是 PID 1,因此 any signals you want to take action on, otherwise they will be ignored. In the case of a service manager this need to pass the SIGTERM onto all managed services. Note that the example scripts on the blog trap 脚本的 EXIT,进而 运行 是一个脚本,可以完全停止所有 monit 服务。 EXIT 包括 SIGTERM.

在您的示例脚本中,容器中的所有进程 运行ning 将在 docker stop 超时后以 SIGKILL 终止。

服务和 SIGKILL

我没怎么用过 monit,但作为服务经理,我希望它能够优雅地处理被 SIGKILL(或 kill -9)杀死并返回下次(可能不会)。

nginx 通常会在 SIGKILL 中存活下来,因为默认情况下它不会主动在磁盘上存储太多状态。

mongodb 确实需要彻底关闭。 SIGKILL 将保留需要手动清理的数据库锁定文件。