运行Amazon ECS集群的EBS卷频繁占满如何解决?
问题结论
这个问题不是Amazon ECS不适配你的使用场景,属于EC2启动类型下Docker存储层的典型运维问题,有成熟的根治方案,不需要靠删除集群重建的方式临时恢复。
你遇到的报错信息:
Status reason CannotPullContainerError: write /var/lib/docker/tmp/GetImageBlob059053200: no space left on device
本质是实例上/var/lib/docker所在的磁盘分区被Docker运行产生的冗余数据占满,导致拉取新镜像时没有临时存储空间写入Blob文件。
根因说明
Docker在ECS实例上长期运行时,会持续累积几类不会自动清理的冗余数据:
- 任务迭代后残留的旧版本容器实例、关联的匿名数据卷
- 拉取新版本镜像后遗留的旧版本镜像、悬空镜像(无标签的无效镜像)
- 镜像拉取过程中产生的临时缓存文件
- 容器运行时输出的无轮转限制的JSON格式日志
- 镜像构建过程产生的构建缓存(如果实例上有自定义镜像构建操作)
单纯扩容EBS卷容量只能拉长空间耗尽的周期,无法解决冗余数据持续累积的问题,最终还是会出现空间耗尽的故障。
根治修复方案
紧急恢复(空间已经占满时)
不需要删除重建集群,直接登录对应ECS实例执行以下命令即可立刻释放空间,命令只会清理未被运行中任务关联的冗余数据,不会影响正在运行的业务:docker system prune -af --volumes
执行完成后即可正常启动新任务、拉取新镜像。
长期根治配置
- 配置定期自动清理:在所有ECS容器实例上添加crontab定时任务,选择业务低峰时段(比如每日凌晨2点)自动执行清理命令,示例crontab规则如下,执行日志会输出到指定文件方便排查:
0 2 * * * /usr/bin/docker system prune -af --volumes > /var/log/docker-prune.log 2>&1
如果是通过Auto Scaling组自动扩缩的实例,可以把这条定时配置写在启动模板的用户数据脚本里,保证新扩容的实例自动带上清理规则。 - 配置Docker日志轮转:避免容器日志无限增长占满磁盘,编辑实例上的
/etc/docker/daemon.json文件,添加如下日志限制配置,配置完成后执行systemctl restart docker生效,配置会限制单个容器日志最大100MB,最多保留3份历史日志:
{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } }
- 优化任务拉取策略:如果你的镜像使用版本号做唯一标签(非持续覆盖的固定标签),把任务定义里的镜像拉取策略从默认的
Always调整为IfNotPresent,减少不必要的重复镜像拉取操作,降低冗余缓存产生的概率。 - 存储路径分离:不要把业务持久化数据存储在容器的可写层,持久化数据必须挂载独立的数据卷,不要写入
/var/lib/docker目录对应的系统盘分区,避免业务数据和Docker运行时数据抢占存储空间。 - 配置监控告警:给ECS实例配置磁盘使用率监控,当系统盘(或
/var/lib/docker所在分区)使用率超过70%时触发告警,提前处理异常空间占用,避免出现磁盘完全写死影响业务的情况。
内容的提问来源于stack exchange,提问作者Dimeji
相关产品推荐
相关产品推荐

