一、上期回顾

每天半小时,轻松学Docker第六篇:Docker卷与绑定挂载


二、引言

在 Docker 的日常使用中,我们经常会遇到这样的实际场景:

运维监控:某个容器的 CPU 使用率异常飙升,如何快速定位问题容器?
资源规划:服务器内存即将耗尽,如何查看哪些容器占用了最多内存?
故障排查:容器莫名停止,如何获取详细的运行状态和配置信息?
成本优化:如何监控容器的资源消耗,为集群扩容提供数据支撑?

这些看似简单的问题,恰恰是 Docker 运维中的核心挑战。许多开发者虽然熟练使用 docker rundocker build 等基础命令,却在面对资源监控和信息查询时感到无从下手。

事实上,Docker 提供了一套强大的对象查询与资源监控工具链。从实时资源统计到详尽的元数据查询,从简单的状态检查到复杂的格式过滤,这些功能构成了 Docker 运维的关键能力。掌握它们,意味着你能够:

  • 透视容器内部:不再局限于表面现象,深入理解容器的运行机制

  • 掌控资源命脉:实时监控资源使用,防患于未然

  • 精准故障定位:快速发现问题根源,提升排障效率

  • 自动化运维:通过格式化输出集成到监控系统中

本章将带你系统学习 Docker 的对象查询与资源配额管理,从基础的 docker stats 实时监控,到强大的 docker inspect 元数据探查,再到精准的格式过滤技巧。无论你是刚刚接触 Docker 的新手,还是希望提升运维效率的资深用户,这些知识都将为你的容器化之旅增添重要的能力维度。


三、资源使用情况查看

资源使用情况查看

【实践01-创建容器并查看容器资源使用情况】

使用 mysql:8.0.40-debian 镜像创建并运行 mysql-studk061 容器,使用 docker stats 命令查看容器资源使用情况。

1) 使用 mysql:8.0.40-debian 镜像创建并运行 mysql-studk061 容器

rz@demo:~$ docker run -d --rm --name mysql-studk061 -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.40-debian
629e1d86e392788749674ed8793f1b12e706c2cd50c362944d9c21639e8923ac

rz@demo:~$ docker ps
CONTAINER ID   IMAGE                 STATUS         PORTS       NAMES
629e1d86e392   mysql:8.0.40-debian   Up 3 seconds   ...3308...  mysql-studk061

2) 使用 docker stats 命令查看容器资源使用情况

rz@demo:~$ docker stats mysql-studk061

命令将实时动态刷新相应容器的资源使用状态。需要按 CTRL+C 退出。

CONTAINER ID   NAME             CPU %     MEM USAGE / LIMIT     MEM %     NET I/O       BLOCK I/O       PIDS
629e1d86e392   mysql-studk061   0.46%     388.1MiB / 1.887GiB   20.08%    1.09kB / 0B   115kB / 277MB   37

docker stats 命令输出字段说明:

字段 说明
CONTAINER ID 容器ID
NAME 容器名称
CPU % CPU 使用百分比
MEM USAGE / LIMIT 内存使用量 / 内存配额上限
MEM % 内存使用百分比
NET I/O 网络输入/输出流量
BLOCK I/O 块设备输入/输出
PIDS 容器内的进程数

3) 停止 mysql-studk061 容器

rz@demo:~$ docker stop mysql-studk061
mysql-studk061

rz@demo:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

注意:由于创建容器时使用了 --rm 参数,容器停止后会自动被删除。


四、对象查询

【实践02-创建容器并对容器进行对象查询】

使用 mysql:8.0.40-debian 镜像创建并运行 mysql-studk062 容器,要求将主系统的 ~/data_bind06 目录绑定到容器的 /var/lib/mysql 目录。再利用容器创建 mysql-inspect:v0.01 镜像,最后使用 docker inspect 命令查询容器与镜像的详细信息。

1) 创建并运行 mysql-studk062 容器

rz@demo:~$ docker run -d --rm --name mysql-studk062 -v $HOME/data_bind06:/var/lib/mysql -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.40-debian
f2154362585d4e44c90bd4cbacaa3fd8749e8c3ef86593ef0c642ee1a797b293

