强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Docker 完全指南 / 05 - 容器管理

05 - 容器管理

掌握容器的完整生命周期:创建、运行、停止、删除,以及 exec、logs、inspect 等调试技巧。


5.1 容器生命周期

容器状态流转:

  ┌─────────┐  docker create  ┌──────────┐  docker start   ┌───────────┐
  │  Image  │ ──────────────> │ Created  │ ──────────────> │  Running  │
  └─────────┘                 └──────────┘                 └─────┬─────┘
                          ┌──────────────┐   docker stop          │
                          │   Stopped    │ <─────────────────────┤
                          └──────┬───────┘                       │
                                 │                                │
                          docker restart                          │
                                 │           docker pause         │
                                 ▼           ───────────>  ┌──────────┐
                          ┌───────────┐                    │  Paused  │
                          │  Running  │ <── docker unpause └──────────┘
                          └─────┬─────┘
                          docker kill / 进程退出
                          ┌──────────┐  docker rm   ┌─────────┐
                          │  Exited  │ ──────────> │ Removed │
                          └──────────┘              └─────────┘

状态说明

状态 说明 典型操作
Created 已创建但未启动 docker create
Running 运行中 docker start, docker run
Paused 已暂停(进程冻结) docker pause
Exited 已退出(进程结束) docker stop, docker kill
Removing 正在删除中 docker rm
Dead 异常状态 需手动清理

5.2 创建容器(Create)

docker create 创建容器但不启动:

# 创建容器
docker create --name my-nginx -p 8080:80 nginx:alpine

# 查看已创建的容器
docker ps -a

# 稍后启动
docker start my-nginx

5.3 运行容器(Run)

docker run 是最常用的命令,等价于 create + start

基本语法

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

常用选项详解

选项 缩写 说明 示例
--name 容器名称 --name web
--detach -d 后台运行 -d
--interactive -i 保持标准输入打开 -i
--tty -t 分配伪终端 -t
--rm 退出后自动删除 --rm
--publish -p 端口映射 -p 8080:80
--volume -v 挂载卷 -v data:/app
--env -e 设置环境变量 -e NODE_ENV=prod
--network 指定网络 --network mynet
--restart 重启策略 --restart unless-stopped
--memory -m 内存限制 -m 512m
--cpus CPU 限制 --cpus 1.5
--workdir -w 工作目录 -w /app
--user -u 指定用户 -u 1000:1000
--entrypoint 覆盖入口点 --entrypoint /bin/sh

常见运行模式

# 1. 后台运行服务
docker run -d --name nginx-web -p 8080:80 nginx:alpine

# 2. 交互式 shell
docker run -it --name dev-ubuntu ubuntu:22.04 bash

# 3. 一次性任务(运行后自动删除)
docker run --rm ubuntu:22.04 echo "Hello Docker"

# 4. 带资源限制的运行
docker run -d --name limited \
    -m 256m --cpus 0.5 \
    -p 8080:80 nginx:alpine

# 5. 挂载数据卷的运行
docker run -d --name data-nginx \
    -v ./html:/usr/share/nginx/html:ro \
    -p 8080:80 nginx:alpine

# 6. 设置环境变量
docker run -d --name db \
    -e POSTGRES_PASSWORD=secret \
    -e POSTGRES_DB=myapp \
    -p 5432:5432 postgres:16

# 7. 设置重启策略
docker run -d --restart unless-stopped \
    --name always-nginx -p 8080:80 nginx:alpine

# 8. 使用主机网络
docker run -d --network host nginx:alpine

# 9. 覆盖入口点
docker run -it --entrypoint /bin/sh nginx:alpine

# 10. 添加额外的 hosts 记录
docker run -d --add-host host.docker.internal:host-gateway nginx:alpine

重启策略

策略 说明
no 默认,不自动重启
on-failure[:max] 非零退出码时重启,可指定最大次数
always 总是重启(包括 daemon 启动时)
unless-stopped 总是重启,除非手动停止
# 设置重启策略
docker run -d --restart on-failure:5 --name web nginx:alpine

