GitLab CI执行后残留<none>标签Docker镜像占用存储如何解决
问题原因
标签为<none>的残留镜像属于悬空镜像(dangling images),产生原因是每次执行docker build时,新镜像生成后旧镜像的同名标签会被转移到新镜像上,旧镜像层就会丢失标签变成<none>;默认情况下GitLab Runner执行CI任务时,只会删除任务产生的临时容器,不会自动清理构建过程中生成的悬空镜像、未被引用的临时存储卷,长期运行就会占用大量磁盘空间。
解决方案
提供两种可落地的方案,可根据实际场景选择:
方案1:在CI流程末尾添加自动清理任务(推荐,单项目生效)
在现有流水线最后新增一个cleanup阶段,给清理任务配置when: always规则,无论前面的构建、测试任务成功、失败还是被取消,都会执行清理操作。
清理逻辑说明
docker image prune -f:仅删除所有标签为<none>的悬空镜像,不会影响正常打标签的业务镜像- 如需同时清理已退出的临时容器、未被使用的网络、无主的存储卷,可以替换为
docker system prune -f --volumes - 如果需要保留近期构建缓存提升后续构建速度,可以添加
until过滤规则,例如仅清理2小时前生成的悬空镜像:docker image prune -f --filter "until=2h"
修改后的完整.gitlab-ci.yml参考如下:
variables: GIT_SUBMODULE_STRATEGY: recursive stages: - build - test - cleanup # 新增清理阶段,放在所有业务阶段最后 build image: stage: build image: docker:20.10.16 services: - docker:dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker pull $CI_REGISTRY_IMAGE - docker build --cache-from $CI_REGISTRY_IMAGE -t $CI_REGISTRY_IMAGE . - docker push $CI_REGISTRY_IMAGE run-tests: stage: test image: $CI_REGISTRY_IMAGE script: - source /app/venv/bin/activate && pytest . # 新增清理任务 ci-job-cleanup: stage: cleanup image: docker:20.10.16 services: - docker:dind when: always script: # 基础清理:仅删除悬空<none>镜像 - docker image prune -f # 如需保留2小时内的构建缓存,用下面的命令替换上面的prune命令 # - docker image prune -f --filter "until=2h" # 如需深度清理(删除停止容器、无主卷、未使用网络),替换为下面的命令 # - docker system prune -f --volumes
方案2:配置Runner全局定期清理(所有项目生效,无需修改CI配置)
如果本地Runner承载了多个项目的CI任务,不想逐个项目修改CI配置,可以在Runner部署侧配置全局清理规则:
- 定时任务清理(最简单)
在运行GitLab Runner的宿主机上添加crontab定时任务,例如每天凌晨2点执行一次全量清理:
该命令不会影响正在运行的CI任务,也不会删除带正常标签的业务镜像。# 编辑crontab配置 crontab -e # 添加以下定时规则,每天2点清理24小时前的无用Docker资源 0 2 * * * /usr/bin/docker system prune -f --volumes --filter "until=24h" - Runner内置清理配置
打开Runner的配置文件config.toml(容器化部署的Runner一般挂载在宿主机/etc/gitlab-runner/config.toml路径),找到对应Runner的[runners.docker]配置段,开启自动删除临时容器参数:[runners.docker] # 每次任务结束自动删除任务关联的临时容器 autoremove = true volumes = ["/cache"]
注意事项
- 不建议在
build阶段刚完成镜像push就立刻执行prune,提前清理可能导致后续测试阶段需要重新拉取镜像,拉长流水线运行时间 docker system prune默认不会删除带正常标签的镜像、正在运行的容器,常规使用不会出现误删业务资源的问题
内容的提问来源于stack exchange,提问作者Rickj
相关产品推荐
相关产品推荐

