Docker 容器维护手册
目录
容器基础操作
查看容器
# 查看运行中的容器
docker ps
# 查看所有容器(包括停止的)
docker ps -a
# 查看容器详细信息
docker inspect <container_id>
# 查看容器资源使用情况
docker stats <container_id>
# 实时查看所有容器资源使用
docker stats
启动和停止
# 启动容器
docker start <container_id>
# 停止容器(优雅关闭,默认10秒超时)
docker stop <container_id>
# 强制停止容器
docker kill <container_id>
# 重启容器
docker restart <container_id>
# 暂停容器
docker pause <container_id>
# 恢复暂停的容器
docker unpause <container_id>
进入容器
# 进入运行中的容器(推荐)
docker exec -it <container_id> /bin/bash
# 如果容器中没有 bash
docker exec -it <container_id> /bin/sh
# 以 root 用户进入
docker exec -it -u root <container_id> /bin/bash
# 执行单个命令
docker exec <container_id> ls -la /app
删除容器
# 删除停止的容器
docker rm <container_id>
# 强制删除运行中的容器
docker rm -f <container_id>
# 删除所有停止的容器
docker container prune
# 删除所有容器(危险操作)
docker rm -f $(docker ps -aq)
镜像管理
查看镜像
# 列出所有镜像
docker images
# 查看镜像详细信息
docker inspect <image_id>
# 查看镜像历史层
docker history <image_name>
# 查看镜像占用空间
docker system df
拉取和推送
# 从仓库拉取镜像
docker pull <image_name>:<tag>
# 拉取特定版本
docker pull nginx:1.21.6
# 推送镜像到仓库
docker push <image_name>:<tag>
# 登录镜像仓库
docker login
# 登出
docker logout
构建镜像
# 从 Dockerfile 构建
docker build -t <image_name>:<tag> .
# 指定 Dockerfile 路径
docker build -f /path/to/Dockerfile -t <image_name> .
# 不使用缓存构建
docker build --no-cache -t <image_name> .
# 使用构建参数
docker build --build-arg VERSION=1.0 -t <image_name> .
镜像操作
# 给镜像打标签
docker tag <source_image> <target_image>:<tag>
# 保存镜像为 tar 文件
docker save -o image.tar <image_name>
# 从 tar 文件加载镜像
docker load -i image.tar
# 删除镜像
docker rmi <image_id>
# 删除所有未使用的镜像
docker image prune -a
# 删除悬空镜像(dangling images)
docker image prune
容器监控
实时监控
# 查看容器 CPU、内存、网络、IO 使用情况
docker stats <container_id>
# 监控所有容器
docker stats
# 以 JSON 格式输出(便于解析)
docker stats --format "{{json .}}" --no-stream
进程查看
# 查看容器内运行的进程
docker top <container_id>
# 查看容器内进程详细信息
docker top <container_id> aux
事件监控
# 实时查看 Docker 事件
docker events
# 过滤特定容器的事件
docker events --filter container=<container_name>
# 过滤特定类型的事件
docker events --filter event=start --filter event=stop
日志管理
查看日志
# 查看容器日志
docker logs <container_id>
# 实时跟踪日志(类似 tail -f)
docker logs -f <container_id>
# 查看最后 100 行日志
docker logs --tail 100 <container_id>
# 查看带时间戳的日志
docker logs -t <container_id>
# 查看指定时间范围的日志
docker logs --since 2024-01-01T00:00:00 <container_id>
docker logs --since 30m <container_id>
日志驱动配置
# 启动容器时指定日志驱动
docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 <image>
# 配置日志轮转
docker run \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=5 \
<image>
清理日志
# 清理容器日志文件(需要 root 权限)
truncate -s 0 /var/lib/docker/containers/<container_id>/<container_id>-json.log
# 或使用
echo "" > $(docker inspect --format='{{.LogPath}}' <container_id>)
网络管理
网络查看
# 列出所有网络
docker network ls
# 查看网络详细信息
docker network inspect <network_name>
# 查看容器的网络配置
docker inspect -f '{{.NetworkSettings.Networks}}' <container_id>
网络操作
# 创建自定义网络
docker network create <network_name>
# 创建指定子网的网络
docker network create --subnet=172.18.0.0/16 <network_name>
# 连接容器到网络
docker network connect <network_name> <container_id>
# 断开容器与网络的连接
docker network disconnect <network_name> <container_id>
# 删除网络
docker network rm <network_name>
# 清理未使用的网络
docker network prune
端口映射
# 查看容器端口映射
docker port <container_id>
# 启动容器时映射端口
docker run -p 8080:80 <image>
# 映射到指定 IP
docker run -p 127.0.0.1:8080:80 <image>
# 映射所有暴露的端口到随机端口
docker run -P <image>
数据卷管理
卷操作
# 列出所有卷
docker volume ls
# 查看卷详细信息
docker volume inspect <volume_name>
# 创建卷
docker volume create <volume_name>
# 删除卷
docker volume rm <volume_name>
# 清理未使用的卷
docker volume prune
# 查看卷占用空间
docker system df -v
使用数据卷
# 使用命名卷
docker run -v <volume_name>:/path/in/container <image>
# 使用绑定挂载(bind mount)
docker run -v /host/path:/container/path <image>
# 只读挂载
docker run -v /host/path:/container/path:ro <image>
# 使用匿名卷
docker run -v /container/path <image>
备份和恢复卷
# 备份卷数据
docker run --rm -v <volume_name>:/source -v $(pwd):/backup alpine tar czf /backup/volume-backup.tar.gz -C /source .
# 恢复卷数据
docker run --rm -v <volume_name>:/target -v $(pwd):/backup alpine tar xzf /backup/volume-backup.tar.gz -C /target
资源限制
CPU 限制
# 限制 CPU 份额(相对权重)
docker run --cpu-shares 512 <image>
# 限制可使用的 CPU 核心数
docker run --cpus 1.5 <image>
# 指定使用特定的 CPU 核心
docker run --cpuset-cpus 0,1 <image>
# 更新运行中容器的 CPU 限制
docker update --cpus 2 <container_id>
内存限制
# 限制内存使用
docker run -m 512m <image>
# 限制内存和交换空间总和
docker run -m 512m --memory-swap 1g <image>
# 禁用交换空间
docker run -m 512m --memory-swap 512m <image>
# 内存预留(软限制)
docker run --memory-reservation 256m <image>
# 更新运行中容器的内存限制
docker update -m 1g <container_id>
IO 限制
# 限制块设备读取速率(字节/秒)
docker run --device-read-bps /dev/sda:1mb <image>
# 限制块设备写入速率
docker run --device-write-bps /dev/sda:1mb <image>
# 限制 IOPS
docker run --device-read-iops /dev/sda:1000 <image>
其他限制
# 限制进程数
docker run --pids-limit 100 <image>
# 限制文件描述符数量
docker run --ulimit nofile=1024:1024 <image>
# 设置重启策略
docker run --restart unless-stopped <image>
docker run --restart on-failure:5 <image>
备份与恢复
容器备份
# 将容器提交为镜像
docker commit <container_id> backup-image:tag
# 导出容器文件系统
docker export <container_id> > container-backup.tar
# 保存镜像
docker save -o image-backup.tar <image_name>
容器恢复
# 从 tar 文件导入容器
docker import container-backup.tar restored-image:tag
# 加载镜像
docker load -i image-backup.tar
# 从备份镜像创建新容器
docker run -d backup-image:tag
完整备份脚本示例
#!/bin/bash
# 备份指定容器
CONTAINER_NAME=$1
BACKUP_DIR="/backup/docker"
DATE=$(date +%Y%m%d_%H%M%S)
# 创建备份目录
mkdir -p $BACKUP_DIR
# 备份容器配置
docker inspect $CONTAINER_NAME > $BACKUP_DIR/${CONTAINER_NAME}_config_${DATE}.json
# 提交容器为镜像
docker commit $CONTAINER_NAME ${CONTAINER_NAME}_backup:${DATE}
# 导出镜像
docker save -o $BACKUP_DIR/${CONTAINER_NAME}_${DATE}.tar ${CONTAINER_NAME}_backup:${DATE}
# 备份数据卷
VOLUMES=$(docker inspect -f '{{range .Mounts}}{{.Name}} {{end}}' $CONTAINER_NAME)
for vol in $VOLUMES; do
docker run --rm -v $vol:/source -v $BACKUP_DIR:/backup alpine \
tar czf /backup/${vol}_${DATE}.tar.gz -C /source .
done
echo "备份完成: $BACKUP_DIR"
故障排查
容器无法启动
# 查看容器日志
docker logs <container_id>
# 查看容器退出码
docker inspect <container_id> | grep ExitCode
# 查看容器启动命令
docker inspect -f '{{.Config.Cmd}}' <container_id>
# 尝试交互式运行查看错误
docker run -it <image> /bin/bash
# 查看 Docker 守护进程日志
journalctl -u docker.service
# 或
tail -f /var/log/docker.log
网络问题
# 检查容器 IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_id>
# 测试容器间连通性
docker exec <container_id> ping <target_ip>
# 检查 DNS 解析
docker exec <container_id> nslookup google.com
# 查看 iptables 规则
sudo iptables -L -n -v
# 检查端口监听
docker exec <container_id> netstat -tunlp
性能问题
# 查看资源使用
docker stats <container_id>
# 查看容器进程
docker top <container_id>
# 进入容器诊断
docker exec -it <container_id> /bin/bash
# 使用 htop 查看(如果安装)
docker exec -it <container_id> htop
# 检查磁盘使用
docker exec <container_id> df -h
磁盘空间问题
# 查看 Docker 磁盘使用
docker system df
# 详细查看
docker system df -v
# 清理未使用的资源
docker system prune
# 清理所有未使用的资源(包括未使用的镜像)
docker system prune -a
# 清理构建缓存
docker builder prune
安全加固
用户权限
# 以非 root 用户运行容器
docker run -u 1000:1000 <image>
# 在 Dockerfile 中指定用户
USER appuser
# 禁用特权模式(默认已禁用)
# 避免使用 --privileged
# 限制容器能力
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE <image>
只读文件系统
# 以只读根文件系统运行
docker run --read-only <image>
# 只读根文件系统 + 可写临时目录
docker run --read-only --tmpfs /tmp <image>
安全扫描
# 使用 Docker 官方扫描(需要登录)
docker scan <image_name>
# 使用 Trivy 扫描镜像漏洞
trivy image <image_name>
# 使用 Grype 扫描
grype <image_name>
资源隔离
# 使用安全计算模式
docker run --security-opt seccomp=/path/to/seccomp/profile.json <image>
# 使用 AppArmor
docker run --security-opt apparmor=docker-default <image>
# 禁用进程间通信
docker run --ipc private <image>
# 使用用户命名空间
docker run --userns host <image>
镜像签名验证
# 启用 Docker Content Trust
export DOCKER_CONTENT_TRUST=1
# 拉取已签名的镜像
docker pull <image_name>
# 查看镜像签名
docker trust inspect <image_name>
性能优化
镜像优化
# 使用更小的基础镜像
FROM alpine:3.18
# 合并 RUN 命令减少层数
RUN apt-get update && \
apt-get install -y package1 package2 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 使用多阶段构建
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
FROM alpine:3.18
COPY --from=builder /app/myapp /usr/local/bin/
CMD ["myapp"]
# 使用 .dockerignore 排除不需要的文件
容器运行优化
# 设置合理的重启策略
docker run --restart unless-stopped <image>
# 使用健康检查
docker run --health-cmd "curl -f http://localhost/ || exit 1" \
--health-interval 30s \
--health-timeout 3s \
--health-retries 3 \
<image>
# 优化日志配置
docker run --log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
<image>
网络优化
# 使用 host 网络模式(性能最佳,但隔离性最差)
docker run --network host <image>
# 使用自定义网络(比默认 bridge 性能更好)
docker network create --driver bridge my-network
docker run --network my-network <image>
# 禁用不需要的网络功能
docker run --network none <image>
存储优化
# 使用数据卷而非绑定挂载(性能更好)
docker run -v myvolume:/data <image>
# 选择合适的存储驱动
# 在 /etc/docker/daemon.json 中配置
{
"storage-driver": "overlay2"
}
# 使用 tmpfs 挂载临时数据
docker run --tmpfs /tmp:rw,size=1g <image>
常见问题
Q: 容器中的时区不正确
# 方法1:挂载主机时区文件
docker run -v /etc/localtime:/etc/localtime:ro <image>
# 方法2:设置环境变量
docker run -e TZ=Asia/Shanghai <image>
# 方法3:在 Dockerfile 中设置
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
Q: 容器内无法解析域名
# 检查 DNS 配置
docker exec <container_id> cat /etc/resolv.conf
# 指定 DNS 服务器
docker run --dns 8.8.8.8 --dns 114.114.114.114 <image>
# 在 daemon.json 中全局配置
{
"dns": ["8.8.8.8", "114.114.114.114"]
}
Q: 容器磁盘空间不足
# 检查磁盘使用
docker system df
# 清理未使用的资源
docker system prune -a --volumes
# 增加 Docker 数据目录大小或迁移到更大的磁盘
# 修改 /etc/docker/daemon.json
{
"data-root": "/new/path/docker"
}
Q: 容器启动后立即退出
# 查看退出原因
docker logs <container_id>
# 查看退出码
docker inspect <container_id> | grep ExitCode
# 常见退出码:
# 0: 正常退出
# 1: 应用错误
# 137: 被 SIGKILL 杀死(内存不足)
# 139: 段错误
# 143: 被 SIGTERM 终止
Q: 无法连接到 Docker 守护进程
# 检查 Docker 服务状态
sudo systemctl status docker
# 启动 Docker 服务
sudo systemctl start docker
# 将用户添加到 docker 组
sudo usermod -aG docker $USER
# 重新登录使组权限生效
Q: 容器内存溢出被杀死
# 查看容器是否因 OOM 被杀
docker inspect <container_id> | grep OOMKilled
# 增加内存限制
docker update -m 2g <container_id>
# 或重新创建容器
docker run -m 2g <image>
# 查看内存使用情况
docker stats <container_id>
最佳实践总结
日常维护清单
安全建议
- 不要以 root 用户运行容器
- 使用最小权限原则
- 定期扫描镜像漏洞
- 使用可信的基础镜像
- 限制容器资源使用
- 使用私有镜像仓库
- 启用 Docker Content Trust
- 定期更新 Docker 版本
性能建议
- 使用多阶段构建减小镜像体积
- 合理配置日志轮转
- 使用合适的存储驱动
- 为高频访问数据使用数据卷
- 配置合理的资源限制
- 使用健康检查确保服务可用
- 监控容器性能指标
有用的脚本
批量停止容器
#!/bin/bash
# 停止所有运行中的容器
docker stop $(docker ps -q)
清理悬空资源
#!/bin/bash
# 清理所有悬空的镜像、容器、网络和卷
docker system prune -a --volumes -f
监控容器状态
#!/bin/bash
# 检查容器是否运行,如果停止则重启
CONTAINER_NAME=$1
if [ ! "$(docker ps -q -f name=$CONTAINER_NAME)" ]; then
if [ "$(docker ps -aq -f status=exited -f name=$CONTAINER_NAME)" ]; then
echo "容器 $CONTAINER_NAME 已停止,正在重启..."
docker start $CONTAINER_NAME
else
echo "容器 $CONTAINER_NAME 不存在"
fi
else
echo "容器 $CONTAINER_NAME 正在运行"
fi
批量更新容器
#!/bin/bash
# 更新所有容器到最新镜像
for container in $(docker ps --format '{{.Names}}'); do
image=$(docker inspect --format='{{.Config.Image}}' $container)
echo "更新容器: $container (镜像: $image)"
docker pull $image
docker stop $container
docker rm $container
docker run -d --name $container $image
done
参考资源