# 查看重启次数
docker inspect --format '{{.RestartCount}}' web

# 修改已有容器的重启策略
docker update --restart unless-stopped web

5.4 容器列表(PS)

# 运行中的容器
docker ps

# 所有容器(包括已停止的)
docker ps -a

# 仅显示容器 ID
docker ps -q

# 格式化输出
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}"

# 自定义格式
docker ps --format '{"id":"{{.ID}}","name":"{{.Names}}","status":"{{.Status}}"}'

# 过滤
docker ps --filter "status=running"
docker ps --filter "name=web"
docker ps --filter "ancestor=nginx:alpine"
docker ps --filter "label=env=production"

# 按大小排序
docker ps -s --format "table {{.Names}}\t{{.Size}}"

# 最近创建的 N 个容器
docker ps -n 5

5.5 容器日志(Logs)

# 查看全部日志
docker logs my-container

# 实时跟踪日志(类似 tail -f)
docker logs -f my-container

# 显示最近 N 行
docker logs --tail 100 my-container

# 显示时间戳
docker logs -t my-container

# 查看指定时间后的日志
docker logs --since 2024-01-01T00:00:00 my-container
docker logs --since 30m my-container    # 最近 30 分钟

# 查看指定时间前的日志
docker logs --until 2024-01-02T00:00:00 my-container

# 组合使用
docker logs -f --tail 50 --since 10m my-container

日志驱动

驱动 说明 用途
json-file 默认,JSON 格式写入文件 通用
syslog 发送到 syslog 集中日志
journald 发送到 systemd journal systemd 环境
fluentd 发送到 fluentd 日志聚合
awslogs 发送到 AWS CloudWatch AWS 环境
none 禁用日志 无需日志的场景
# 查看当前日志驱动
docker info | grep "Logging Driver"

# 为单个容器指定日志驱动
docker run -d \
    --log-driver=json-file \
    --log-opt max-size=10m \
    --log-opt max-file=3 \
    --name web nginx:alpine

# 全局配置 (/etc/docker/daemon.json)
# {
#   "log-driver": "json-file",
#   "log-opts": {
#     "max-size": "10m",
#     "max-file": "3"
#   }
# }

5.6 进入容器(Exec)

# 进入运行中的容器(交互式 shell)
docker exec -it my-container /bin/bash

# 如果容器没有 bash,使用 sh
docker exec -it my-container /bin/sh

# 以 root 用户进入
docker exec -it -u root my-container /bin/bash

# 执行单条命令(不进入交互模式)
docker exec my-container cat /etc/os-release
docker exec my-container ls -la /app
docker exec my-container env

# 设置环境变量
docker exec -e MY_VAR=hello my-container printenv MY_VAR

# 在指定目录执行
docker exec -w /tmp my-container pwd

# 以指定用户执行
docker exec -u www-data my-container whoami

exec vs attach

特性 docker exec docker attach
创建新进程 ✅ 新进程 ❌ 连接主进程
退出影响 不影响容器 可能停止容器
多终端 ✅ 多个 exec ❌ 只能一个 attach
用途 调试、运行命令 查看主进程输出
# attach 到容器主进程
docker attach my-container
# 退出: Ctrl+P, Ctrl+Q(detach)
# 注意: 不要按 Ctrl+C,会终止容器主进程

5.7 容器信息(Inspect)

# 查看完整 JSON 信息
docker inspect my-container

# 使用 Go template 提取特定字段
docker inspect --format '{{.State.Status}}' my-container
docker inspect --format '{{.NetworkSettings.IPAddress}}' my-container
docker inspect --format '{{.HostConfig.Memory}}' my-container
docker inspect --format '{{json .State}}' my-container

# 使用 jq 过滤(更灵活)
docker inspect my-container | jq '.[0].State'
docker inspect my-container | jq '.[0].NetworkSettings.Networks'
docker inspect my-container | jq '.[0].Mounts'
docker inspect my-container | jq '.[0].Config.Env'

常用 inspect 字段

