6

我最近在我的配置中设置了healthchecks 。docker-compose

它做得很好,我喜欢它。这是一个典型的例子:

services:
  app:
    healthcheck:
      test: curl -sS http://127.0.0.1:4000 || exit 1
      interval: 5s
      timeout: 3s
      retries: 3
      start_period: 30s

我的容器启动速度很慢,因此我设置了 30 seconds start_period

但这并不真正符合我的期望:我不需要每 5 秒检查一次,但我需要知道容器何时第一次为我的编排准备好,并且由于 mystart_period是近似的,如果它第一次检查还没有准备好,我必须等待interval才能重试。

我想要的是:

  • 当容器不健康时,每 5 秒重试一次
  • 健康后,每 1 分钟检查一次

没有办法实现这个开箱即用的docker-compose吗?

我可以编写一个自定义脚本来实现这一点,但如果可能的话,我宁愿有一个本机解决方案。

4

2 回答 2

3

不幸的是,这不可能开箱即用。
所有持续时间设置都是最终的。它们不能根据容器状态进行更改。

但是,根据文档start_period,在检查您的测试之前,探针似乎没有等待完成。它唯一的作用是在此期间发生的任何故障start_period都不会被视为错误。

以下是让我认为的句子:

start_period为需要时间引导的容器提供初始化时间。在此期间探测失败将不计入最大重试次数。但是,如果在启动期间健康检查成功,则认为容器已启动,所有连续失败将计入最大重试次数。

我鼓励您测试是否真的是这种情况,因为我从来没有真正注意过是否在开始期间测试了运行状况检查。
如果是这种情况,start_period如果您不确定持续时间,您可能可以增加您的时间,也可以增加时间interval以找到一个好的折衷方案。

于 2020-02-13T13:37:31.367 回答
2

我编写了一个脚本来执行此操作,但我宁愿找到一个本机解决方案:

#!/bin/sh

HEALTHCHECK_FILE="/root/.healthchecked"

COMMAND=${*?"Usage: healthcheck_retry <COMMAND>"}

if [ -r "$HEALTHCHECK_FILE" ]; then
  LAST_HEALTHCHECK=$(date -r "$HEALTHCHECK_FILE" +%s)
  # FIVE_MINUTES_AGO=$(date -d 'now - 5 minutes' +%s)
  FIVE_MINUTES_AGO=$(echo "$(( $(date +%s)-5*60 ))")
  echo "Healthcheck file present";
  # if (( $LAST_HEALTHCHECK > $FIVE_MINUTES_AGO )); then
  if [ $LAST_HEALTHCHECK -gt $FIVE_MINUTES_AGO ]; then
    echo "Healthcheck too recent";
    exit 0;
  fi
fi

if $COMMAND ; then
  echo "\"$COMMAND\" succeed: updating file";
  touch $HEALTHCHECK_FILE;
  exit 0;
else
  echo "\"$COMMAND\" failed: exiting";
  exit 1;
fi

我使用的是:test: /healthcheck_retry.sh curl -fsS localhost:4000/healthcheck

痛苦是我需要确保脚本在每个容器中都可用,所以我必须为此创建一个额外的卷:

    image: postgres:11.6-alpine
    volumes:
      - ./scripts/utils/healthcheck_retry.sh:/healthcheck_retry.sh
于 2020-02-18T16:58:15.080 回答