Docker容器基础

一、容器创建与启动

1.1 docker run命令

1.1.1 基本语法

命令格式

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

常用选项

运行模式:
-d, --detach          后台运行
-it                   交互式运行
--rm                  容器退出后自动删除

命名与标识:
--name string         容器名称
-h, --hostname string 容器主机名

网络配置:
-p, --publish list    发布端口
-P, --publish-all     发布所有端口
--net string          网络模式

资源限制:
-m, --memory bytes    内存限制
--cpus decimal        CPU限制
--cpu-shares int      CPU权重

存储挂载:
-v, --volume list     挂载卷
--mount mount         挂载点

环境变量:
-e, --env list        环境变量
--env-file list       环境变量文件

重启策略:
--restart string      重启策略

1.1.2 基本使用

简单运行

# 前台运行
docker run nginx:latest

# 后台运行
docker run -d nginx:latest

# 交互式运行
docker run -it ubuntu:22.04 bash

# 指定名称
docker run -d --name mynginx nginx:latest

# 运行后自动删除
docker run --rm nginx:latest echo "hello"

端口映射

# 映射单个端口
docker run -d -p 8080:80 nginx:latest

# 映射多个端口
docker run -d -p 8080:80 -p 8443:443 nginx:latest

# 指定IP映射
docker run -d -p 127.0.0.1:8080:80 nginx:latest

# 随机端口映射
docker run -d -P nginx:latest

# 查看端口映射
docker port 容器名

环境变量

# 设置单个环境变量
docker run -d -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0

# 设置多个环境变量
docker run -d \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_DATABASE=mydb \
  mysql:8.0

# 从文件加载环境变量
docker run -d --env-file env.list myapp

# env.list文件内容
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=mydb

1.2 容器启动流程

1.2.1 启动过程详解

启动流程

docker run nginx:latest

执行步骤:
┌─────────────────────────────┐
│ 1. 检查本地是否有镜像        │
└──────────┬──────────────────┘
           │ 没有
           ↓
┌─────────────────────────────┐
│ 2. 从仓库拉取镜像            │
└──────────┬──────────────────┘
           │
           ↓
┌─────────────────────────────┐
│ 3. 创建容器文件系统          │
└──────────┬──────────────────┘
           │
           ↓
┌─────────────────────────────┐
│ 4. 配置网络和存储            │
└──────────┬──────────────────┘
           │
           ↓
┌─────────────────────────────┐
│ 5. 执行容器启动命令          │
└──────────┬──────────────────┘
           │
           ↓
┌─────────────────────────────┐
│ 6. 容器运行中                │
└─────────────────────────────┘

东巴文理解

容器启动 = 开机启动
就像:打开一台虚拟的电脑

启动过程:
├─ 检查系统盘(检查镜像)
├─ 安装系统(拉取镜像)
├─ 创建文件系统(准备容器层)
├─ 连接网络(配置网络)
├─ 加载程序(启动进程)
└─ 系统运行(容器运行)

1.2.2 启动选项详解

运行模式

# 前台运行(默认)
docker run nginx:latest
# 容器日志输出到终端
# Ctrl+C停止容器

# 后台运行(-d)
docker run -d nginx:latest
# 容器在后台运行
# 返回容器ID

# 交互式运行(-it)
docker run -it ubuntu:22.04 bash
# 进入容器交互终端
# exit退出容器

# 临时运行(--rm)
docker run --rm alpine:latest echo "hello"
# 执行完命令后自动删除容器

重启策略

# 不重启(默认)
docker run -d --restart=no nginx:latest

# 总是重启
docker run -d --restart=always nginx:latest

# 除非手动停止,否则重启
docker run -d --restart=unless-stopped nginx:latest

# 失败时重启(最多3次)
docker run -d --restart=on-failure:3 nginx:latest

