【问题标题】:How to get a docker container to the state: dead for debugging?如何让 docker 容器进入状态:dead for debug?
【发布时间】:2017-06-09 10:31:42
【问题描述】:

我需要让一些容器进入死状态,因为我想检查我的脚本是否正常工作。欢迎任何建议。谢谢你。

【问题讨论】:

  • 不清楚容器处于死状态是什么意思。您可以使用“docker stop”停止容器或使用“docker rm”删除容器
  • 我的意思是docker ps -a -q -f status=dead的结果

标签: docker containers dockerfile


【解决方案1】:

您已请求dead 容器。

TL;DR:这是创建死容器的方法

不要在家里这样做:

ID=$(docker run --name dead-experiment -d -t alpine sh)
docker kill dead-experiment
test "$ID" != "" && chattr +i -R /var/lib/docker/containers/$ID
docker rm -f dead-experiment

瞧,docker 无法删除容器根目录,所以它落入status=dead

docker ps -a -f status=dead
CONTAINER ID        IMAGE         COMMAND       CREATED             STATUS        PORTS         NAMES
616c2e79b75a        alpine        "sh"          6 minutes ago       Dead                        dead-experiment

说明

我已经检查了source code of docker and saw this state transition

container.SetDead()
// (...)
if err := system.EnsureRemoveAll(container.Root); err != nil {
    return errors.Wrapf(err, "unable to remove filesystem for %s", container.ID)
}
// (...)
container.SetRemoved()

所以,如果 docker 无法移除容器根目录,它会保持死亡状态,不会继续进入 Removed 状态。所以我强制文件权限不允许root删除文件(chattr -i)。

PS:要恢复目录权限,请执行以下操作:chattr -i -R /var/lib/docker/containers/$ID

【讨论】:

  • 我的朋友正是我所需要的。
  • 我也试图在我的本地设置中重现此问题,但这不起作用,不知何故容器被删除并且未显示在docker ps -a 输出中(文件夹/var/lib/docker/containers/$ID 存在) .
  • @Tony 你还记得最后这是什么吗?
  • 不知道,可能和以前的 Docker 版本有关,我最近无法重现。
【解决方案2】:

对于docker-1.12+,instructionHEALTHCHECK可以帮到你。

HEALTHCHECK 指令告诉 Docker 如何测试容器以检查它是否仍在工作。这可以检测到诸如 Web 服务器陷入无限循环并且无法处理新连接等情况,即使服务器进程仍在运行。

例如,我们有一个 Dockerfile 来定义我自己的 webapp:

FROM nginx:1.13.1

RUN apt-get update \
    && apt-get install -y curl \
    && rm -rf /var/lib/apt/lists/*

HEALTHCHECK --interval=15s --timeout=3s \
    CMD curl -fs http://localhost:80/ || exit 1

每五分钟左右检查一次,以便网络服务器能够在三秒内为网站的主页提供服务。 命令的退出状态表示容器的健康状态。可能的值是:

0:成功 - 容器运行良好并可以使用
1:不健康 - 容器工作不正常
2:保留 - 不要使用此退出代码

然后使用docker build命令构建镜像:

$ docker build -t myapp:v1 .

并使用此图像运行容器:

$ docker run -d --name healthcheck-demo -p 80:80 myapp:v1

检查容器状态:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                            PORTS                NAMES
b812c8d6f43a        myapp:v1            "nginx -g 'daemon ..."   3 seconds ago       Up 2 seconds (health: starting)   0.0.0.0:80->80/tcp   healthcheck-demo

一开始,容器的状态是(health: starting);过了一会儿,它变成了healthy

$ docker ps                        
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                   PORTS                NAMES
d2bb640a6036        myapp:v1            "nginx -g 'daemon ..."   2 minutes ago       Up 5 minutes (healthy)   0.0.0.0:80->80/tcp   healthcheck-demo

需要retries consecutive failures 的健康检查才能将容器视为unhealthy

您可以使用自己的脚本来替换命令curl -fs http://localhost:80/ || exit 1。更重要的是,你的脚本的stdoutstderr可以从docker inspect命令中获取:

$ docker inspect --format '{{json .State.Health}}' healthcheck-demo |python -m json.tool
{
    "FailingStreak": 0,
    "Log": [
        {
            "End": "2017-06-09T19:39:58.379906565+08:00",
            "ExitCode": 0,
            "Output": "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r100   612  100   612    0     0  97297      0 --:--:-- --:--:-- --:--:--   99k\n<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\n    body {\n        width: 35em;\n        margin: 0 auto;\n        font-family: Tahoma, Verdana, Arial, sans-serif;\n    }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.</p>\n\n<p>For online documentation and support please refer to\n<a href=\"http://nginx.org/\">nginx.org</a>.<br/>\nCommercial support is available at\n<a href=\"http://nginx.com/\">nginx.com</a>.</p>\n\n<p><em>Thank you for using nginx.</em></p>\n</body>\n</html>\n",
            "Start": "2017-06-09T19:39:58.229550952+08:00"
        }
    ],
    "Status": "healthy"
}

希望这会有所帮助!

【讨论】:

  • 这有点帮助,但其想法是强制容器死亡,即如何使其死亡、不停止和不退出。
  • 在我的解决方案中,您可以使用docker ps -a --filter=health=unhealthy 过滤处于unhealthy 状态的容器。如果您只是想检查您的脚本是否正常工作,我认为不应该强制容器死亡。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
相关资源
最近更新 更多