rz@demo:~$ docker ps -a
CONTAINER ID   IMAGE                 STATUS         PORTS       NAMES
f2154362585d   mysql:8.0.40-debian   Up 4 seconds   ...3310...  mysql-studk062

rz@demo:~$ ls $HOME/data_bind06/
auto.cnf          client-key.pem      '#innodb_temp'        server-key.pem
binlog.000001    '#ib_16384_0.dblwr'   mysql                sys
binlog.000002    '#ib_16384_1.dblwr'   mysql.ibd            undo_001
binlog.index     ib_buffer_pool       performance_schema    undo_002
ca-key.pem       ibdata1              private_key.pem
ca.pem           ibtmp1               public_key.pem
client-cert.pem  '#innodb_redo'       server-cert.pem

2) 利用容器创建 mysql-inspect:v0.01 镜像

rz@demo:~$ docker commit -a "Zhu Chuan zhuchuan1978@foxmail.com" -m "mysql & inspect" mysql-studk062 mysql-inspect:v0.01
sha256:5b0010d39c349bcf9b70f22586117561b4467b6fa5c3b241434b3175b4801d25

rz@demo:~$ docker images
REPOSITORY      TAG             IMAGE ID       CREATED         SIZE
mysql-inspect   v0.01           5b0010d39c34   6 seconds ago   610MB
mysql           8.0.40-debian   2d415917245b   3 months ago    610MB
hello-world     latest          d2c94e258dcb   21 months ago   13.3kB

3) 使用 docker inspect 查询 mysql-studk062 容器

rz@demo:~$ docker inspect mysql-studk062

输出内容包含完整的容器信息,其中关键部分显示:

{
    "Id": "f2154362585d4e44c90bd4cbacaa3fd8749e8c3ef86593ef0c642ee1a797b293",
    "HostConfig": {
        "Binds": [
            "/home/rz/data_bind06:/var/lib/mysql"
        ],
        "PortBindings": {
            "3306/tcp": [
                {
                    "HostIp": "",
                    "HostPort": "3310"
                }
            ]
        }
    },
    "Mounts": [
        {
            "Type": "bind",
            "Source": "/home/rz/data_bind06",
            "Destination": "/var/lib/mysql",
            "Mode": "",
            "RW": true
        }
    ]
}

说明:如果不使用 -f 选项,docker inspect 会输出全部相关信息,内容较多。在实际运维中,通常结合 -f 参数进行精确查询。

4) 使用 -f 参数精确查询容器信息

# 查询容器ID
rz@demo:~$ docker inspect -f '{{.Id}}' mysql-studk062
f2154362585d4e44c90bd4cbacaa3fd8749e8c3ef86593ef0c642ee1a797b293

# 查询绑定挂载信息
rz@demo:~$ docker inspect -f '{{.HostConfig.Binds}}' mysql-studk062
[/home/rz/data_bind06:/var/lib/mysql]

# 查询第一个绑定挂载的源路径
rz@demo:~$ docker inspect -f '{{index .HostConfig.Binds 0}}' mysql-studk062
/home/rz/data_bind06:/var/lib/mysql

# 查询挂载的源路径
rz@demo:~$ docker inspect -f '{{range .Mounts}}{{.Source}}{{end}}' mysql-studk062
/home/rz/data_bind06

5) 使用 docker inspect 查询 mysql-inspect:v0.01 镜像

rz@demo:~$ docker inspect mysql-inspect:v0.01

输出内容包含完整的镜像信息,其中关键部分显示:

{
    "Id": "sha256:5b0010d39c349bcf9b70f22586117561b4467b6fa5c3b241434b3175b4801d25",
    "RepoTags": [
        "mysql-inspect:v0.01"
    ],
    "Comment": "mysql & inspect",
    "Created": "2025-01-22T03:27:49.999123259Z",
    "DockerVersion": "27.4.1",
    "Author": "Zhu Chuan zhuchuan1978@foxmail.com"
}

6) 使用 -f 参数精确查询镜像信息