# 重启策略说明
┌────────────────┬────────────────────────────┐
│ 策略           │ 说明                       │
├────────────────┼────────────────────────────┤
│ no             │ 不自动重启(默认)         │
│ always         │ 总是重启                   │
│ unless-stopped │ 除非手动停止,否则重启     │
│ on-failure     │ 失败时重启                 │
└────────────────┴────────────────────────────┘

二、容器生命周期管理

2.1 查看容器

2.1.1 docker ps命令

基本语法

docker ps [OPTIONS]

OPTIONS:
  -a, --all         显示所有容器(包括停止的)
  -f, --filter      过滤条件
      --format      格式化输出
  -n, --last int    显示最后n个容器
  -l, --latest      显示最新创建的容器
  -q, --quiet       只显示ID
  -s, --size        显示大小

使用示例

# 查看运行中的容器
docker ps

# 输出示例
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                NAMES
a1b2c3d4e5f6   nginx:latest   "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   0.0.0.0:8080->80/tcp mynginx

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

# 只显示ID
docker ps -q

# 显示最后3个容器
docker ps -n 3

# 显示最新创建的容器
docker ps -l

# 显示容器大小
docker ps -s

# 过滤容器
docker ps -f "status=running"
docker ps -f "name=mynginx"
docker ps -f "ancestor=nginx"

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

2.1.2 容器状态

状态类型

Created(已创建):
├─ 容器已创建但未启动
├─ 文件系统已准备
└─ 资源已分配

Running(运行中):
├─ 容器正在运行
├─ 进程活跃
└─ 资源正在使用

Paused(已暂停):
├─ 容器进程被挂起
├─ 内存状态保留
└─ 可恢复运行

Restarting(重启中):
├─ 容器正在重启
└─ 通常由于崩溃或配置

Exited(已退出):
├─ 容器进程已终止
├─ 资源已释放
└─ 可重新启动

Dead(已死亡):
├─ 容器无法启动
└─ 通常由于设备问题

2.2 启动与停止

2.2.1 启动容器

docker start命令

# 启动已停止的容器
docker start mynginx

# 启动并附加
docker start -a mynginx

# 启动多个容器
docker start container1 container2 container3

# 启动所有停止的容器
docker start $(docker ps -aq -f status=exited)

docker restart命令

# 重启容器
docker restart mynginx

# 指定停止时间
docker restart -t 10 mynginx

# 重启多个容器
docker restart container1 container2

2.2.2 停止容器

docker stop命令

# 优雅停止(发送SIGTERM)
docker stop mynginx

# 指定等待时间(秒)
docker stop -t 10 mynginx

# 停止多个容器
docker stop container1 container2 container3

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

docker kill命令

# 强制停止(发送SIGKILL)
docker kill mynginx

# 发送指定信号
docker kill -s SIGINT mynginx

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

stop vs kill

docker stop:
├─ 发送SIGTERM信号
├─ 等待进程优雅退出
├─ 超时后发送SIGKILL
└─ 推荐使用

docker kill:
├─ 发送SIGKILL信号
├─ 立即终止进程
├─ 不等待进程退出
└─ 强制使用

推荐:
✅ 优先使用stop
⚠️ kill用于无响应的容器

2.3 暂停与恢复

2.3.1 暂停容器

docker pause命令

# 暂停容器
docker pause mynginx

# 暂停多个容器
docker pause container1 container2

# 查看暂停状态
docker ps -f "status=paused"

# 输出示例
CONTAINER ID   IMAGE          STATUS
a1b2c3d4e5f6   nginx:latest   Up 5 minutes (Paused)

2.3.2 恢复容器

docker unpause命令

# 恢复容器
docker unpause mynginx

# 恢复多个容器
docker unpause container1 container2

# 恢复所有暂停的容器
docker unpause $(docker ps -q -f "status=paused")

pause vs stop

docker pause:
├─ 冻结容器进程
├─ 内存状态保留
├─ 恢复速度快
└─ 不释放资源

docker stop:
├─ 终止容器进程
├─ 内存状态释放
├─ 启动速度慢
└─ 释放资源

使用场景:
✅ pause:临时暂停,快速恢复
✅ stop:长时间停止,释放资源

2.4 删除容器

2.4.1 docker rm命令

基本语法

docker rm [OPTIONS] CONTAINER [CONTAINER...]

OPTIONS:
  -f, --force     强制删除运行中的容器
  -l, --link      删除链接
  -v, --volumes   删除关联的卷

使用示例

# 删除已停止的容器
docker rm mynginx

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

# 删除多个容器
docker rm container1 container2 container3

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

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

# 删除容器和关联的卷
docker rm -v mynginx

2.4.2 清理容器

docker container prune命令

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

# 输出
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
a1b2c3d4e5f6
b2c3d4e5f6a7
Total reclaimed space: 50MB

# 强制删除,不提示
docker container prune -f

# 过滤条件
docker container prune --filter "until=24h"

三、容器资源限制

3.1 内存限制

3.1.1 内存限制选项

基本语法

docker run [OPTIONS] IMAGE

OPTIONS:
  -m, --memory bytes           内存限制
      --memory-reservation bytes  内存软限制
      --memory-swap bytes      内存+交换分区限制
      --memory-swappiness int  交换分区使用倾向(0-100)
      --oom-kill-disable       禁用OOM Killer

使用示例

# 限制内存为512MB
docker run -d -m 512m nginx:latest

# 限制内存为1GB,交换分区为2GB
docker run -d -m 1g --memory-swap 2g nginx:latest

# 设置内存软限制
docker run -d -m 1g --memory-reservation 512m nginx:latest

# 禁用OOM Killer
docker run -d -m 512m --oom-kill-disable nginx:latest

# 设置交换分区使用倾向
docker run -d -m 512m --memory-swappiness 0 nginx:latest

3.1.2 内存限制详解

内存限制类型

硬限制(-m):
├─ 容器最大可用内存
├─ 超过限制会触发OOM
├─ 可能导致容器被杀死
└─ 示例:-m 512m

软限制(--memory-reservation):
├─ 内存不足时的最小保证
├─ 不会触发OOM
├─ 允许超过限制
└─ 示例:--memory-reservation 256m

交换分区限制(--memory-swap):
├─ 内存+交换分区总量
├─ 必须大于内存限制
└─ 示例:--memory-swap 1g

交换分区倾向(--memory-swappiness):
├─ 0:不使用交换分区
├─ 100:积极使用交换分区
└─ 默认:-1(继承主机设置)

内存单位

k或K:千字节(KB)
m或M:兆字节(MB)
g或G:吉字节(GB)

示例:
-m 512m   # 512MB
-m 1g     # 1GB
-m 1073741824  # 1GB(字节)

3.2 CPU限制

3.2.1 CPU限制选项

基本语法

docker run [OPTIONS] IMAGE

OPTIONS:
      --cpus decimal           CPU数量
  -c, --cpu-shares int         CPU权重
      --cpu-period int         CPU周期(微秒)
      --cpu-quota int          CPU配额(微秒)
      --cpuset-cpus string     指定CPU核心
      --cpuset-mems string     指定内存节点

使用示例

# 限制使用1.5个CPU
docker run -d --cpus 1.5 nginx:latest

# 设置CPU权重
docker run -d -c 512 nginx:latest

# 指定使用CPU 0和1
docker run -d --cpuset-cpus 0,1 nginx:latest

# 指定CPU周期和配额
docker run -d --cpu-period 100000 --cpu-quota 50000 nginx:latest

# 指定内存节点
docker run -d --cpuset-mems 0 nginx:latest

3.2.2 CPU限制详解

CPU限制类型

CPU数量(--cpus):
├─ 可使用的CPU核心数
├─ 支持小数
├─ 示例:--cpus 1.5
└─ 推荐:使用此选项

CPU权重(--cpu-shares):
├─ 相对权重(默认1024)
├─ CPU竞争时生效
├─ 不限制绝对使用量
└─ 示例:-c 512

CPU周期和配额:
├─ cpu-period:CFS调度器周期
├─ cpu-quota:可使用的CPU时间
├─ quota/period = CPU核心数
└─ 示例:--cpu-period 100000 --cpu-quota 50000(0.5个CPU)

CPU核心绑定(--cpuset-cpus):
├─ 指定使用的CPU核心
├─ 提高缓存命中率
└─ 示例:--cpuset-cpus 0,1,2,3

3.3 其他资源限制

3.3.1 磁盘IO限制

基本语法

docker run [OPTIONS] IMAGE

OPTIONS:
      --blkio-weight int         块IO权重(10-1000)
      --blkio-weight-device list 设备权重
      --device-read-bps list     设备读取速率限制
      --device-write-bps list    设备写入速率限制
      --device-read-iops list    设备读取IOPS限制
      --device-write-iops list   设备写入IOPS限制

使用示例

# 设置块IO权重
docker run -d --blkio-weight 500 nginx:latest

# 限制读取速率
docker run -d --device-read-bps /dev/sda:10mb nginx:latest

# 限制写入速率
docker run -d --device-write-bps /dev/sda:10mb nginx:latest

# 限制读取IOPS
docker run -d --device-read-iops /dev/sda:1000 nginx:latest

# 限制写入IOPS
docker run -d --device-write-iops /dev/sda:1000 nginx:latest

3.3.2 进程数限制

基本语法

docker run [OPTIONS] IMAGE

OPTIONS:
      --pids-limit int   限制容器进程数

使用示例

# 限制进程数为100
docker run -d --pids-limit 100 nginx:latest

# 不限制进程数
docker run -d --pids-limit -1 nginx:latest

四、容器监控与调试

4.1 查看容器日志

4.1.1 docker logs命令

基本语法

docker logs [OPTIONS] CONTAINER

OPTIONS:
      --details        显示详细信息
  -f, --follow         实时跟踪日志
      --since string   显示指定时间之后的日志
      --tail string    显示最后n行日志
  -t, --timestamps     显示时间戳
      --until string   显示指定时间之前的日志

使用示例

# 查看所有日志
docker logs mynginx

# 实时跟踪日志
docker logs -f mynginx

# 显示最后100行日志
docker logs --tail 100 mynginx

# 显示时间戳
docker logs -t mynginx

# 显示最近1小时的日志
docker logs --since 1h mynginx

# 显示指定时间之后的日志
docker logs --since "2024-01-15T10:00:00" mynginx

# 显示指定时间范围的日志
docker logs --since "2024-01-15T10:00:00" --until "2024-01-15T12:00:00" mynginx

4.1.2 日志驱动

配置日志驱动

# 使用json-file驱动(默认)
docker run -d --log-driver json-file nginx:latest

# 使用syslog驱动
docker run -d --log-driver syslog nginx:latest

# 使用none驱动(不记录日志)
docker run -d --log-driver none nginx:latest

# 配置日志选项
docker run -d \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  nginx:latest

日志驱动类型

json-file(默认):
├─ JSON格式存储
├─ 支持日志轮转
└─ 本地存储

syslog:
├─ 发送到syslog守护进程
├─ 集中式日志管理
└─ 需要syslog服务

journald:
├─ 发送到systemd journal
├─ Linux系统日志
└─ 需要systemd

none:
├─ 不记录日志
└─ 性能最优

fluentd:
├─ 发送到Fluentd
├─ 日志收集和分析
└─ 需要Fluentd服务

4.2 查看容器状态

4.2.1 docker stats命令

基本语法

docker stats [OPTIONS] [CONTAINER...]

OPTIONS:
  -a, --all       显示所有容器(包括停止的)
      --format    格式化输出
      --no-stream 不实时刷新
      --no-trunc  不截断输出

使用示例

# 实时显示所有容器资源使用
docker stats

# 输出示例
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
a1b2c3d4e5f6   mynginx   0.50%     10.5MiB / 512MiB      2.05%     1.2kB / 0B        0B / 0B           2

# 显示指定容器
docker stats mynginx

# 显示所有容器(包括停止的)
docker stats -a

# 不实时刷新
docker stats --no-stream

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

4.2.2 docker top命令

基本语法

docker top CONTAINER [ps OPTIONS]

使用示例

# 查看容器进程
docker top mynginx

# 输出示例
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                12345               12344               0                   10:30               ?                   00:00:00            nginx: master process nginx -g daemon off;
systemd+            12346               12345               0                   10:30               ?                   00:00:00            nginx: worker process

# 使用ps选项
docker top mynginx aux
docker top mynginx -ef

4.3 进入容器

4.3.1 docker exec命令

基本语法

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

OPTIONS:
  -d, --detach        后台运行
      --detach-keys   覆盖分离按键
  -e, --env list      设置环境变量
      --env-file list 从文件读取环境变量
  -i, --interactive   保持STDIN打开
      --privileged    给予扩展权限
  -t, --tty           分配伪TTY
  -u, --user string   用户名或UID
  -w, --workdir string 工作目录

使用示例

# 进入容器交互终端
docker exec -it mynginx bash

# 执行单个命令
docker exec mynginx ls /app

# 以root用户执行
docker exec -u root mynginx id

# 指定工作目录
docker exec -w /app mynginx ls

# 设置环境变量
docker exec -e DEBUG=true mynginx env

# 后台执行命令
docker exec -d mynginx touch /app/test.txt

4.3.2 docker attach命令

基本语法

docker attach [OPTIONS] CONTAINER

