【问题标题】:How to check if all docker-compose up services started successfully?如何检查所有 docker-compose up 服务是否成功启动?
【发布时间】:2021-12-09 04:13:11
【问题描述】:

如何查看docker-compose up的服务是否启动成功?

上下文:我正在将 CI 添加到我的项目中,作为其中的一部分,我想让我的 CI 构建 docker 映像并执行 docker-compose 命令以查看之前是否可以成功启动所有服务进入 CI 的下一阶段。

我在想我应该做点什么:

$ docker build -t myimage 。 $ 码头工人组成 -d # 尝试计算状态为“退出”的图像,如果大于 1,则返回 1 # 如果图像名称包含子字符串“Exit”但运行正常,会发生什么? $ if [[ $(docker-compose -f docker-compose-local.yml ps | grep "Exit" | wc -l) -ne 0 ]];然后返回 1;菲

我怀疑通过ps 子命令查找容器的状态不是很好,并且有更好的解决方案。我看过但没有找到。

docker 容器有哪些可能的状态? docker docks 没有提到可能的状态。

【问题讨论】:

  • 也许 docker swarm 会解决你的问题。就像在那里一样,您可以选择服务的副本并为您维护它。
  • 有趣的想法。我不需要服务来熬夜。我只需要验证它们是否在我的 CI 中启动一次,以便我可以继续下一步。我们将使用 swarm/kubernetes 来管理生产部署。

标签: docker docker-compose


【解决方案1】:

您也许可以尝试使用自定义的HEALTHCHECK 命令运行,该命令可以将状态写入临时文件或其他内容,CI 进程可以检查,然后终止容器。

HEALTHCHECK 还会将每个容器的健康状态存储在docker inspect 输出中的相应health_status 字段中,这对您来说可能比docker ps 更容易。

更一般地说,我在一些应用程序中创建了一种我们称为“冒烟测试”的测试——与完全验收测试非常相似,只是它仍然可以使用某些类型的人工或固定数据.但对 Web / 容器应用程序的实际请求是真实的。

然后你要做的是有一个脚本来启动你的容器集,然后针对这些容器支持的任何应用程序(例如数据库查询、http 请求等)执行一个测试套件。

通常,您可以从您选择的语言中重复使用单元测试框架。在我的例子中,我们使用pytest 编写了一些基于 Python 的冒烟测试……启动所有容器,然后用各种已知正确响应的人工请求来攻击它们。如果 Python 测试过程成功退出,则整个测试通过,它将关闭容器。

我喜欢这种方法,因为这样“检查所有 docker-compose up 服务是否已成功启动”的定义就像任何其他的一样变成了一些自动化测试,并且它被检查到某个地方的源代码中。如果应用程序发生变化,您需要相应地更改测试,否则它们会导致构建失败。

然而,如果您使用简单的HEALTHCHECK 命令,您可能会得到虚假信息。也许容器看起来已经启动并运行了,但是如果某个数据资源或远程连接等在启动时没有成功,除非你的HEALTHCHECK 明确涉及验证它,否则你不会知道。

实际上,知道容器已启动并正在运行并不重要。相反,通常重要的是一些“真实”测试套件,这些测试会命中正在运行的容器,并证明在真实用例场景中运行所需的一切实际上都在正常工作。

【讨论】:

【解决方案2】:

如何查看所有 docker-compose up 服务是否启动成功?

您可以通过比较所有正在运行的服务和所有服务来检查 docker-compose 中的所有服务是否正在运行。请注意,这可能并不意味着您的服务正在运行 - 只是 docker 容器正在运行。下面的 shell 脚本只是比较运行和所有服务的计数:

running="$(docker-compose ps --services --filter "status=running")"
services="$(docker-compose ps --services)"
if [ "$running" != "$services" ]; then
    echo "Following services are not running:" 
    # Bash specific
    comm -13 <(sort <<<"$running") <(sort <<<"$services")
else
    echo "All services are running"
fi

看来negating filter is not possible在docker里,所以应该是这样的。

【讨论】:

    【解决方案3】:

    检查 .State.Status.State.Running 等会告诉您它是否正在运行,但最好确保您的 health容器。

    下面是一个您可以运行的脚本,它将确保所有 docker compose 服务容器都处于良好状态,然后再在其中一个预定义的服务容器中执行命令。如果已达到等待时间/尝试次数阈值,它将以代码 1 退出并打印出 docker 日志。

    修改自npm sql-mdb

    
        #!/bin/bash
        # Wait for all docker compose service healthchecks to be in a "healthy" state before executing a "docker exec -it $2_container_name bash $3"
        # Example:
        # ./this_script.sh "my_docker_compose_project" "mymainservice" "ls -al"
        ##############################################################################################################################
        # $1 Docker compose project name (required)
        # $2 Docker compose service name that will be used to run the execution command (required)
        # $3 The actual execution command that will be ran within the execution service container (required)
        # $4 The max number of attempts to wait for a healthy healthcheck on each service (optional, defaults to 80)
        # $5 The sleep time between attempts to wait for a healthy healthcheck on each service (optional, default to 2)
    
        attempts_max=$([[ -n "$4" ]] && echo "$4" || echo 80)
        sleep_time=$([[ -n "$5" ]] && echo "$5" || echo 2)
        printf "=======> Waiting for docker healthchecks &2
    
        if [[ -z "$1" ]]; then
          echo "Docker compose project name is required as the first passed argument!" >&2
          exit 1
        fi
        if [[ -z "$2" ]]; then
          echo "Docker compose service name for project \"$1\" used as the executing container is required as the second passed argument!" >&2
          exit 1
        fi
        if [[ -z "$3" ]]; then
          echo "The command that will be executed for the docker compose project \"$1\" within the container for service \"$2\" is required as the third passed argument!" >&2
          exit 1
        fi
    
        dc_services="$(docker-compose -p $1 ps --services)"
        if [[ -z "$dc_services" ]]; then
          echo "No docker compose services found for project: \"$1\"!" >&2
          exit 1
        fi
    
        dc_service_exec="$1_${2}_1"
        dc_service_cnt=$(wc -l &2; exit 1; }
            fi
            if [[ health == "healthy" ]]; then
              echo "Docker healthcheck on service $dc_service ($health)"
              dc_service_healthy_cnt=$(( $dc_service_healthy_cnt + 1 ))
              break
            fi
            sleep "$sleep_time"
          done
          if [[ $health != "healthy"  ]]; then
            echo "Failed to wait for docker healthcheck on \"$dc_service\" ($health) after $attempt attempts - services:\n$dc_services\n"
            docker logs --details "$dc_service"
            exit 1
          fi
          echo "SERVICE: $dc_service"
        done
        if (( "$dc_service_healthy_cnt" >= "$dc_service_cnt" )); then
          echo "Docker healthcheck are healthy on services: \"$dc_services\" - Executing \"$3\" in container \"$dc_service_exec\""
          docker exec -it "$dc_service_exec" bash -c "$3"
          [[ $? != 0 ]] && { echo "Failed to execute \"$3\" in docker container \"$dc_service_exec\"" >&2; exit 1; }
        fi
    

    【讨论】:

      猜你喜欢
      • 2020-06-30
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      • 1970-01-01
      • 2021-01-01
      • 1970-01-01
      相关资源
      最近更新 更多