基于healthcheck重新启动不健康的docker容器

时间:2017-11-03 03:59:33

标签: docker health-monitoring

我正在使用Docker version 17.09.0-ce我看到容器被标记为不健康的健康检查失败。

是否有选项可以重新启动容器,而不是将容器保持为不健康状态。

7 个答案:

答案 0 :(得分:38)

重新启动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即可

答案 1 :(得分:7)

您可以尝试将Dockerfile放入如下内容:

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

不要忘记--restart always选项。

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

不幸的是,此方法可能不会将容器的状态更改为不良状态,因此请当心。

答案 2 :(得分:2)

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

答案 3 :(得分:2)

您可以通过设置智能的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的所有进程发送信号以使其死亡。

答案 4 :(得分: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重新启动容器,具体取决于错误。如果您正在启动/重新启动containers automatically,则捕获启动错误或记录它们以及运行状况检查状态可以帮助快速解决错误。如果您对自动启动感兴趣,请检查链接。

答案 5 :(得分:0)

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

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

答案 6 :(得分:-2)

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

创建容器并添加“restart:always”。

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

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