基于 healthcheck 重启一个不健康的 docker 容器

新手上路,请多包涵

我正在使用 Docker version 17.09.0-ce ,我看到容器被标记为不健康。是否可以选择重新启动容器而不是保持容器不健康?

原文由 Govind Kailas 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.4k
2 个回答

重新启动不健康容器功能在原始 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

原文由 Navrocky 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以通过设置智能 HEALTHCHECK 和正确的重启策略来自动重启不健康的容器。

Docker 重启策略应该是 alwaysunless-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/kill
  • curl 文档: https ://curl.haxx.se/docs/manpage.html
  • docker 重启文档: https ://docs.docker.com/compose/compose-file/compose-file-v2/#restart

陷阱: kill 在 bash 中的行为与在 sh 中的行为不同。在 bash 中,您可以使用 -1 向所有 PID 大于 1 的进程发出信号以终止。

原文由 Naramsim 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进