# 查询镜像ID
rz@demo:~$ docker inspect -f '{{.Id}}' mysql-inspect:v0.01
sha256:5b0010d39c349bcf9b70f22586117561b4467b6fa5c3b241434b3175b4801d25

# 查询作者信息
rz@demo:~$ docker inspect -f '{{.Author}}' mysql-inspect:v0.01
Zhu Chuan zhuchuan1978@foxmail.com

# 查询注释信息
rz@demo:~$ docker inspect -f '{{.Comment}}' mysql-inspect:v0.01
mysql & inspect

7) 清理资源

# 停止容器
rz@demo:~$ docker stop mysql-studk062
mysql-studk062

rz@demo:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

# 删除挂载目录
rz@demo:~$ sudo rm -rf data_bind06/

rz@demo:~$ ls
debian-src  docker-ce  scripts

# 删除镜像
rz@demo:~$ docker rmi mysql-inspect:v0.01
Untagged: mysql-inspect:v0.01
Deleted: sha256:5b0010d39c349bcf9b70f22586117561b4467b6fa5c3b241434b3175b4801d25
Deleted: sha256:91ab40bbd4ed58f9ed52d67cae77ff71cea1c1ea75f4ca1d9e77f54aa8f0f4c1

rz@demo:~$ docker images
REPOSITORY    TAG             IMAGE ID       CREATED         SIZE
mysql         8.0.40-debian   2d415917245b   3 months ago    610MB
hello-world   latest          d2c94e258dcb   21 months ago   13.3kB

【实践03-创建容器并对容器进行对象查询,观察匿名卷信息】

使用 mysql:8.0.40-debian 镜像创建并运行 mysql-studk063 容器,查看卷列表信息,并用 docker inspect 命令验证容器的匿名卷信息。

1) 创建容器并查看卷列表

rz@demo:~$ docker volume ls
DRIVER    VOLUME NAME

rz@demo:~$ docker run -d --rm --name mysql-studk063 -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.40-debian
aa4dffd6631efb9bf13a024b76209d1ac8955b7ddfc44afd326e10e1567613f1

rz@demo:~$ docker ps
CONTAINER ID   IMAGE                 STATUS         PORTS       NAMES
aa4dffd6631e   mysql:8.0.40-debian   Up 3 seconds   ...3310...  mysql-studk063

rz@demo:~$ docker volume ls
DRIVER    VOLUME NAME
local     c0ee6543a6822fa25b110bda21acb72d6ac91a047c9f4c8ab8571800c3c29ae9

观察:伴随着 mysql-studk063 容器的创建与运行,自动创建了一个匿名卷 c0ee6543a6822...

2) 使用 docker inspect 查询容器匿名卷信息

# 查询容器的挂载卷名称
rz@demo:~$ docker inspect -f '{{range .Mounts}}{{.Name}}{{end}}' mysql-studk063
c0ee6543a6822fa25b110bda21acb72d6ac91a047c9f4c8ab8571800c3c29ae9

# 查看卷存储位置
rz@demo:~$ sudo ls -l /var/lib/docker/volumes/
total 36
brw------- 1 root root  8, 1 Jan 22 09:33 backingFsBlockDev
drwx-----x 3 root root  4096 Jan 22 13:21 c0ee6543a6822fa25b110bda21acb72d6ac91a047c9f4c8ab8571800c3c29ae9
-rw------- 1 root root 65536 Jan 22 13:21 metadata.db

结论:在创建 mysql-studk063 容器时,Docker 自动为其创建了一个匿名卷,存储位置为 /var/lib/docker/volumes 目录。

3) 停止容器并观察卷清理

rz@demo:~$ docker stop mysql-studk063
mysql-studk063

rz@demo:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

rz@demo:~$ docker volume ls
DRIVER    VOLUME NAME

观察:伴随着 mysql-studk063 容器的停止,由于创建时使用了 --rm 参数,容器被自动删除,同时自动创建的匿名卷也自动清除了。


五、资源配额

【实践04-创建容器并限制容器的资源占用】

