需求:适用于Linux自托管代理VM的PowerShell脚本——自动保留最新10个Docker镜像并清理其余(支持Azure Pipeline AZ CLI内联脚本执行)
嘿,刚好之前在团队的Linux自托管代理上实现过类似的镜像清理需求,给你整理了一套完整的方案,分脚本实现和Azure Pipeline集成两部分:
一、PowerShell脚本核心逻辑
这个脚本会基于镜像的创建时间排序,自动保留最新的10个,删除其余的。同时加了个小判断,避免误删正在被容器使用的镜像(如果你的场景不需要,可以去掉这部分):
# 获取所有Docker镜像,按创建时间降序排序 $allImages = docker images --format "{{.ID}} {{.CreatedAt}}" | Sort-Object -Descending {[datetime]$_ -split ' ' | Select-Object -First 1} # 提取要保留的最新10个镜像ID $keepImageIds = $allImages | Select-Object -First 10 | ForEach-Object { ($_ -split ' ')[0] } # 遍历所有镜像,删除不在保留列表里的 foreach ($imageLine in $allImages) { $imageId = ($imageLine -split ' ')[0] if ($keepImageIds -notcontains $imageId) { # 检查是否有容器在使用该镜像 $usedByContainers = docker ps -a --filter "ancestor=$imageId" --format "{{.ID}}" if (-not $usedByContainers) { Write-Host "正在删除镜像: $imageId" docker rmi -f $imageId } else { Write-Host "镜像 $imageId 被容器占用,跳过删除" } } }
脚本说明:
- 用
docker images的格式化输出获取镜像ID和创建时间,避免解析默认表格格式的麻烦 - 排序的时候把创建时间转成datetime类型,确保排序逻辑准确
- 增加了容器占用检查,防止删除正在运行/暂停的容器依赖的镜像,如果你确定代理上没有长期运行的容器,可以把这部分判断去掉,直接执行删除
二、Azure Pipeline中集成执行
因为是Linux自托管代理,推荐用PowerShell任务(指定使用pwsh,也就是PowerShell Core)来执行,比AZ CLI内联脚本更直接。下面是Pipeline YAML的示例:
steps: - task: PowerShell@2 displayName: '清理Docker镜像(保留最新10个)' inputs: targetType: 'inline' script: | # 这里粘贴上面的完整脚本内容 $allImages = docker images --format "{{.ID}} {{.CreatedAt}}" | Sort-Object -Descending {[datetime]$_ -split ' ' | Select-Object -First 1} $keepImageIds = $allImages | Select-Object -First 10 | ForEach-Object { ($_ -split ' ')[0] } foreach ($imageLine in $allImages) { $imageId = ($imageLine -split ' ')[0] if ($keepImageIds -notcontains $imageId) { $usedByContainers = docker ps -a --filter "ancestor=$imageId" --format "{{.ID}}" if (-not $usedByContainers) { Write-Host "正在删除镜像: $imageId" docker rmi -f $imageId } else { Write-Host "镜像 $imageId 被容器占用,跳过删除" } } } pwsh: true condition: succeededOrFailed() # 不管之前任务成功失败都执行,避免代理磁盘满
注意事项:
- 确保你的自托管代理用户已经加入
docker组,否则执行docker命令会有权限问题,可以用sudo usermod -aG docker $USER提前配置 - 首次运行前可以把
docker rmi -f $imageId改成Write-Host "将要删除镜像: $imageId",先验证要删除的列表是否符合预期 - 如果需要保留特定的基础镜像(比如
ubuntu:latest),可以在获取$allImages的时候加过滤,比如docker images --format "{{.ID}} {{.CreatedAt}} {{.Repository}}" | Where-Object { $_ -notmatch 'ubuntu:latest' }
内容的提问来源于stack exchange,提问作者OoO
相关产品推荐
相关产品推荐

