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

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
--cpusCPU 限制--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 journalsystemd 环境
fluentd发送到 fluentd日志聚合
awslogs发送到 AWS CloudWatchAWS 环境
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 execdocker 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.NanoCpusCPU 限制
.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。