在 Docker 中可以使用 --cpus 和 -m 或 --memory 选项来限制容器的 CPU 和内存使用上限。本实践将拉取 nginx:1.27-alpine 镜像,创建容器并限制资源使用,然后进行压测观察。

1) 拉取 nginx:1.27-alpine 镜像

rz@demo:~$ docker pull nginx:1.27-alpine
1.27-alpine: Pulling from library/nginx
66a3d608f3fa: Pull complete
...
Digest: sha256:814a8e88df978ade80e584cc5b333144b9372a8e3c98872d07137dbf3b44d0e4
Status: Downloaded newer image for nginx:1.27-alpine
docker.io/library/nginx:1.27-alpine

rz@demo:~$ docker images
REPOSITORY    TAG             IMAGE ID       CREATED         SIZE
nginx         1.27-alpine     93f9c72967db   8 weeks ago     47MB
mysql         8.0.40-debian   2d415917245b   3 months ago    610MB
hello-world   latest          d2c94e258dcb   21 months ago   13.3kB

说明nginx:1.27-alpine 是基于精简的 Linux 发行版 alpine 构建的,具有占用资源少、体积小的特点。

2) 创建 nginx-alpine 容器并限制资源

rz@demo:~$ docker run -d --rm --name nginx-alpine --cpus="0.2" -m 100M -p 8080:80 nginx:1.27-alpine
64173508bbc5c8143bb4a6046a8e27e9d2015f4fea61c4e4460ef689fd7cc206

资源限制参数说明:

  • --cpus="0.2":限制 CPU 使用不超过 0.2 核(即 20% 的 CPU 时间)

  • -m 100M:限制内存使用不超过 100MB

3) 使用 docker stats 命令观察资源占用情况

rz@demo:~$ docker stats nginx-alpine
CONTAINER ID   NAME           CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O     PIDS
64173508bbc5   nginx-alpine   0.00%     3.086MiB / 100MiB   3.09%     946B / 0B   0B / 12.3kB   3

4) 使用 wrk 命令对 Nginx 服务进行压测

rz@demo:~$ wrk -t4 -c100 -d30s http://127.0.0.1:8080
Running 30s test @ http://127.0.0.1:8080
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    37.37ms   29.44ms 169.17ms   61.99%
    Req/Sec   728.67    113.40     1.31k    72.08%
  87067 requests in 30.01s, 70.83MB read
Requests/sec:   2900.99
Transfer/sec:      2.36MB

wrk 命令参数说明:

  • -c 或 --connections:保持的并发连接数(100)

  • -d 或 --duration:持续压测的时间(30秒)

  • -t 或 --threads:发起请求的线程数量(4)

说明:该命令启动 4 个线程,每个线程维护 100 个并发连接,持续测试 30 秒。

5) 压测过程中观察容器资源使用情况

在 wrk 压测过程中(持续 30 秒),新开一个终端窗口,使用 docker stats 观察:

rz@demo:~$ docker stats nginx-alpine
CONTAINER ID   NAME           CPU %     MEM USAGE / LIMIT   MEM %     NET I/O          BLOCK I/O     PIDS
64173508bbc5   nginx-alpine   20.41%    3.746MiB / 100MiB   3.75%     18.8MB / 112MB   0B / 12.3kB   3

资源使用分析:

  • CPU 使用:20.41%,接近预设的 0.2 核(20%)限制

  • 内存使用:3.746MB,远低于 100MB 的限制

  • 网络 I/O:18.8MB 接收 / 112MB 发送,显示有大量网络活动

重要说明:这些限制是软限制。在资源充足的情况下,容器可能会短暂地超过这些限制,但 Docker 会尽力确保容器不会长时间超过其分配的资源。此外,这些限制仅适用于容器内的进程,不会直接影响宿主机的整体资源使用情况。

6) 停止容器并清理资源

rz@demo:~$ docker stop nginx-alpine
nginx-alpine

rz@demo:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

rz@demo:~$ docker volume ls
DRIVER    VOLUME NAME

六、总结与预告

1、下节课程预告

每天半小时,轻松学Docker第八篇:Docker应用部署实训案例

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