繁体   English   中英

基于健康检查重启不健康的docker容器

[英]Restarting an unhealthy docker container based on healthcheck

我使用的是Docker version 17.09.0-ce ,我看到容器被标记为不健康。 有没有让容器重新启动而不是让容器保持不健康状态的选项?

重新启动 unhealty 容器功能在原始 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 重启策略应该是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在 bash 中的行为与在 sh 中的行为不同。 在 bash 中,您可以使用-1来通知所有 PID 大于 1 的进程死亡。

对于独立容器,Docker 没有本地集成来在健康检查失败时重新启动容器,尽管我们可以使用 Docker 事件和脚本来实现相同的功能。 健康检查更好地与 Swarm 集成。 通过将健康检查集成到 Swarm 中,当服务中的容器不健康时,Swarm 会自动关闭不健康的容器并启动一个新容器,以保持服务副本计数中指定的容器计数。

您可以尝试在您的 Dockerfile 中添加如下内容:

HEALTHCHECK --interval=5s --timeout=2s CMD curl --fail http://localhost || kill 1

不要忘记--restart always选项。

kill 1将终止容器中 pid 为 1 的进程并强制容器退出。 通常由 CMD 或 ENTRYPOINT 启动的进程的 pid 为 1。

不幸的是,此方法可能不会将容器的状态更改为不健康,因此请小心使用。

Docker 有几种方法可以获取有关容器运行状况的详细信息。 您可以配置运行状况检查及其运行频率。 此外,可以在容器内运行的应用程序上运行健康检查,例如 http(这将使用curl --fail选项。)您可以查看health_status事件以获取详细信息。

有关不健康容器的详细信息,inspect 命令派上用场, docker inspect --format='{{json .State.Health}}' container-name (参见https://blog.newrelic.com/2016/08/ 24/docker-health-check-instruction/了解更多详情。)

您应该首先解决导致“不健康”标签的错误条件(任何时候运行健康检查命令并获得退出代码 1)。 这可能需要也可能不需要 Docker 重新启动容器,具体取决于错误。 如果您正在自动启动/重新启动容器,那么捕获启动错误或记录它们和健康检查状态可以帮助快速解决错误。 如果您对自动启动感兴趣,请查看链接。

根据https://codeblog.dotsandbrackets.com/docker-health-check/

创建容器并添加“重新启动:始终”。

在使用healthcheck时,要注意以下几点:

对于独立容器,Docker 没有本地集成来在健康检查失败时重新启动容器,尽管我们可以使用 Docker 事件和脚本来实现相同的功能。 健康检查更好地与 Swarm 集成。 通过将健康检查集成到 Swarm 中,当服务中的容器不健康时,Swarm 会自动关闭不健康的容器并启动一个新容器,以保持服务副本计数中指定的容器计数。

我可以通过使用--force-recreate选项来解决这个错误

docker-compose up --force-recreate <service>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM