背景
那是一个平静的凌晨3点,菜鸟小王正在睡梦中。突然,手机剧烈地震动起来——生产环境的磁盘告警!
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 100G 91G 9G 91% /
91%的磁盘使用率,意味着系统已经处于危险边缘。菜鸟立即打开笔记本,通过SSH连接到服务器。
ubuntu@localhost:~$ docker system df -v
Images space usage:
REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS
xxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/hello-front 11.05.12 f2e43csd7bf3 4 weeks ago 941MB 908.8MB 32.53MB 1
Containers space usage:
CONTAINER ID IMAGE COMMAND LOCAL VOLUMES SIZE CREATED STATUS NAMES
7d62a35be571 xxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/hello-front:11.05.12 "docker-entrypoint.s…" 0 81.21GB 4 weeks ago Up 8 hours hello-front
Local Volumes space usage:
VOLUME NAME LINKS SIZE
Build cache usage: 0B
CACHE ID CACHE TYPE SIZE CREATED LAST USED USAGE SHARED
此时小王首先需要解决的任务是: 1. 清理镜像以释放磁盘空间。 2. 尽可能短时间内完成服务重启,避免对用户造成影响。
探索的解决方案
方法一:最基础的容器替换
docker ps
docker stop hello-front
docker rm 8a78931d9e74
docker compose up -d chat-front
docker system df -v
效果:小王通过简单的docker stop和docker rm,手动移除旧容器并启动新服务。这种方法虽然直观,但过程稍显繁琐,对服务中断时间没有明显优化。
方法二:通过docker compose down重启
docker compose down hello-front && docker compose up -d hello-front
效果:小王发现使用docker compose down可以优雅地停止相关服务并清理旧容器。然而,这种方法对复杂环境可能造成较大中断,因为它会停止整个服务栈。
方法三:强制重建容器
docker compose up -d --force-recreate hello-front
效果:--force-recreate选项成为小王的最爱!它无需停止其他无关服务,直接重建指定服务容器,既保留了上下文环境,又将服务中断时间降到了最低。
最终优化方案 基于以上尝试,小王总结了一套优化流程:
分析磁盘使用情况:使用docker system df -v
了解镜像膨胀的根源。
提前构建镜像:利用CI/CD管道提前构建优化后的镜像。
平滑重启服务:采用docker compose up -d --force-recreate
实现无缝切换。
清理旧资源:通过docker system prune
定期清理无用镜像和容器。
完整流程如下:
docker system df -v
docker compose up -d --force-recreate hello-front
docker system prune -f
总结
通过对生产环境中镜像膨胀问题的深入研究,菜鸟小王成功减少了重建过程的服务中断时间,并总结出一套适用于大多数生产环境的优化方案。如果你也面临类似问题,不妨尝试以上方法