如何检查 Docker 容器的状态

DockerBeginner
立即练习

介绍

Docker 彻底改变了我们开发、部署和管理应用程序的方式。作为一个强大的容器化平台,Docker 允许你将应用程序及其依赖项打包到隔离的、可移植的环境中。了解如何检查 Docker 容器的状态对于有效的管理和故障排除至关重要。

在这个实践实验(Lab)中,你将学习监控 Docker 容器、了解它们的状态以及管理其生命周期的基本命令。在本教程结束时,你将能够自信地检查和管理 Docker 容器的状态,从而实现高效的应用程序开发和部署。

创建和运行 Docker 容器

在我们能够检查 Docker 容器的状态之前,我们需要先运行一些容器。在这一步中,我们将创建并运行一个简单的 Docker 容器。

了解 Docker 容器

Docker 容器是轻量级的、独立的、可执行的软件包,其中包含了运行应用程序所需的一切:代码、运行时、系统工具、库和设置。它们在不同的开发阶段提供一致的环境。

使用 Docker 容器的好处包括:

  • 一致的运行时环境
  • 与其他应用程序隔离
  • 快速部署和扩展
  • 资源利用效率高

验证 Docker 安装

首先,让我们验证 Docker 是否已正确安装在系统上:

docker --version

你应该看到类似如下的输出:

Docker version 20.10.21, build baeda1f

运行你的第一个容器

让我们使用官方的 Nginx Web 服务器镜像运行一个简单的容器。这将为我们在后续步骤中监控容器提供基础。

在你的终端中运行以下命令:

docker run --name my-nginx -d -p 8080:80 nginx

此命令:

  • 创建一个名为 my-nginx 的容器
  • 以分离模式 (-d) 运行它,这意味着它在后台运行
  • 将主机的端口 8080 映射到容器的端口 80 (-p 8080:80)
  • 使用 Docker Hub 上的官方 nginx 镜像

你应该看到一长串字符,这是容器 ID:

a72369167c214c20247f786a47b6b0b8581b60324bd2d151a7a0db8ddb024959

现在让我们验证容器是否正在运行:

docker ps

你应该看到类似如下的输出:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
a72369167c21   nginx     "/docker-entrypoint.…"   10 seconds ago   Up 9 seconds    0.0.0.0:8080->80/tcp   my-nginx

恭喜你!你已经成功创建并启动了一个 Docker 容器。在下一步中,我们将更详细地探讨如何检查此容器的状态。

基本的容器状态命令

现在我们有了一个正在运行的容器,让我们学习如何使用 Docker 最常用的命令来检查其状态。

使用 docker ps 命令

docker ps 命令是查看正在运行的容器的最基本方法。

docker ps

输出应该类似于:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
a72369167c21   nginx     "/docker-entrypoint.…"   2 minutes ago    Up 2 minutes    0.0.0.0:8080->80/tcp   my-nginx

此命令显示:

  • CONTAINER ID:容器的唯一标识符
  • IMAGE:用于创建容器的 Docker 镜像
  • COMMAND:在容器内执行的命令
  • CREATED:容器的创建时间
  • STATUS:容器的当前状态
  • PORTS:主机和容器之间的端口映射
  • NAMES:容器的指定名称

查看所有容器

基本的 docker ps 命令仅显示正在运行的容器。要查看所有容器,包括已停止的容器,请使用:

docker ps -a

这将显示所有容器,无论它们的状态如何:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
a72369167c21   nginx     "/docker-entrypoint.…"   5 minutes ago    Up 5 minutes    0.0.0.0:8080->80/tcp   my-nginx

目前,我们只有一个容器,但是如果你有已停止的容器,它们也会出现在这里。

使用格式化查看容器状态

你可以自定义 docker ps 的输出,仅显示你需要的信息,使用 --format 选项:

docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

这将显示一个简化的表格,仅包含容器名称、状态和端口:

NAMES       STATUS          PORTS
my-nginx    Up 7 minutes    0.0.0.0:8080->80/tcp

停止容器

让我们停止我们的容器,看看它的状态如何变化:

docker stop my-nginx

输出:

my-nginx

现在再次检查状态:

docker ps

你会注意到该容器不再列在正在运行的容器中。要查看它,请使用:

docker ps -a

输出:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES
a72369167c21   nginx     "/docker-entrypoint.…"   10 minutes ago   Exited (0) 10 seconds ago             my-nginx

容器的状态已更改为 "Exited",表明它不再运行。

启动容器

让我们再次启动容器:

docker start my-nginx

输出:

my-nginx

检查状态以确认它正在运行:

docker ps

输出:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
a72369167c21   nginx     "/docker-entrypoint.…"   12 minutes ago   Up 5 seconds    0.0.0.0:8080->80/tcp   my-nginx

太棒了!你现在了解了如何使用 docker ps 命令检查 Docker 容器的基本状态,以及如何停止和启动容器。

高级容器监控