OPTIONS:
      --detach-keys   覆盖分离按键
      --no-stdin      不附加STDIN
      --sig-proxy     代理所有信号(默认true

使用示例

# 附加到容器
docker attach mynginx

# 附加但不附加STDIN
docker attach --no-stdin mynginx

# 使用自定义分离按键
docker attach --detach-keys="ctrl-a" mynginx

exec vs attach

docker exec:
├─ 在容器中执行新命令
├─ 创建新进程
├─ 不影响主进程
└─ 推荐:调试和管理

docker attach:
├─ 附加到容器主进程
├─ 不创建新进程
├─ 退出可能影响容器
└─ 用于:查看主进程输出

推荐:
✅ 使用exec进入容器
⚠️ attach用于查看主进程输出

4.4 查看容器详情

4.4.1 docker inspect命令

基本语法

docker inspect [OPTIONS] NAME|ID [NAME|ID...]

OPTIONS:
  -f, --format string 格式化输出
  -s, --size          显示总文件大小
      --type string   返回指定类型

使用示例

# 查看容器详细信息
docker inspect mynginx

# 格式化输出
docker inspect -f '{{.State.Status}}' mynginx
docker inspect -f '{{.NetworkSettings.IPAddress}}' mynginx
docker inspect -f '{{.HostConfig.Memory}}' mynginx

# 查看容器IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mynginx

# 查看容器端口映射
docker inspect -f '{{json .NetworkSettings.Ports}}' mynginx | jq

# 查看容器挂载点
docker inspect -f '{{json .Mounts}}' mynginx | jq

4.4.2 docker diff命令

基本语法

docker diff CONTAINER

使用示例

# 查看容器文件系统变化
docker diff mynginx

# 输出示例
A /app/test.txt      # A:新增
C /etc/nginx/nginx.conf  # C:修改
D /tmp/oldfile.txt   # D:删除

五、本章小结

5.1 核心命令总结

5.1.1 容器生命周期命令

创建与启动:
├─ docker run:创建并启动容器
├─ docker create:创建容器(不启动)
├─ docker start:启动容器
└─ docker restart:重启容器

停止与删除:
├─ docker stop:优雅停止容器
├─ docker kill:强制停止容器
├─ docker pause:暂停容器
├─ docker unpause:恢复容器
└─ docker rm:删除容器

查看与监控:
├─ docker ps:查看容器列表
├─ docker logs:查看容器日志
├─ docker stats:查看资源使用
├─ docker top:查看容器进程
└─ docker inspect:查看容器详情

进入容器:
├─ docker exec:在容器中执行命令
└─ docker attach:附加到容器主进程

5.1.2 资源限制命令

内存限制:
├─ -m, --memory:内存限制
├─ --memory-reservation:内存软限制
├─ --memory-swap:内存+交换分区限制
└─ --memory-swappiness:交换分区使用倾向

CPU限制:
├─ --cpus:CPU数量
├─ -c, --cpu-shares:CPU权重
├─ --cpu-period:CPU周期
├─ --cpu-quota:CPU配额
└─ --cpuset-cpus:指定CPU核心

其他限制:
├─ --blkio-weight:块IO权重
├─ --device-read-bps:读取速率限制
├─ --device-write-bps:写入速率限制
└─ --pids-limit:进程数限制

5.2 最佳实践

5.2.1 容器管理建议

命名规范:
✅ 使用有意义的容器名称
✅ 包含环境、服务、序号
└─ 示例:web-prod-nginx-01

资源限制:
✅ 始终设置资源限制
✅ 根据应用需求合理配置
✅ 监控资源使用情况
✅ 及时调整限制

日志管理:
✅ 配置日志驱动
✅ 设置日志轮转
✅ 集中收集日志
✅ 定期清理日志

监控告警:
✅ 实时监控容器状态
✅ 设置资源告警
✅ 监控容器日志
✅ 定期检查健康状态

5.2.2 常见问题排查

容器无法启动:
├─ 查看日志:docker logs
├─ 检查镜像:docker images
├─ 检查配置:docker inspect
└─ 检查资源:docker stats

容器性能问题:
├─ 检查资源限制
├─ 查看资源使用:docker stats
├─ 查看进程:docker top
└─ 进入容器排查:docker exec

容器网络问题:
├─ 检查端口映射:docker port
├─ 检查网络配置:docker inspect
├─ 测试网络连接
└─ 查看容器日志

容器存储问题:
├─ 检查挂载点:docker inspect
├─ 查看磁盘使用:docker system df
├─ 清理无用数据:docker system prune
└─ 检查文件权限

5.3 下一章预告

下一章:Docker网络

将学习:

  • 🌐 Docker网络模式
  • 🔗 容器间通信
  • 🌍 自定义网络
  • 🔧 网络故障排查

📝 练习题

基础题

  1. 容器操作:创建一个nginx容器,要求:

    • 容器名称为myweb
    • 映射端口8080:80
    • 后台运行
    • 设置重启策略为always
  2. 生命周期管理:练习容器的启动、停止、重启、暂停、恢复操作,观察容器状态变化。

  3. 资源限制:创建一个容器,限制内存为512MB,CPU为0.5核。

进阶题

  1. 日志管理:配置nginx容器的日志驱动为json-file,设置日志文件最大10MB,最多保留3个文件。

  2. 监控调试:使用docker stats监控容器资源使用,使用docker exec进入容器查看进程。

  3. 故障排查:模拟一个容器启动失败的场景,使用docker logs和docker inspect排查问题。

实践题

  1. 完整应用:部署一个完整的Web应用,包括:

    • nginx容器(前端)
    • node.js容器(后端)
    • mysql容器(数据库)
    • 配置网络和资源限制
    • 设置日志收集
  2. 性能优化:为一个高并发应用配置容器资源限制,要求:

    • 合理分配CPU和内存
    • 配置健康检查
    • 设置重启策略
    • 监控资源使用