Docker 容器管理

核心知识点

1. 容器生命周期

容器的完整生命周期包括以下阶段:

┌─────────────────────────────────────────────────────────────┐
│                   容器生命周期                          │
├─────────────────────────────────────────────────────────────┤
│                                                      │
│   Created ──> Running ──> Paused ──> Running       │
│      │           │            │                        │
│      │           └──> Stopped ───> Removed          │
│      │                 │                             │
│      └─────────────────┘                             │
│                                                      │
└─────────────────────────────────────────────────────────────┘

2. 容器创建与运行

2.1 docker run 命令详解

# 基本语法
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

# 常用选项
-d, --detach          # 后台运行容器
-i, --interactive     # 保持标准输入打开
-t, --tty           # 分配伪终端
--name               # 指定容器名称
-p, --publish       # 端口映射(主机端口:容器端口)
-v, --volume       # 挂载数据卷
-e, --env         # 设置环境变量
--rm               # 容器退出时自动删除
--restart          # 重启策略
--cpus            # 限制 CPU 使用量
--memory          # 限制内存使用量
--network         # 指定网络模式

2.2 运行容器示例

# 交互式运行容器
docker run -it ubuntu:20.04 /bin/bash

# 后台运行容器
docker run -d --name my-nginx nginx:latest

# 端口映射
docker run -d -p 8080:80 --name web-server nginx:latest

# 挂载数据卷
docker run -d -v /host/data:/container/data --name data-container ubuntu:latest

# 设置环境变量
docker run -d -e MYSQL_ROOT_PASSWORD=password --name mysql mysql:5.7

# 限制资源
docker run -d --cpus="0.5" --memory="512m" --name limited-app nginx:latest

# 自动删除
docker run --rm --name temp-container alpine echo "Hello World"

# 指定重启策略
docker run -d --restart=always --name persistent-app nginx:latest

3. 容器状态管理

3.1 查看容器

# 查看运行中的容器
docker ps

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

# 查看最近创建的容器
docker ps -l

# 查看最近 N 个容器
docker ps -n 5

# 只显示容器 ID
docker ps -q

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

# 查看容器大小
docker ps -s

3.2 查看容器详细信息

# 查看容器详细信息
docker inspect my-nginx

# 查看容器 IP 地址
docker inspect my-nginx | grep IPAddress

# 查看容器挂载信息
docker inspect my-nginx | grep -A 10 Mounts

# 查看容器网络配置
docker inspect my-nginx | grep -A 20 NetworkSettings

# 查看 JSON 格式的详细信息
docker inspect --format='{{json .State}}' my-nginx | jq

3.3 查看容器日志

# 查看容器日志
docker logs my-nginx

# 实时跟踪日志
docker logs -f my-nginx

# 显示最后 N 行
docker logs --tail 100 my-nginx

# 显示最近的时间戳日志
docker logs --since 2024-01-01T00:00:00 my-nginx

# 显示带时间戳的日志
docker logs -t my-nginx

# 组合使用
docker logs -f --tail 50 -t my-nginx

4. 容器控制

4.1 启动与停止

# 启动已停止的容器
docker start my-nginx

# 停止运行中的容器
docker stop my-nginx

# 强制停止容器
docker kill my-nginx

# 重启容器
docker restart my-nginx

# 暂停容器
docker pause my-nginx

# 恢复暂停的容器
docker unpause my-nginx

4.2 容器重启策略

# 重启策略选项
no              # 不自动重启(默认)
on-failure      # 仅在失败时重启
always          # 总是重启
unless-stopped  # 总是重启,除非手动停止

# 创建时设置重启策略
docker run -d --restart=always --name myapp nginx:latest

# 修改现有容器的重启策略
docker update --restart=on-failure:3 myapp

# 查看重启策略
docker inspect myapp | grep -A 5 RestartPolicy

5. 容器交互

5.1 进入运行中的容器

# 使用 exec 进入容器(推荐)
docker exec -it my-nginx /bin/bash

# 使用 attach 附加到容器
docker attach my-nginx

# 在容器中执行单个命令
docker exec my-nginx ls -la

# 以特定用户执行命令
docker exec -u root my-nginx whoami

