Docker 容器生命周期管理:run/exec/logs/inspect/cp 命令详解
系统讲解 Docker 容器的完整生命周期:docker run 常用参数(-d/-p/-v/-e/--name/--restart)、容器状态机(created/running/paused/stopped/dead)、docker exec 进入容器调试、docker logs 日志查看与跟踪、docker inspect 容器信息提取、docker cp 文件传输,以及容器的优雅停止与强制删除。
容器生命周期管理是 Docker 日常运维中最频繁的操作。本文以“一个容器从创建到删除”的完整流程为主线,系统讲解所有相关命令,重点覆盖生产环境中最常见的参数和使用场景。
容器状态机
Docker 容器有几种状态,理解状态转换对排障很重要:
docker create
↓
Created(已创建,未运行)
↓ docker start
Running(运行中) ←──────── docker unpause
↓ ↓
docker pause docker stop/kill
↓ ↓
Paused Stopped(已停止,进程退出)
↓ docker start
Running
↓ docker rm
Deleted(已删除,不可恢复)
特殊状态:
Restarting:正在重启(restart policy 触发)
Dead:容器进程崩溃且无法恢复
OOMKilled:被内核 OOM Killer 杀死
一、docker run — 启动容器
docker run 是最核心的命令,等于 docker create + docker start。
基础参数
# 前台运行(看到输出,Ctrl+C 退出并停止容器)
docker run nginx
# 后台运行(-d/--detach,最常用)
docker run -d nginx
# 交互模式(-it,进入容器 shell)
docker run -it ubuntu:22.04 bash
# -i: 保持 stdin 打开
# -t: 分配 TTY 终端(使 shell 可以正常交互)
端口映射 (-p)
# 格式:-p 宿主机端口:容器端口
docker run -d -p 8080:80 nginx # 宿主机 8080 → 容器 80
docker run -d -p 443:443 -p 80:80 nginx # 多端口映射
# 绑定特定 IP(限制访问来源)
docker run -d -p 127.0.0.1:8080:80 nginx # 只允许本机访问
# 随机端口(宿主机随机分配)
docker run -d -p 80 nginx
docker port <container> # 查看分配的端口
环境变量 (-e)
# 传入单个环境变量
docker run -d \
-e MYSQL_ROOT_PASSWORD=secret123 \
-e MYSQL_DATABASE=myapp \
mysql:8.0
# 从文件读取(每行 KEY=VALUE)
cat > .env << 'EOF'
MYSQL_ROOT_PASSWORD=secret123
MYSQL_DATABASE=myapp
MYSQL_USER=appuser
MYSQL_PASSWORD=apppass123
EOF
docker run -d --env-file .env mysql:8.0
# 传递宿主机的环境变量
docker run -d -e JAVA_OPTS=$JAVA_OPTS myapp:v1
数据卷挂载 (-v)
# Bind mount(挂载宿主机目录)
docker run -d \
-v /data/nginx/html:/usr/share/nginx/html \
-v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
nginx
# :ro 表示容器内只读
# Named volume(Docker 管理的卷)
docker run -d \
-v mysql_data:/var/lib/mysql \
mysql:8.0
# --mount 语法(更清晰,推荐)
docker run -d \
--mount type=bind,source=/data/app,target=/app \
--mount type=volume,source=mysql_data,target=/var/lib/mysql \
myapp:v1
容器命名和重启策略
# 命名容器(--name)
docker run -d --name mysql-prod mysql:8.0
docker run -d --name nginx-prod nginx
# 重启策略(--restart)
docker run -d --restart=always nginx # 总是重启(系统重启后也会启动)
docker run -d --restart=unless-stopped nginx # 手动 stop 不重启,其他情况重启
docker run -d --restart=on-failure:3 nginx # 失败时重启,最多 3 次
docker run -d --restart=no nginx # 不自动重启(默认)
# 生产建议:使用 unless-stopped 或 always
资源限制
# CPU 限制
docker run -d --cpus=1.5 nginx # 最多使用 1.5 个 CPU 核
docker run -d --cpu-shares=512 nginx # 相对权重(默认 1024)
# 内存限制
docker run -d --memory=512m nginx # 内存上限 512MB(超出被 OOM Kill)
docker run -d --memory=512m --memory-swap=1g nginx # 内存+Swap 共 1GB
# 同时设置(生产推荐)
docker run -d \
--cpus=2 \
--memory=1g \
--memory-swap=1g \ # 禁止使用 swap(swap=memory 时)
--name myapp \
myapp:v1
其他常用参数
# 删除容器时自动清理(--rm,适合临时任务)
docker run --rm ubuntu echo "hello world"
# 设置主机名
docker run -d --hostname myapp-01 myapp:v1
# 设置 DNS
docker run -d --dns=114.114.114.114 myapp:v1
# 连接到已有网络
docker run -d --network=mynet myapp:v1
# 容器间共享网络(--network=container:)
docker run -d --network=container:nginx-prod myapp-sidecar
# 特权模式(尽量避免)
docker run -d --privileged myapp:v1 # 危险!容器有完整宿主机权限
二、容器状态查看
# 查看运行中的容器
docker ps
# 输出示例:
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# a1b2c3d4e5f6 nginx "/docker-entrypoint…" 2 hours ago Up 2 hours 0.0.0.0:8080->80/tcp nginx-prod
# 查看所有容器(包括已停止的)
docker ps -a
# 只显示容器 ID(用于脚本)
docker ps -q # 运行中
docker ps -aq # 所有
# 格式化输出
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# 过滤
docker ps --filter "name=nginx" # 按名称过滤
docker ps --filter "status=exited" # 查找已停止的容器
docker ps --filter "ancestor=nginx:1.25" # 按基础镜像过滤
# 查看容器统计(CPU/内存实时)
docker stats # 所有容器
docker stats nginx-prod redis-prod # 指定容器
docker stats --no-stream # 只输出一次,不刷新
三、docker exec — 进入容器
# 进入运行中容器的 bash(最常用)
docker exec -it nginx-prod bash
# 如果容器没有 bash,用 sh
docker exec -it alpine-prod sh
# 执行单条命令(不进入交互)
docker exec nginx-prod nginx -t # 检查 nginx 配置
docker exec mysql-prod mysqladmin ping # 检查 MySQL 是否运行
# 以指定用户执行
docker exec -it -u root nginx-prod bash # root 用户
docker exec -it -u 1000 myapp bash # UID 1000
# 设置环境变量
docker exec -e DEBUG=true myapp python debug.py
# 在指定目录执行
docker exec -w /tmp myapp ls -la
exec vs attach 的区别:
# docker attach:连接到容器的主进程 stdin/stdout
docker attach nginx-prod
# 危险:Ctrl+C 会停止容器!只在需要查看主进程输出时使用
# docker exec:在容器内创建新进程
docker exec -it nginx-prod bash
# 安全:exit 退出但容器继续运行
四、docker logs — 查看容器日志
# 查看全部日志
docker logs nginx-prod
# 跟踪日志(-f,类似 tail -f)
docker logs -f nginx-prod
# 最近 N 行
docker logs --tail=100 nginx-prod
# 跟踪最近 50 行
docker logs -f --tail=50 nginx-prod
# 按时间过滤
docker logs --since="2026-06-10T10:00:00" nginx-prod
docker logs --since=2h nginx-prod # 最近 2 小时
docker logs --until=1h nginx-prod # 1 小时前之前的
# 显示时间戳
docker logs -t nginx-prod
# 综合用法(生产排障最常用)
docker logs -f --tail=100 -t nginx-prod
# 保存日志到文件
docker logs nginx-prod > nginx.log 2>&1
日志驱动配置:
# 查看容器使用的日志驱动
docker inspect nginx-prod --format '{{.HostConfig.LogConfig}}'
# daemon.json 全局配置(推荐)
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m", ← 单个日志文件最大 100MB
"max-file": "3" ← 保留 3 个日志文件(滚动)
}
}
# 单容器指定(覆盖全局配置)
docker run -d \
--log-driver=json-file \
--log-opt max-size=50m \
--log-opt max-file=5 \
nginx-prod
五、docker inspect — 查看容器详情
# 完整 JSON 信息
docker inspect nginx-prod
# 常用字段提取
# IP 地址
docker inspect nginx-prod --format '{{.NetworkSettings.IPAddress}}'
# 挂载卷
docker inspect nginx-prod --format '{{json .Mounts}}' | jq .
# 环境变量
docker inspect nginx-prod --format '{{json .Config.Env}}' | jq .
# 启动命令
docker inspect nginx-prod --format '{{json .Config.Cmd}}'
# 容器状态(ExitCode、OOMKilled 等)
docker inspect nginx-prod --format '{{json .State}}' | jq .
# 资源限制
docker inspect nginx-prod --format \
'Memory: {{.HostConfig.Memory}} CPUs: {{.HostConfig.NanoCpus}}'
# 查看容器的完整网络信息
docker inspect nginx-prod --format '{{json .NetworkSettings.Networks}}' | jq .
六、docker cp — 容器与宿主机文件传输
# 从容器复制到宿主机
docker cp nginx-prod:/etc/nginx/nginx.conf ./nginx.conf
docker cp nginx-prod:/var/log/nginx/ ./nginx-logs/
# 从宿主机复制到容器
docker cp ./nginx.conf nginx-prod:/etc/nginx/nginx.conf
docker cp ./myapp.jar myapp-prod:/opt/app/myapp.jar
# 使用场景:
# 1. 临时修改容器内配置(测试用,生产应重新构建镜像)
docker cp nginx.conf nginx-prod:/etc/nginx/nginx.conf
docker exec nginx-prod nginx -s reload
# 2. 从容器拿出日志/数据
docker cp nginx-prod:/var/log/nginx/error.log ./
# 3. 不进入容器直接查看文件
docker cp nginx-prod:/etc/nginx/nginx.conf - # 输出到 stdout
七、容器停止与删除
# 优雅停止(发送 SIGTERM,等待进程自行退出)
docker stop nginx-prod # 默认等待 10 秒
docker stop -t 30 nginx-prod # 等待 30 秒后强制 SIGKILL
# 强制停止(立即发送 SIGKILL)
docker kill nginx-prod
docker kill --signal=SIGUSR1 nginx-prod # 发送指定信号
# 重启
docker restart nginx-prod
docker restart -t 5 nginx-prod # 等 5 秒再重启
# 删除停止的容器
docker rm nginx-prod
# 删除运行中的容器(强制)
docker rm -f nginx-prod # 慎用
# 批量删除所有已停止的容器
docker container prune
# 删除所有容器(包括运行中的)
docker rm -f $(docker ps -aq) # 危险!生产禁用
容器操作速查
# 创建但不启动
docker create --name myapp myapp:v1
# 启动已存在的容器
docker start myapp
# 暂停/恢复(冻结进程,适合快照前)
docker pause myapp
docker unpause myapp
# 查看容器进程
docker top myapp
# 查看容器的端口映射
docker port myapp
# 等待容器退出
docker wait myapp
echo "Container exited with: $?"
# 查看容器变更(相对于镜像)
docker diff myapp
# C /var/log/nginx ← C = Changed
# A /var/log/nginx/access.log ← A = Added
小结
容器生命周期管理的核心:
docker run -d 启动容器(后台模式),-p 映射端口,-v 挂载数据,-e 传环境变量,--restart=unless-stopped 设置重启策略。
日常运维最常用的组合:
docker logs -f --tail=100 <container> # 看日志
docker exec -it <container> bash # 进入排查
docker stats <container> # 看资源使用
docker inspect <container> # 看配置详情
下一篇讲 Dockerfile:如何通过写 Dockerfile 把自己的应用打包成镜像。