字段路径 说明
.State.Status 容器状态
.State.Pid 主进程 PID
.State.StartedAt 启动时间
.NetworkSettings.IPAddress 容器 IP
.NetworkSettings.Ports 端口映射
.HostConfig.Memory 内存限制
.HostConfig.NanoCpus CPU 限制
.Mounts 挂载信息
.Config.Image 使用的镜像
.Config.Env 环境变量

5.8 容器的文件操作

# 从宿主机复制到容器
docker cp ./config.yml my-container:/app/config.yml

# 从容器复制到宿主机
docker cp my-container:/var/log/nginx/access.log ./access.log

# 复制目录
docker cp ./templates my-container:/app/templates

5.9 容器资源监控

# 实时查看容器资源使用
docker stats

# 仅查看一次(不持续更新)
docker stats --no-stream

# 指定容器
docker stats my-container --no-stream

# 格式化输出
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"

# 输出示例:
# NAME       CPU %   MEM USAGE / LIMIT   NET I/O           BLOCK I/O
# web        0.15%   15MiB / 256MiB      1.2kB / 0B        0B / 0B
# db         1.25%   120MiB / 512MiB     5.6kB / 2.1kB     12MB / 0B

5.10 容器停止与删除

# 停止容器(发送 SIGTERM,超时后 SIGKILL)
docker stop my-container

# 指定超时时间(默认 10 秒)
docker stop -t 30 my-container

# 强制停止(直接 SIGKILL)
docker kill my-container

# 发送指定信号
docker kill --signal=SIGHUP my-container

# 重启容器
docker restart my-container

# 暂停/恢复容器
docker pause my-container
docker unpause my-container

# 删除已停止的容器
docker rm my-container

# 强制删除运行中的容器
docker rm -f my-container

# 删除所有已停止的容器
docker container prune

# 删除所有已停止的容器(跳过确认)
docker container prune -f

# 删除指定时间前的已停止容器
docker container prune --filter "until=24h"

批量操作

# 停止所有运行中的容器
docker stop $(docker ps -q)

# 删除所有已停止的容器
docker rm $(docker ps -aq --filter "status=exited")

# 删除所有容器(危险!)
docker rm -f $(docker ps -aq)

5.11 等待与事件监听

# 等待容器停止并获取退出码
docker wait my-container
# 输出: 0 (正常退出)

# 查看容器的退出码
docker inspect --format '{{.State.ExitCode}}' my-container

# 查看容器的 OOM(内存溢出)状态
docker inspect --format '{{.State.OOMKilled}}' my-container

# 实时监听 Docker 事件
docker events

# 过滤特定类型的事件
docker events --filter "type=container"
docker events --filter "event=start"
docker events --filter "container=my-container"

# 查看最近 5 分钟的事件
docker events --since 5m

# JSON 格式输出
docker events --format '{{json .}}'

5.12 容器重命名与更新

# 重命名容器
docker rename old-name new-name

# 更新容器配置(运行中的容器)
docker update --restart unless-stopped my-container
docker update --memory 512m --cpus 1 my-container

要点回顾

要点 核心内容
run 命令 最常用,-d 后台运行,-it 交互式,--rm 自动清理
日志管理 docker logs -f --tail,注意配置日志轮转
exec 调试 进入容器调试首选方式,不影响主进程
资源限制 --memory, --cpus 限制资源使用
重启策略 生产环境使用 unless-stopped
清理 定期 docker system prune 清理无用资源

注意事项

容器内 PID 1: 容器内的第一个进程是 PID 1,它负责处理信号和回收子进程。使用 exec 模式(而非 shell 模式)确保应用成为 PID 1。

日志轮转: 默认不限制日志大小,可能导致磁盘写满。务必在 daemon.json 中配置 max-sizemax-file

优雅停止: Docker 默认等待 10 秒后才强制停止容器。如果应用需要更长的关闭时间,使用 docker stop -t 60 或在 Dockerfile 中设置 STOPSIGNAL


下一步

06 - Dockerfile 详解:学习如何编写高效的 Dockerfile。