1. 概述

Docker 容器是 Docker 镜像的一个运行实例,内部运行着一个或多个进程。随着这些进程状态的变化,容器的行为也会随之改变。因此,在容器的生命周期中,它可能会处于多种不同的状态。

本文将详细介绍 Docker 容器的六种可能状态,并通过实际命令演示每种状态的表现和操作方式。

2. 查看 Docker 容器当前状态

在深入了解容器状态之前,我们先来看看如何查看容器的当前状态。

默认情况下,使用 docker ps -a 命令可以列出所有容器及其状态:

$ docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED              STATUS                          PORTS     NAMES
8f0b524f2d32   centos:7   "/bin/bash"   46 seconds ago       Created                                   strange_beaver
e6d798254d45   centos:7   "/bin/bash"   About a minute ago   Exited (0) About a minute ago             wizardly_cohen

输出中的 STATUS 列(第五列)即为容器当前的状态。

我们也可以使用 docker inspect 命令查看某个容器的详细状态:

$ docker inspect -f '{{.State.Status}}' mycontainer
running

其中 mycontainer 是我们要查询的容器名,也可以使用容器 ID 替代。

3. Docker 容器的六种状态

Docker 容器在任意时刻只能处于以下六种状态之一:

3.1. Created(已创建)

容器处于 created 状态表示它已经被创建,但尚未启动。此时容器不占用任何 CPU 或内存资源。

使用 docker create 命令创建的容器初始状态为 created

$ docker create --name mycontainer httpd
dd109e4be16219f1a6b9fc1cbfb050c1ae035d6a2c301ea0e93eb7d5252b8d2e
$ docker inspect -f '{{.State.Status}}' mycontainer
created

这类容器适用于提前准备、后续再启动的场景,比如为了快速响应某个任务而提前构建好容器环境。

3.2. Running(运行中)

当使用 docker startdocker run 命令启动一个容器后,它的状态会变为 running,表示容器内部的进程正在执行。

示例如下:

$ docker create --name mycontainer httpd
8d60cb560afc1397d6732672b2b4af16a08bf6289a5a0b6b5125c5635e8ee749
$ docker inspect -f '{{.State.Status}}' mycontainer
created
$ docker start mycontainer
mycontainer
$ docker inspect -f '{{.State.Status}}' mycontainer
running

或者直接使用 docker run 启动:

$ docker run -itd --name mycontainer httpd
685efd4c1c4a658fd8a0d6ca66ee3cf88ab75a127b9b439026e91211d09712c7
$ docker inspect -f '{{.State.Status}}' mycontainer
running

在该状态下,容器正常消耗 CPU 和内存资源。

3.3. Restarting(重启中)

当容器正在被 Docker 重启策略触发重启时,其状态为 restarting

Docker 支持四种重启策略:

  • no:默认,退出时不重启
  • on-failure[:max-retries]:失败时重启
  • always:无论退出码如何都重启
  • unless-stopped:除非手动停止,否则一直重启

我们可以通过设置 --restart=always 来启用自动重启:

$ docker run -itd --restart=always --name mycontainer centos:7 sleep 5
f7d0e8becdac1ebf7aae25be2d02409f0f211fcc191aea000041d158f89be6f6

该容器执行完 sleep 5 后会自动重启,几秒后状态变为 restarting

$ docker inspect -f '{{.State.Status}}' mycontainer
restarting

3.4. Exited(已退出)

当容器内部进程执行完毕或异常退出后,容器状态变为 exited。此状态下不消耗任何 CPU 和内存资源。

常见原因包括:

  • 容器内进程执行完毕(如 sleep 10
  • 进程异常崩溃
  • 手动使用 docker stop 停止容器
  • 没有交互式终端的容器执行 bash 会立即退出

示例:

$ docker run -itd --name mycontainer centos:7 sleep 10
596a10ddb635b83ad6bb9daffb12c1e2f230280fe26be18559c53c1dca6c755f

10 秒后查看状态:

$ docker inspect -f '{{.State.Status}}' mycontainer
exited

处于 exited 状态的容器无法使用 docker exec 进入,但可以使用 docker startdocker restart 重新启动。

3.5. Paused(已暂停)

paused 状态表示容器内的所有进程都被暂停,处于挂起状态。

使用 docker pause 命令可将容器暂停:

$ docker run -itd --name mycontainer centos:7 sleep 1000
1a44702cea17eec42195b057588cf72825174db311a35374e250d3d1da9d70c5
$ docker pause mycontainer
mycontainer
$ docker inspect -f '{{.State.Status}}' mycontainer
paused

使用 docker stats 可以看到,此时 CPU 使用率为 0%,但内存仍在占用:

$ docker stats --no-stream
CONTAINER ID   NAME          CPU %     MEM USAGE / LIMIT    MEM %     NET I/O       BLOCK I/O   PIDS
1a44702cea17   mycontainer   0.00%     1.09MiB / 7.281GiB   0.01%     1.37kB / 0B   0B / 0B     1

使用 docker unpause 可恢复容器运行:

$ docker unpause mycontainer
mycontainer

恢复后,容器会从暂停的位置继续执行。例如,容器原本在 sleep 1000,暂停了 100 秒后恢复,还会继续 sleep 900 秒。

适用场景:当你有两个高负载容器,想优先运行其中一个时,可以先暂停另一个,等优先级高的任务完成后再恢复。

3.6. Dead(已死亡)

dead 状态表示容器处于不可恢复的损坏状态,通常是因为资源被外部进程占用导致无法删除。

处于该状态的容器无法重启,只能删除。

⚠️ 踩坑提示:容器进入 dead 状态后,虽然不占用资源,但会一直留在 `docker ps -a` 中,影响查看和管理。建议及时清理。

4. 总结

本文系统介绍了 Docker 容器的六种状态及其含义:

状态 描述
Created 容器已创建,尚未启动
Running 容器正在运行
Restarting 容器正在被重启策略触发重启
Exited 容器已退出
Paused 容器被暂停
Dead 容器损坏,无法删除,需手动清理

掌握这些状态有助于更好地理解容器生命周期,便于排查问题和优化资源使用。在实际使用中,注意观察容器状态变化,可以有效避免一些常见的部署和运行时问题。


原始标题:States of a Docker Container