现在你了解了检查容器状态的基础知识,让我们探索更多高级的监控命令,这些命令提供了关于你的容器的详细信息。

使用 docker inspect 获取详细的容器信息

docker inspect 命令提供了关于容器的详细配置和运行时信息:

docker inspect my-nginx

此命令返回一个 JSON 数组,其中包含关于容器的全面信息。输出结果很长,但它包括:

  • 网络设置
  • 卷挂载
  • 环境变量
  • 资源限制
  • 容器状态
  • 以及更多

让我们使用 --format 选项查看一个特定部分:

docker inspect --format='{{.State.Status}}' my-nginx

输出:

running

你可以提取其他特定的信息:

docker inspect --format='{{.NetworkSettings.IPAddress}}' my-nginx

这将显示容器的内部 IP 地址。

使用 docker stats 获取实时容器指标

docker stats 命令提供容器资源使用情况统计信息的实时流:

docker stats my-nginx

你将看到类似如下的输出:

CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O        PIDS
a72369167c21   my-nginx   0.00%     2.312MiB / 7.764GiB   0.03%     1.05kB / 1.51kB   0B / 4.1kB       2

这显示了:

  • CPU 使用率百分比
  • 内存使用情况
  • 网络 I/O
  • 块 I/O
  • 进程数

Ctrl+C 退出实时统计信息视图。

要同时查看所有容器的统计信息:

docker stats --no-stream

这会显示统计信息的快照,而不会进行持续更新。

查看容器日志

为了排除问题,通常需要检查容器的日志:

docker logs my-nginx

你将看到来自 Nginx 服务器的日志。如果你访问了 Web 服务器,你将看到 HTTP 请求日志。

要实时跟踪日志(类似于 tail -f):

docker logs -f my-nginx

Ctrl+C 退出日志流。

检查容器进程

要查看在容器内运行的进程:

docker top my-nginx

输出将类似于:

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                12345               12321               0                   14:15               ?                   00:00:00            nginx: master process nginx -g daemon off;
systemd+            12401               12345               0                   14:15               ?                   00:00:00            nginx: worker process

这显示了在容器内运行的所有进程、它们的 PID 和资源使用情况。

创建一个新的容器进行比较

让我们创建另一个容器,以便与我们现有的容器进行比较:

docker run --name redis-server -d redis

现在让我们比较两个容器的统计信息:

docker stats --no-stream my-nginx redis-server

你应该看到两个容器的统计信息,这使你能够比较它们对资源的使用情况。

这些高级监控命令为你提供了对容器的健康状况和性能更深入的了解,这对于排除问题和优化资源使用至关重要。

管理容器生命周期

了解如何管理容器的生命周期对于有效使用 Docker 至关重要。在这一步中,我们将探索各种命令来控制容器状态并理解容器生命周期。

容器生命周期状态

一个 Docker 容器可以存在于几种状态:

  • Created:容器已创建但未启动
  • Running:容器当前正在运行
  • Paused:容器执行已暂停
  • Stopped:容器已停止但仍然存在
  • Removed:容器已删除

让我们探索如何在这些状态之间转换。

创建一个容器而不启动它

你可以使用 create 命令创建一个容器而不启动它:

docker create --name test-container nginx

这会创建一个容器,但不会启动它。检查其状态:

docker ps -a

你应该看到新的容器,状态为 "Created":

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS                  NAMES
3f4ab92d1234   nginx     "/docker-entrypoint.…"   5 seconds ago    Created                                            test-container
a72369167c21   nginx     "/docker-entrypoint.…"   40 minutes ago   Up 30 minutes               0.0.0.0:8080->80/tcp   my-nginx
bc123def456a   redis     "docker-entrypoint.s…"   10 minutes ago   Up 10 minutes               6379/tcp               redis-server

启动已创建的容器

要启动已创建的容器:

docker start test-container

验证它是否正在运行:

docker ps

暂停和取消暂停容器

Docker 允许你暂停一个容器,这将冻结其内部的所有进程:

docker pause test-container

检查其状态:

docker ps

输出:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                  PORTS                  NAMES
3f4ab92d1234   nginx     "/docker-entrypoint.…"   2 minutes ago    Up 1 minute (Paused)                           test-container
a72369167c21   nginx     "/docker-entrypoint.…"   42 minutes ago   Up 32 minutes           0.0.0.0:8080->80/tcp   my-nginx
bc123def456a   redis     "docker-entrypoint.s…"   12 minutes ago   Up 12 minutes           6379/tcp               redis-server

要恢复容器:

docker unpause test-container

验证它是否再次运行:

docker ps

停止和重启容器

要正常停止一个容器(发送 SIGTERM,然后在宽限期后发送 SIGKILL):

docker stop test-container

要强制终止一个容器(发送 SIGKILL):

docker start test-container ## 先启动它
docker kill test-container  ## 然后终止它

要重启一个容器(停止并再次启动它):

docker start test-container ## 先启动它
docker restart test-container

移除容器

要移除一个已停止的容器:

docker stop test-container ## 首先确保它已停止
docker rm test-container

验证它是否已消失:

docker ps -a | grep test-container

你应该没有输出,这表明容器已被移除。

移除正在运行的容器

你可以强制移除一个正在运行的容器:

docker run --name temp-container -d nginx
docker rm -f temp-container

容器重启策略

Docker 允许你为容器设置重启策略:

docker run --name always-restart --restart always -d nginx

如果此容器退出或 Docker 重启,它将自动重启。

检查重启策略:

docker inspect --format='{{.HostConfig.RestartPolicy.Name}}' always-restart

输出:

always

让我们停止并移除此容器:

docker rm -f always-restart

理解这些生命周期命令可以让你完全控制你的 Docker 容器,从而可以根据你的应用程序需求有效地管理它们的状态。

容器问题排查

即使有了适当的监控和管理,容器有时也可能会遇到问题。这一步将教你如何使用 Docker 的诊断工具来排除常见的容器问题。

常见的容器问题

容器可能由于各种原因而失败:

  • 应用程序崩溃
  • 资源限制
  • 配置问题
  • 网络问题
  • 权限错误

让我们探索如何识别和诊断这些问题。

创建一个有问题的容器

让我们创建一个容器,该容器将由于无效命令而立即退出:

docker run --name problematic -d nginx sleep 5

此容器将运行 sleep 5 命令,然后在 5 秒后退出。

等待几秒钟,然后检查其状态:

docker ps -a

输出:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS                  NAMES
1a2b3c4d5e6f   nginx     "sleep 5"                10 seconds ago   Exited (0) 5 seconds ago                           problematic
a72369167c21   nginx     "/docker-entrypoint.…"   1 hour ago       Up 50 minutes               0.0.0.0:8080->80/tcp   my-nginx
bc123def456a   redis     "docker-entrypoint.s…"   30 minutes ago   Up 30 minutes               6379/tcp               redis-server

容器已退出,退出码为 0(成功),但它不再运行。

检查容器退出码

退出码可以告诉你容器停止的原因:

  • 0:成功
  • 非零:发生错误

要查看退出码:

docker inspect problematic --format='{{.State.ExitCode}}'

输出:

0

这意味着容器在完成其分配的任务后成功退出。

检查容器日志

日志对于故障排除至关重要:

docker logs problematic

在这种情况下,你可能看不到任何输出,因为我们的 sleep 命令不会产生日志。

让我们创建另一个会生成日志的有问题的容器:

docker run --name crash-test -d nginx sh -c "echo 'Starting container'; sleep 2; echo 'About to crash'; exit 1"

几秒钟后,检查其状态和日志:

docker ps -a | grep crash-test

输出:

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES
f1e2d3c4b5a6   nginx     "sh -c 'echo 'Starti…"   10 seconds ago   Exited (1) 7 seconds ago              crash-test

现在检查日志:

docker logs crash-test

输出:

Starting container
About to crash

这些日志提供了关于容器崩溃前发生了什么的线索。

检查资源使用情况

资源限制可能导致容器崩溃或性能不佳:

docker stats --no-stream my-nginx

这显示了 CPU、内存和 I/O 使用情况,这有助于识别资源瓶颈。

检查容器配置

配置错误是常见的问题来源:

docker inspect my-nginx

查找:

  • 卷挂载
  • 环境变量
  • 网络设置
  • 资源限制

访问正在运行的容器

要调试正在运行的容器中的问题:

docker exec -it my-nginx bash

这为你提供了容器内的 shell,你可以在其中运行命令来诊断问题:

ls -la
ps aux
cat /etc/nginx/nginx.conf
exit ## 离开容器 shell

清理

让我们清理我们有问题的容器:

docker rm problematic crash-test

通过掌握这些故障排除技术,你可以快速识别和解决 Docker 容器的问题,确保你的应用程序平稳可靠地运行。

总结

在这个实践实验中,你获得了监控和管理 Docker 容器的基本技能:

  1. 创建和运行容器 - 你学习了如何使用 docker run 命令创建和运行 Docker 容器。

  2. 基本状态检查 - 你掌握了 docker ps 命令,用于列出正在运行的容器并检查它们的基本状态信息。

  3. 高级监控 - 你探索了使用 docker inspectdocker stats 的高级监控技术,以获取详细的容器信息和实时性能指标。

  4. 容器生命周期管理 - 你学习了如何管理容器的完整生命周期,包括创建、启动、停止、暂停和移除容器。

  5. 故障排除 - 你培养了使用日志、资源监控和直接容器访问来诊断和解决常见容器问题的技能。

这些技能对于在开发、测试和生产环境中有效使用 Docker 容器至关重要。你现在可以自信地监控容器的健康状况,管理它们的生命周期,并在出现问题时进行故障排除。

要继续你的 Docker 之旅,请考虑探索诸如 Docker Compose(用于多容器应用程序)、Docker 网络和使用 Kubernetes 进行容器编排等主题。