# 在特定工作目录执行命令
docker exec -w /tmp my-nginx pwd

5.2 容器与主机之间传输文件

# 从主机复制文件到容器
docker cp /host/file.txt my-nginx:/container/file.txt

# 从容器复制文件到主机
docker cp my-nginx:/container/file.txt /host/file.txt

# 复制目录
docker cp -r /host/dir my-nginx:/container/dir

# 从容器复制目录
docker cp -r my-nginx:/container/dir /host/dir

6. 容器资源管理

6.1 CPU 限制

# 限制 CPU 使用量(0.5 表示 50%)
docker run -d --cpus="0.5" --name cpu-limited nginx:latest

# 限制 CPU 核心数
docker run -d --cpuset-cpus="0-2" --name cpu-pinned nginx:latest

# 设置 CPU 权重(相对权重)
docker run -d --cpu-shares=512 --name cpu-weighted nginx:latest

# 组合使用
docker run -d \
    --cpus="1.5" \
    --cpuset-cpus="0,1" \
    --cpu-shares=1024 \
    --name cpu-optimized \
    nginx:latest

6.2 内存限制

# 限制内存使用
docker run -d --memory="512m" --name memory-limited nginx:latest

# 限制内存和交换空间
docker run -d \
    --memory="512m" \
    --memory-swap="1g" \
    --name memory-swap \
    nginx:latest

# 禁用交换空间
docker run -d \
    --memory="512m" \
    --memory-swap="512m" \
    --name no-swap \
    nginx:latest

# 限制内存保留
docker run -d \
    --memory="512m" \
    --memory-reservation="256m" \
    --name memory-reservation \
    nginx:latest

6.3 磁盘 I/O 限制

# 限制读取速率
docker run -d \
    --device-read-bps /dev/sda:1mb \
    --name io-read-limited \
    nginx:latest

# 限制写入速率
docker run -d \
    --device-write-bps /dev/sda:1mb \
    --name io-write-limited \
    nginx:latest

# 限制 IOPS
docker run -d \
    --device-read-iops /dev/sda:1000 \
    --device-write-iops /dev/sda:1000 \
    --name io-iops-limited \
    nginx:latest

7. 容器监控

7.1 实时监控

# 查看容器资源使用情况
docker stats

# 查看特定容器
docker stats my-nginx

# 只显示一次结果
docker stats --no-stream

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

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

7.2 容器事件

# 查看容器事件
docker events

# 查看最近的事件
docker events --since 1h

# 过滤特定容器的事件
docker events --filter container=my-nginx

# 过滤特定类型的事件
docker events --filter event=start
docker events --filter event=stop
docker events --filter event=die

# 持续监控
docker events --since $(date +%s)

8. 容器删除

8.1 删除单个容器

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

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

# 删除容器并删除关联的匿名卷
docker rm -v my-nginx

# 删除容器并删除链接
docker rm --link my-link my-nginx

8.2 批量删除容器

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

# 删除所有容器(包括运行中的)
docker rm -f $(docker ps -aq)

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

# 按模式删除容器
docker rm $(docker ps -aq -f name=myapp*)

# 删除所有退出的容器
docker container prune -f

实用案例分析

案例 1:部署多容器 Web 应用

场景描述

部署一个包含 Nginx、PHP 和 MySQL 的多容器 Web 应用。

操作步骤

# 1. 创建网络
docker network create my-web-app

# 2. 启动 MySQL 容器
docker run -d \
    --name mysql \
    --network my-web-app \
    -e MYSQL_ROOT_PASSWORD=rootpassword \
    -e MYSQL_DATABASE=myapp \
    -e MYSQL_USER=myapp \
    -e MYSQL_PASSWORD=password \
    -v mysql-data:/var/lib/mysql \
    mysql:5.7

# 3. 启动 PHP-FPM 容器
docker run -d \
    --name php-fpm \
    --network my-web-app \
    -v php-code:/var/www/html \
    php:7.4-fpm

# 4. 启动 Nginx 容器
docker run -d \
    --name nginx \
    --network my-web-app \
    -p 80:80 \
    -v php-code:/var/www/html \
    -v nginx-config:/etc/nginx/conf.d \
    nginx:latest

# 5. 查看容器状态
docker ps

