如何检查 docker 引擎和 docker 容器是不是正在运行?

Posted

技术标签:

【中文标题】如何检查 docker 引擎和 docker 容器是不是正在运行?【英文标题】:How to check if the docker engine and a docker container are running?如何检查 docker 引擎和 docker 容器是否正在运行? 【发布时间】:2017-09-29 00:15:24 【问题描述】:

在脚本中,我需要检查:

a) docker 引擎是否正在运行? b) 给定一个容器名称,该 docker 容器是否正在运行?

[这个问题的最初措辞含糊不清,有些人将其解释为“检查 docker 引擎”,而另一些人将其解释为“检查 docker 容器”]

【问题讨论】:

任何 docker 命令(docker -v 除外),例如 docker ps docker attach containerName 或试试docker ps sudo systemctl status docker docker ps ----- 这个命令只会显示正在运行的容器 【参考方案1】:

检查 .State.Status、.State.Running 等会告诉您它是否正在运行,但最好确保容器的 health。下面是一个您可以运行的脚本,它将确保两个容器在第二个容器中执行命令之前运行良好。如果已达到等待时间/尝试次数阈值,它会打印出 docker 日志。

示例取自npm sql-mdb。

#!/bin/bash
# Wait for two docker healthchecks to be in a "healthy" state before executing a "docker exec -it $2 bash $3"
##############################################################################################################################
# $1 Docker container name that will wait for a "healthy" healthcheck (required)
# $2 Docker container name that will wait for a "healthy" healthcheck and will be used to run the execution command (required)
# $3 The actual execution command that will be ran (required). When "npm_deploy", all tokens will be included in execution of
#     "npm run jsdoc-deploy" and "npm publish"
attempt=0
health1=checking
health2=checking
while [ $attempt -le 79 ]; do
  attempt=$(( $attempt + 1 ))
  echo "Waiting for docker healthcheck on services $1 ($health1) and $2 ($health2): attempt: $attempt..."
  if [[ health1 != "healthy" ]]; then
    health1=$(docker inspect -f .State.Health.Status $1)
  fi
  if [[ $health2 != "healthy" ]]; then
    health2=$(docker inspect -f .State.Health.Status $2)
  fi
  if [[ $health1 == "healthy" && $health2 == "healthy"  ]]; then
    echo "Docker healthcheck on services $1 ($health1) and $2 ($health2) - executing: $3"
    docker exec -it $2 bash -c "$3"
    [[ $? != 0 ]] &&  echo "Failed to execute \"$3\" in docker container \"$2\"" >&2; exit 1; 
    break
  fi
  sleep 2
done
if [[ $health1 != "healthy" || $health2 != "healthy"  ]]; then
  echo "Failed to wait for docker healthcheck on services $1 ($health1) and $2 ($health2) after $attempt attempts"
  docker logs --details $1
  docker logs --details $2
  exit 1
fi

【讨论】:

【参考方案2】:

我最终使用了

docker info

使用 bash 脚本检查 docker 引擎是否正在运行。

编辑:如果 docker 没有运行,它可以用来使你的脚本失败,如下所示:

#!/usr/bin/env bash
if ! docker info > /dev/null 2>&1; then
  echo "This script uses docker, and it isn't running - please start docker and try again!"
  exit 1
fi

【讨论】:

这个答案被低估了。它是跨平台的,可以快速通过/失败。 docker info > /dev/null 2>&1 如果你不需要输出【参考方案3】:

我有一个更充实的例子,在 Gitea 容器的上下文中使用上面的一些工作,但它可以很容易地根据名称转换为另一个容器。此外,您还可以使用docker ps --filter 功能在较新的系统或未使用 docker-compose 的系统中设置 $GITEA_CONTAINER。

# Set to name or ID of the container to be watched.
GITEA_CONTAINER=$(./bin/docker-compose ps |grep git|cut -f1 -d' ')

# Set timeout to the number of seconds you are willing to wait.
timeout=500; counter=0
# This first echo is important for keeping the output clean and not overwriting the previous line of output.
echo "Waiting for $GITEA_CONTAINER to be ready ($counter/$timeout)"
#This says that until docker inspect reports the container is in a running state, keep looping.
until [[ $(docker inspect --format 'json .State.Running' $GITEA_CONTAINER) == true ]]; do

  # If we've reached the timeout period, report that and exit to prevent running an infinite loop.
  if [[ $timeout -lt $counter ]]; then
    echo "ERROR: Timed out waiting for $GITEA_CONTAINER to come up."
    exit 1
  fi

  # Every 5 seconds update the status
  if (( $counter % 5 == 0 )); then
    echo -e "\e[1A\e[KWaiting for $GITEA_CONTAINER to be ready ($counter/$timeout)"
  fi

  # Wait a second and increment the counter
  sleep 1s
  ((counter++))

done

【讨论】:

【参考方案4】:

容器状态:真/假

# docker inspect --format 'json .State.Running' container-name
true
#

【讨论】:

请在您的答案中添加一些解释,以便其他人可以从中学习 对于其他关注此内容的人,如果您正在寻找容器的健康检查,这很好。如果它正在工作,它将返回 true 这似乎不再起作用了。 “状态”不是 JSOn 中返回的键之一。也没有看到任何关于跑步或健康的信息。但它已经启动,我收到了 JSON 响应。 完美运行【参考方案5】:

有关第一个问题的答案,请参阅此答案 - https://***.com/a/65447848/4691279

对于您的第二个问题 - 您可以使用 docker ps --filter "name=<<<YOUR_CONTAINER_NAME>>>" 之类的命令来检查特定容器是否正在运行。

如果 Docker 和 Container 都在运行,那么您将得到如下输出:

$ docker ps --filter "name=nostalgic_stallman"

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES       
9b6247364a03        busybox             "top"               2 minutes ago       Up 2 minutes                            nostalgic_stallman

如果 Docker 未运行,那么您将收到一条错误消息,指出 docker daemon 未运行。

如果 Docker 正在运行但 Container 没有运行,那么您将不会在此命令的输出中获得容器名称。

【讨论】:

【参考方案6】:

在终端中运行这个命令:

docker ps

如果 docker 没有运行,您将收到以下消息:

来自守护进程的错误响应:拨打 unix docker.raw.sock:连接:连接被拒绝

【讨论】:

【参考方案7】:

有时您不知道完整的容器名称,在这种情况下,这对我有用:

if docker ps | grep -q keyword
then 
    echo "Running!"
else
    echo "Not running!"
    exit 1
fi

我们列出所有正在运行的容器进程(docker ps -a 会显示我们也没有运行的容器进程,但这不是我需要的),我们搜索一个特定的词(grep 部分),如果我们没有找到就会失败至少一个运行中的容器,其名称包含我们的关键字。

【讨论】:

重构以删除大量shell programming antipatterns.【参考方案8】:

对于 OS X 用户 (Mojave 10.14.3)

这是我在 Bash 脚本中用来测试 Docker 是否正在运行的内容

# Check if docker is running
if ! docker info >/dev/null 2>&1; then
    echo "Docker does not seem to be running, run it first and retry"
    exit 1
fi

【讨论】:

我重构了这个以删除if [[ $? -ne 0 ]] antipattern.【参考方案9】:

docker ps -a

你可以看到所有的 docker 容器,不管它是活的还是死的。

【讨论】:

【参考方案10】:

我如何签入 SSH.Run:

systemctl

如果响应:获取 D-Bus 连接失败:不允许操作

它是一个 docker 或 WSL 容器。

【讨论】:

【参考方案11】:

如果你正在寻找一个特定的容器,你可以运行:

if [ "$( docker container inspect -f '.State.Running' $container_name )" == "true" ]; then ...

为了避免容器处于崩溃循环并不断重启以显示它已启动,可以通过检查Status 字段来改进上述内容:

if [ "$( docker container inspect -f '.State.Status' $container_name )" == "running" ]; then ...

如果你想知道 dockerd 是否在本地机器上运行并且你已经安装了 systemd,你可以运行:

systemctl show --property ActiveState docker

您也可以使用docker infodocker version 连接到docker,如果守护程序不可用,它们会出错。

【讨论】:

如何将docker inspect … 放入bash 脚本的if 语句中? if [ $(docker inspect -f '.State.Running' $container_name) = "true" ]; then echo yup; else echo nope; fi 我使用docker inspect -f '.State.Restarting' $container_name,因为我使用重启策略启动我的容器,但这里“true”是你想要避免的。 当容器没有运行时,bash 和 docker 都会抱怨上面的if 语句。这隐藏了错误情况下不需要的溢出:if [ "$(docker inspect -f '.State.Running' $container_name 2>/dev/null)" = "true" ]; then echo yup; else echo nope; fi @MarcoLackovic 听起来你错过了上面的“你已经安装了 systemd”部分。【参考方案12】:

列出所有容器:

docker container ls -a

ls = 列表-a = 全部

检查“状态”列

【讨论】:

这就是我所需要的,因为它适用于所有平台!! 简单易行......工作成功。【参考方案13】:

在 Mac 上,您可能会看到该图像:

如果您右键单击泊坞窗图标,您会看到:

或者:

docker ps

docker run hello-world

【讨论】:

【参考方案14】:

运行:

docker version

如果 docker 正在运行,您将看到:

Client: Docker Engine - Community
 Version:           ...
 [omitted]

Server: Docker Engine - Community
 Engine:
  Version:          ...
 [omitted]

如果 docker 没有运行,你会看到:

Client: Docker Engine - Community
 Version:           ...
 [omitted]

Error response from daemon: Bad response from Docker engine

【讨论】:

对于 Windows 用户,如果引擎未运行,您可能还会看到如下错误:连接时出错:Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1 .35/info: 打开 //./pipe/docker_engine【参考方案15】:

如果基本目标是“如何在 Docker 启动时启动容器?”

我们可以使用Docker的restart policy

向现有容器添加重启策略:

Docker: Add a restart policy to a container that was already created

例子:

docker update --restart=always <container>

【讨论】:

【参考方案16】:

您可以使用以下方式检查 docker 状态:systemctl is-active docker

➜  ~  systemctl is-active docker
active

您可以将其用作:

➜  ~  if [ "$(systemctl is-active docker)" = "active" ]; then echo "is alive :)" ; fi
is alive :)

➜  ~  sudo systemctl stop docker

➜  ~  if [ "$(systemctl is-active docker)" = "active" ]; then echo "is alive :)" ; fi
 * empty response *

【讨论】:

这不回答问题。 "检查容器名称" 是的,问题似乎不明确,要检查容器是否正在运行,您应该使用docker ps --filter name=pattern,然后您可以格式化输出以仅检查添加此标志的状态:--format .Status 这会告诉你 systemctl thinks docker 是否正在运行,但它不会真正检查 docker 是否真的在运行。所以上面的docker info 命令是更好的选择,恕我直言【参考方案17】:

您还可以使用以下命令检查特定 docker 容器是否正在运行:

docker inspect postgres | grep "Running"

此命令将检查例如我的 postgres 容器是否正在运行,并将返回输出为 "Running": true

希望这会有所帮助。

【讨论】:

这正是我想要的。它有效。 (投反对票的人说出原因很好,这样菜鸟就可以学习更好的礼仪。:)) 我没有投反对票,但是“错误:没有这样的对象:postgres” @ged postgres 是容器的名称,而不是命令。【参考方案18】:

您可以使用此命令检查systemctl status docker,它将显示 docker 的状态。如果你想开始你可以使用systemctl start docker而不是systemctl你也可以分别尝试serviceservice docker statusservice docker start

【讨论】:

此答案假定最终用户使用 systemd 作为他们的 init。 systemctl status docker 正确显示 docker 服务正在运行。谢谢。【参考方案19】:

任何 docker 命令(docker -v 除外),例如 docker ps 如果 Docker 正在运行,您将获得一些有效响应,否则您将收到一条消息,其中包括“您的 docker 守护程序是否已启动并正在运行?”

您也可以查看您的任务管理器。

【讨论】:

有趣的是,docker -v 不会检查 docker 是否正在运行,但 docker version 会!哈哈

以上是关于如何检查 docker 引擎和 docker 容器是不是正在运行?的主要内容,如果未能解决你的问题,请参考以下文章

Docker OCI容器标准和引擎架构

云原生之Docker实战使用docker部署 Searxng个人搜索引擎平台

强力的应用容器引擎——docker的安装和镜像容器的基本操作!

Health Check - 每天5分钟玩转 Docker 容器技术(142)

如何检查一个进程是不是在 docker 容器内运行?

Docker容器引擎——安装部署和镜像容器的基本操作