我正在使用
Docker version 17.09.0-ce
,我看到容器被标记为不健康。是否有一个选项可以让容器重新启动而不是让容器保持不健康状态?
重新启动不健康的容器功能在原始 PR 中(https://github.com/moby/moby/pull/22719),但经过讨论后被删除,并被认为是作为 RestartPolicy 的增强而稍后完成的。
此时,您可以使用此解决方法来自动重新启动不健康的容器:https://hub.docker.com/r/willfarrell/autoheal/
这是一个示例撰写文件:
version: '2'
services:
autoheal:
restart: always
image: willfarrell/autoheal
environment:
- AUTOHEAL_CONTAINER_LABEL=all
volumes:
- /var/run/docker.sock:/var/run/docker.sock
只需执行
docker-compose up -d
即可
您可以通过设置智能 HEALTHCHECK 和适当的重启策略来自动重启不健康的容器。
Docker 重启策略应为
always
或 unless-stopped
之一。
HEALTHCHECK 相反应该实现一个在容器不健康时杀死容器的逻辑。
在下面的示例中,我使用
curl
及其内部重试机制,并将其通过管道(在出现故障/服务不健康的情况下)到 kill
命令。
HEALTHCHECK --interval=5m --timeout=2m --start-period=45s \
CMD curl -f --retry 6 --max-time 5 --retry-delay 10 --retry-max-time 60 "http://localhost:8080/health" || bash -c 'kill -s 15 -1 && (sleep 10; kill -s 9 -1)'
这里要理解的重要一步是,重试逻辑是自包含在
curl
命令中的,这里的Docker重试实际上是强制性的,但没有用处。那么如果 curl
HTTP 请求失败 3 次,则执行 kill
。首先,它向容器中的所有进程发送 SIGTERM,以允许它们正常停止,然后 10 秒后,它发送 SIGKILL 以完全终止容器中的所有进程。必须注意的是,当容器的 PID1 死亡时,容器本身也会死亡并调用重启策略。
kill
文档:https://linux.die.net/man/1/killcurl
文档:https://curl.haxx.se/docs/manpage.htmldocker
重新启动文档:https://docs.docker.com/compose/compose-file/compose-file-v2/#restart陷阱:
kill
在 bash 中的行为与在 sh 中不同。在 bash 中,您可以使用 -1
向所有 PID 大于 1 的进程发出信号以终止。
不健康的 docker 容器可以通过简单的 crontab 规则重新启动:
* * * * * docker ps -f health=unhealthy --format "docker restart {{.ID}}" | sh
你可以尝试在你的 Dockerfile 中添加如下内容:
HEALTHCHECK --interval=5s --timeout=2s CMD curl --fail http://localhost || kill 1
不要忘记
--restart always
选项。
kill 1
将终止容器中 pid 1 的进程并强制容器退出。通常由 CMD 或 ENTRYPOINT 启动的进程的 pid 为 1。
不幸的是,这种方法可能不会将容器的状态更改为不健康,所以要小心。
对于独立容器,Docker 没有本机集成来在运行状况检查失败时重新启动容器,尽管我们可以使用 Docker 事件和脚本来实现相同的目的。健康检查与Swarm更好地集成。通过将健康检查集成到 Swarm 中,当服务中的容器不健康时,Swarm 会自动关闭不健康的容器并启动新容器以维持服务副本计数中指定的容器计数。
根据https://codeblog.dotsandbrackets.com/docker-health-check/
创建容器并添加“restart:always”。
在使用healthcheck时,需要注意以下几点:
对于独立容器,Docker 没有本机集成来在运行状况检查失败时重新启动容器,尽管我们可以使用 Docker 事件和脚本来实现相同的目的。健康检查与Swarm更好地集成。通过将健康检查集成到 Swarm 中,当服务中的容器不健康时,Swarm 会自动关闭不健康的容器并启动新容器以维持服务副本计数中指定的容器计数。
Docker 有多种方法来获取有关容器运行状况的详细信息。您可以配置运行状况检查及其运行频率。此外,可以对容器内运行的应用程序运行运行状况检查,例如 http(这将使用
curl --fail
选项。)您可以查看 health_status
事件以获取详细信息。
有关不健康容器的详细信息,检查命令会派上用场,
docker inspect --format='{{json .State.Health}}' container-name
(有关更多详细信息,请参阅https://blog.newrelic.com/2016/08/24/docker-health-check-instruction/。 )
您应该首先解决导致“不健康”标签的错误情况(每当运行状况检查命令运行并获得退出代码 1 时)。这可能需要也可能不需要 Docker 重新启动容器,具体取决于错误。如果您自动启动/重新启动“容器”,则捕获启动错误或记录它们以及运行状况检查状态可以帮助快速解决错误。如果您对自动启动感兴趣,请检查链接。
What this does:
每 60 秒搜索不健康的容器并重新启动它。
Why not willfarrell/autoheal
:这个更简单。从第一眼看到撰写文件,我就知道它的作用,更重要的是“如何”。 Compose 不依赖于将来可能维护或不维护的另一个映像。