# 6. 查看网络连接
docker network inspect my-web-app

# 7. 测试连接
docker exec nginx ping php-fpm
docker exec php-fpm ping mysql

# 8. 查看容器日志
docker logs nginx
docker logs php-fpm
docker logs mysql

# 9. 清理
docker stop nginx php-fpm mysql
docker rm nginx php-fpm mysql
docker network rm my-web-app

案例 2:容器资源限制与监控

场景描述

为容器设置资源限制并监控其使用情况。

操作步骤

# 1. 创建测试容器(无限制)
docker run -d --name unlimited-app nginx:latest

# 2. 创建测试容器(有资源限制)
docker run -d \
    --name limited-app \
    --cpus="0.5" \
    --memory="256m" \
    --memory-swap="256m" \
    nginx:latest

# 3. 查看容器资源使用
docker stats unlimited-app limited-app --no-stream

# 4. 持续监控
docker stats unlimited-app limited-app

# 5. 查看容器详细信息
docker inspect limited-app | grep -A 10 "Memory"
docker inspect limited-app | grep -A 5 "CpuShares"

# 6. 动态调整资源限制
docker update --cpus="1.0" --memory="512m" limited-app

# 7. 验证更新
docker inspect limited-app | grep -A 10 "Memory"

# 8. 清理
docker stop unlimited-app limited-app
docker rm unlimited-app limited-app

案例 3:容器自动重启策略

场景描述

测试不同的重启策略,确保应用的高可用性。

操作步骤

# 1. 创建测试脚本
cat > /tmp/test-app.sh << 'EOF'
#!/bin/bash
echo "App started at $(date)"
sleep 10
echo "App crashed at $(date)"
exit 1
EOF
chmod +x /tmp/test-app.sh

# 2. 创建测试镜像
cat > /tmp/Dockerfile << 'EOF'
FROM alpine:latest
COPY test-app.sh /app/
CMD ["/app/test-app.sh"]
EOF
docker build -t test-app /tmp

# 3. 测试 no 重启策略
docker run -d --restart=no --name test-no test-app
sleep 15
docker ps -a | grep test-no

# 4. 测试 on-failure 重启策略
docker run -d --restart=on-failure:3 --name test-on-failure test-app
sleep 40
docker ps -a | grep test-on-failure

# 5. 测试 always 重启策略
docker run -d --restart=always --name test-always test-app
sleep 15
docker ps | grep test-always

# 6. 测试 unless-stopped 重启策略
docker run -d --restart=unless-stopped --name test-unless-stopped test-app
docker stop test-unless-stopped
docker start test-unless-stopped
docker ps | grep test-unless-stopped

# 7. 查看重启次数
docker inspect test-on-failure | grep RestartCount

# 8. 清理
docker stop test-no test-on-failure test-always test-unless-stopped
docker rm test-no test-on-failure test-always test-unless-stopped
docker rmi test-app

最佳实践

  1. 使用有意义的容器名称:便于识别和管理容器。

  2. 合理设置资源限制:防止单个容器耗尽系统资源。

  3. 使用数据卷持久化数据:避免容器删除后数据丢失。

  4. 定期清理未使用的容器:释放系统资源。

# 清理所有停止的容器
docker container prune -f

# 清理所有未使用的资源
docker system prune -a -f
  1. 监控容器状态:及时发现和解决问题。
# 查看所有容器状态
docker ps -a

# 查看容器资源使用
docker stats

# 查看容器日志
docker logs -f container-name
  1. 使用健康检查:确保容器正常运行。
# 创建带健康检查的容器
docker run -d \
    --name health-check \
    --health-cmd="curl -f http://localhost/ || exit 1" \
    --health-interval=30s \
    --health-timeout=3s \
    --health-retries=3 \
    nginx:latest

# 查看健康状态
docker inspect health-check | grep -A 10 Health

总结

本教程详细介绍了 Docker 容器的生命周期管理,包括创建、启动、停止、删除等操作。通过实际案例,我们学习了如何部署多容器应用、设置资源限制以及配置重启策略。掌握这些技能后,可以高效地管理和维护 Docker 容器。

« 上一篇 Docker 镜像管理 下一篇 » Docker 网络配置