第06章:Docker 容器生命周期

📅 2026/7/2 20:27:11
第06章:Docker 容器生命周期
第06章Docker 容器生命周期本章目标掌握容器从创建到销毁的完整生命周期学会容器的资源管理、健康检查和日志管理。6.1 容器的状态机6.1.1 容器的五种状态┌─────────────────────────────────────────────────────┐ │ Docker 容器状态机 │ │ │ │ ┌──────────┐ │ │ │ Created │ ← docker create / docker run │ │ └────┬─────┘ │ │ │ docker start │ │ ▼ │ │ ┌──────────┐ │ │ │ Running │ ← 容器正在运行 │ │ └──┬───┬───┘ │ │ │ │ │ │ │ │ docker pause / unpause │ │ │ ▼ │ │ │ ┌──────────┐ │ │ │ │ Paused │ ← 进程被 SIGSTOP 挂起 │ │ │ └────┬─────┘ │ │ │ │ docker unpause │ │ │ └──→ Running │ │ │ │ │ │ docker stop (SIGTERM → SIGKILL) │ │ ▼ │ │ ┌──────────┐ │ │ │ Stopped │ ← 容器已停止可重启 │ │ │ (Exited) │ │ │ └────┬─────┘ │ │ │ docker rm │ │ ▼ │ │ ┌──────────┐ │ │ │ Deleted │ ← 容器已删除不可恢复 │ │ └──────────┘ │ └─────────────────────────────────────────────────────┘6.1.2 状态转换命令当前状态操作目标状态命令—创建Createddocker create—创建并启动Runningdocker runCreated启动Runningdocker startRunning暂停Pauseddocker pausePaused恢复Runningdocker unpauseRunning停止Stoppeddocker stopRunning强制停止Stoppeddocker killStopped启动Runningdocker startStopped删除Deleteddocker rm任意强制删除Deleteddocker rm -f6.2 容器的基本操作6.2.1 创建容器# docker create 只创建不启动dockercreate--namemy-nginx-p8080:80 nginx:latest# 输出容器 IDa1b2c3d4e5f6...# 查看创建的容器状态为 Createddockerps-a|grepmy-nginx# CONTAINER ID IMAGE STATUS NAMES# a1b2c3d4e5f6 nginx:latest Created my-nginx# 启动容器dockerstart my-nginx6.2.2 运行容器# 常用的 docker run 参数# 基本运行dockerrun nginx# 后台运行detach 模式dockerrun-dnginx# 交互式运行dockerrun-itubuntu:22.04 /bin/bash# 命名容器dockerrun-d--nameweb-server nginx# 端口映射dockerrun-d-p8080:80 nginx# 主机端口:容器端口dockerrun-d-p127.0.0.1:8080:80 nginx# 仅本地访问dockerrun-d-p8080:80/tcp nginx# 指定协议dockerrun-d-Pnginx# 随机映射 EXPOSE 的端口# 环境变量dockerrun-d-eDB_HOSTmysql-eDB_PORT3306myapp# 挂载卷dockerrun-d-v/host/path:/container/path nginxdockerrun-d--mounttypebind,source/host,target/container nginx# 限制资源dockerrun-d--cpus1.5--memory512mnginx# 自动重启策略dockerrun-d--restartalways nginxdockerrun-d--restartunless-stopped nginx# 设置网络dockerrun-d--networkhostnginxdockerrun-d--networkmy-network nginx# 读写模式dockerrun-d--read-only nginx# 只读文件系统dockerrun-d--tmpfs/tmp nginx# 临时文件系统# 删除退出的容器dockerrun--rmnginx# 容器退出后自动删除6.2.3 docker run 参数详解# 完整的 docker run 示例dockerrun-d\--nameproduction-app\--hostnameapp-server\--networkmy-network\--publish8080:80\--envAPP_ENVproduction\--envDB_HOSTmysql\--volume/data/app:/app/data\--mounttypebind,source/config,target/app/config,readonly\--cpus2\--memory1g\--memory-swap1g\--restartunless-stopped\--health-cmdcurl -f http://localhost/health || exit 1\--health-interval 30s\--health-timeout 5s\--health-retries3\--read-only\--tmpfs/tmp\myapp:latest6.3 容器的停止与删除6.3.1 停止容器# 优雅停止先发 SIGTERM等待后发 SIGKILLdockerstopcontainer# 默认等待 10 秒dockerstop-t30container# 等待 30 秒后强杀# 停止所有运行中的容器dockerstop$(dockerps-q)# 强制停止直接发 SIGKILLdockerkillcontainer# 发送自定义信号dockerkill--signalSIGHUPcontainer# 重载配置dockerkill--signalSIGUSR1container# 自定义信号6.3.2 删除容器# 删除已停止的容器dockerrmcontainerdockercontainerrmcontainer# 强制删除运行中的容器dockerrm-fcontainer# 删除所有已停止的容器dockercontainer prune# 删除所有容器包括运行中的dockerrm-f$(dockerps-aq)# 删除容器时同时删除关联的卷dockerrm-vcontainer6.3.3 清理策略# 一键清理所有停止的容器、无用网络、悬空镜像和构建缓存dockersystem prune# 更彻底的清理dockersystem prune-a--volumes# 清理特定类型的资源dockercontainer prune-f# 停止的容器dockervolume prune-f# 无主的卷dockernetwork prune-f# 无用的网络dockerimage prune-a-f# 未使用的镜像6.4 容器的交互与调试6.4.1 进入运行中的容器# 方式1docker exec推荐dockerexec-itcontainer/bin/bashdockerexec-itcontainer/bin/sh# Alpine 等没有 bash 的镜像# 以特定用户执行dockerexec-it--userrootcontainer/bin/bash# 设置环境变量dockerexec-it-eMY_VARvaluecontainer/bin/bash# 方式2docker attach不推荐dockerattachcontainer# ⚠️ attach 进入的是容器的主进程按 CtrlP, CtrlQ 可以安全退出# ⚠️ 如果直接退出CtrlC容器会停止6.4.2 查看容器日志# 查看容器日志dockerlogscontainer# 实时跟踪日志dockerlogs-fcontainer# 类似 tail -fdockerlogs--followcontainer# 查看最后 N 行dockerlogs--tail100container# 查看特定时间之后的日志dockerlogs--since2024-01-01T10:00:00containerdockerlogs--since30mcontainer# 最近30分钟# 查看特定时间之前的日志dockerlogs--until2024-01-01T12:00:00container# 带时间戳dockerlogs-tcontainer# 查看容器详情包含日志路径dockerinspectcontainer--format{{.LogPath}}# /var/lib/docker/containers/id/id-json.log6.4.3 容器进程查看# 查看容器内运行的进程dockertopcontainer# 查看容器资源使用实时更新dockerstatsdockerstatscontainer# 查看容器资源使用一次性dockerstats --no-streamcontainer# 输出示例# CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O# a1b2c3d4e5f6 web-server 0.05% 12.5MiB / 512MiB 2.44% 1.2kB / 0B 8.19kB / 0B6.5 容器资源限制6.5.1 CPU 限制# 限制 CPU 核数dockerrun-d--cpus1.5nginx# 最多使用 1.5 个 CPU 核心dockerrun-d--cpus2nginx# 最多使用 2 个 CPU 核心# 限制 CPU 份额相对权重dockerrun-d--cpu-shares512nginx# 默认 1024dockerrun-d--cpu-shares1024nginx# 与默认相同dockerrun-d--cpu-shares2048nginx# 两倍权重# 绑定到特定 CPU 核心dockerrun-d--cpuset-cpus0,1nginx# 只使用 CPU 0 和 1dockerrun-d--cpuset-cpus0-3nginx# 使用 CPU 0 到 3# 查看容器 CPU 使用dockerstats --no-stream--formattable {{.Name}}\t{{.CPUPerc}}container6.5.2 内存限制# 限制内存dockerrun-d--memory512mnginx# 最大 512MBdockerrun-d--memory1gnginx# 最大 1GBdockerrun-d--memory1g--memory-swap2gnginx# 内存 1GB swap 1GB# 禁用 OOM Killer谨慎使用dockerrun-d--memory512m--oom-kill-disable nginx# 设置内存软限制dockerrun-d--memory512m--memory-reservation256mnginx# 查看容器内存使用dockerstats --no-stream--formattable {{.Name}}\t{{.MemUsage}}container6.5.3 磁盘 I/O 限制# 限制读写速率dockerrun-d--device-read-bps /dev/sda:10mb nginx# 读速率 10MB/sdockerrun-d--device-write-bps /dev/sda:10mb nginx# 写速率 10MB/s# 限制读写 IOPSdockerrun-d--device-read-iops /dev/sda:1000 nginx# 读 IOPS 1000dockerrun-d--device-write-iops /dev/sda:1000 nginx# 写 IOPS 10006.5.4 查看容器资源使用# 查看所有运行容器的资源使用dockerstats# 实时更新类似 topdockerstats# 单次查询dockerstats --no-stream# 自定义输出格式dockerstats --no-stream--format\table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}6.6 容器健康检查6.6.1 在 Dockerfile 中定义# 健康检查指令 HEALTHCHECK --interval30s --timeout5s --start-period10s --retries3 \ CMD curl -f http://localhost:8080/health || exit 1 # 不同应用的健康检查示例 # Web 应用HTTP 检查 HEALTHCHECK CMD curl -f http://localhost/ || exit 1 # MySQL 数据库 HEALTHCHECK CMD mysqladmin ping -h localhost || exit 1 # Redis HEALTHCHECK CMD redis-cli ping || exit 1 # PostgreSQL HEALTHCHECK CMD pg_isready -U postgres || exit 1 # 禁用健康检查 HEALTHCHECK NONE6.6.2 在 docker run 中定义# 运行时添加健康检查dockerrun-d\--health-cmdcurl -f http://localhost/ || exit 1\--health-interval 30s\--health-timeout 5s\--health-start-period 10s\--health-retries3\nginx6.6.3 查看健康状态# 查看容器健康状态dockerinspect--format{{.State.Health.Status}}container# healthy / unhealthy / starting# 查看健康检查日志dockerinspect--format{{json .State.Health}}container|python3-mjson.tool# 查看所有容器的健康状态dockerps--formattable {{.Names}}\t{{.Status}}# NAMES STATUS# web-server Up 5 minutes (healthy)# database Up 10 minutes (healthy)# cache Up 10 minutes (unhealthy)6.7 容器的重启策略# 设置重启策略dockerrun-d--restartno nginx# 默认不自动重启dockerrun-d--restartalways nginx# 始终重启dockerrun-d--restartunless-stopped nginx# 除非手动停止否则重启dockerrun-d--restarton-failure:5 nginx# 失败时重启最多5次# 重启策略说明# no 不自动重启默认# always 始终重启包括 Docker 守护进程启动时# unless-stopped 类似 always但手动停止的容器不会自动重启# on-failure[:max] 仅在非零退出码退出时重启可选最大重试次数6.8 容器的复制文件# 从容器复制文件到主机dockercpcontainer:/app/logs/app.log ./logs/dockercpa1b2c3d4e5f6:/app/config.json ./config.json# 从主机复制文件到容器dockercp./data.csvcontainer:/app/data/dockercp./config.json web-server:/etc/nginx/conf.d/# 复制目录dockercpcontainer:/app/logs/ ./logs/dockercp./static/container:/app/static/# 注意# 1. 容器可以是运行中或已停止状态# 2. 目标路径不存在时会自动创建# 3. 复制的是文件内容不保留权限和时间戳6.9 容器的导出与快照6.9.1 导出容器文件系统# 导出容器的文件系统为 tar 文件dockerexportcontainercontainer-backup.tardockerexport-ocontainer-backup.tarcontainer# 通过管道导入为镜像dockerexportcontainer|dockerimport- my-snapshot:v1.0# 导出并压缩dockerexportcontainer|gzipcontainer-backup.tar.gz gunzip-ccontainer-backup.tar.gz|dockerimport- my-snapshot:v1.06.9.2 docker commit vs docker export操作docker commitdocker export输入运行中的容器运行或停止的容器输出新镜像保留层和元数据tar 文件单层丢失元数据用途基于容器创建镜像备份容器文件系统数据保留保留所有层只保留最终状态6.10 动手实验实验 6.1容器生命周期完整体验# 1. 创建容器不启动dockercreate--namelifecycle-test ubuntu:22.04sleep3600# 2. 查看状态dockerps-a|greplifecycle-test# 状态Created# 3. 启动容器dockerstart lifecycle-testdockerps|greplifecycle-test# 状态Up ... (running)# 4. 暂停容器dockerpause lifecycle-testdockerps|greplifecycle-test# 状态Up ... (Paused)# 5. 恢复容器dockerunpause lifecycle-testdockerps|greplifecycle-test# 状态Up ... (running)# 6. 停止容器dockerstop lifecycle-testdockerps-a|greplifecycle-test# 状态Exited (0) ...# 7. 重新启动dockerstart lifecycle-testdockerps|greplifecycle-test# 状态Up ... (running)# 8. 强制停止并删除dockerrm-flifecycle-testdockerps-a|greplifecycle-test# 无输出已删除实验 6.2资源限制测试# 1. 启动一个限制资源的容器dockerrun-d--nameresource-test\--cpus0.5\--memory256m\nginx:latest# 2. 查看资源限制dockerinspect resource-test--format{{.HostConfig.CpuQuota}}dockerinspect resource-test--format{{.HostConfig.Memory}}# 3. 监控资源使用dockerstats resource-test# 4. 在容器内进行压力测试dockerexec-itresource-testbash# 安装压测工具apt-getupdateapt-getinstall-ystress# 创建 CPU 压力单核stress--cpu1--timeout30s# 5. 观察 CPU 使用率被限制在 50%# 6. 清理dockerrm-fresource-test实验 6.3健康检查测试# 1. 启动一个带健康检查的容器dockerrun-d--namehealth-test\--health-cmdcurl -f http://localhost/ || exit 1\--health-interval 5s\--health-timeout 3s\--health-retries3\nginx:latest# 2. 观察健康状态变化dockerps# 初始状态health: starting# 几秒后 health: healthy# 3. 模拟不健康状态dockerexec-ithealth-testbash-cecho server { } /etc/nginx/conf.d/default.conf nginx -s reloadsleep10dockerps# 状态health: unhealthy# 4. 清理dockerrm-fhealth-test6.11 本章小结操作命令说明创建docker create创建容器但不启动运行docker run创建并启动容器启动docker start启动已停止的容器暂停docker pause挂起容器进程恢复docker unpause恢复暂停的容器停止docker stop优雅停止容器强杀docker kill强制停止容器重启docker restart重启容器删除docker rm删除容器进入docker exec -it进入运行中的容器日志docker logs查看容器日志统计docker stats查看资源使用复制docker cp在容器和主机间复制文件6.12 课后练习基础题创建一个 Nginx 容器体验从创建到删除的完整生命周期。进阶题为 Nginx 容器配置 CPU 和内存限制使用压测工具验证限制效果。实践题为 MySQL 容器配置健康检查观察健康状态的变化。 下一章Docker 网络模型 —— 深入理解容器间通信机制