容器运行时云原生【免费下载链接】docker-ce:warning: This repository is deprecated and will be archived (Docker CE itself is NOT deprecated) see the https://github.com/docker/docker-ce/blob/master/README.md :warning:项目地址https://gitcode.com/gh_mirrors/do/docker-ce点击查看免费下载本篇技术指南以 Docker CE 官方 CLI 参考文档中volume prune为核心系统讲解如何批量删除未被任何容器引用的本地卷local volumes涵盖命令用法、参数解析、label 过滤器四种匹配格式并结合 docker-ce 仓库中的 CLI 源码、Engine API 路由与卷服务实现深入剖析 prune 操作从用户输入到删除落盘的完整调用链与底层安全机制。读完本文你将掌握在开发机与生产环境安全回收卷占用的实战技能并能通过label过滤实现精准清理。一、命令总览与使用场景docker volume prune用于移除所有未被任何容器引用的本地卷。所谓“未使用”是指当前没有容器挂载该卷被运行中或已停止但未删除容器引用的卷不会被清理这是 Docker 判定卷“存活”的唯一依据。在长期运行的开发环境中反复执行docker run -v、docker compose up或卷创建操作后/var/lib/docker/volumes/下会积累大量不再被引用的卷目录。它们持续占用磁盘空间而docker volume ls只能“看”无法“删”。docker volume prune正是为批量回收这类空间而设计的命令。Usage: docker volume prune [OPTIONS] Remove all unused local volumes Options: --filter filter Provide filter values (e.g. labellabel) -f, --force Do not prompt for confirmation --help Print usage在 docker-ce 仓库中该命令由components/cli/cli/command/volume/prune.go实现是docker volume子命令族的一员与其他卷操作命令一同在components/cli/cli/command/volume/cmd.go中注册NewVolumeCommand依次挂载create、inspect、ls、rm、prune五个子命令。二、参数详解1.-f, --force跳过交互确认默认情况下执行 prune 前会弹出确认提示$ docker volume prune WARNING! This will remove all local volumes not used by at least one container. Are you sure you want to continue? [y/N] y Deleted Volumes: 07c7bdf3e34ab76d921894c2b834f073721fccfbbcba792aa7648e3a7a664c2e my-named-vol Total reclaimed space: 36 B提示中[y/N]中Y大写表示默认答案为否即直接回车不会删除任何卷只有输入y或Y才会继续其余任意输入含n、no、任意字符都视为放弃。这一交互逻辑在components/cli/cli/command/utils.go的PromptForConfirmation函数中实现将用户输入小写化后与y做精确比较。加入-f或--force后跳过确认直接删除适合脚本与 CI 场景$ docker volume prune -f Deleted Volumes: 07c7bdf3e34ab76d921894c2b834f073721fccfbbcba792aa7648e3a7a664c2e my-named-vol Total reclaimed space: 36 B从源码看runPrune的核心逻辑是if !options.force !command.PromptForConfirmation(...) { return 0, , nil }即未加-f且用户未确认时直接空操作返回不会发起任何删除请求。2.--filter按条件精准清理过滤参数格式为keyvalue多个过滤条件需多次传入--filter标志例如--filter foobar --filter bifbaz。当前volume prune官方文档仅声明支持label一类过滤器但 Docker 引擎端的 bash/zsh/fish 补全脚本见components/cli/contrib/completion/bash/docker中_docker_volume_prune函数同时提示了label与label!两种过滤键。label 过滤器包含语义labelkey匹配带有该标签键的卷无论值是什么labelkeyvalue匹配带有该标签键且值完全等于value的卷。label 过滤器排除语义label!key匹配不带该标签键的卷label!keyvalue匹配不带该标签键或该键的值不等于value的卷。实例如下先创建带标签的卷$ docker volume create the-doctor --label is-timelordyes the-doctor $ docker volume create daleks --label is-timelordno daleks只清理带is-timelord标签无论值的卷$ docker volume prune --filter labelis-timelord只清理标签精确等于is-timelordno的卷$ docker volume prune --filter labelis-timelordno清理不带is-timelord标签的卷$ docker volume prune --filter label!is-timelord3.--help查看帮助docker volume prune --help输出上文 Usage 块中的完整参数说明。三、工作流程与底层实现剖析1. CLI 侧参数解析与确认命令的 Cobra 定义位于components/cli/cli/command/volume/prune.go定义pruneOptions{ force bool; filter opts.FilterOpt }承载参数注册--force/-f布尔标志与--filter标志Args: cli.NoArgs严格拒绝位置参数——测试用例prune_test.go中的TestVolumePruneErrors验证了传入foo会报错accepts no argument命令注解Annotations: {version: 1.25}表明该命令自 Docker API 1.25 版本引入。runPrune的执行顺序为合并配置过滤条件 → 确认交互 → 调用客户端 API → 格式化输出。pruneFilters : command.PruneFilters(dockerCli, options.filter.Value()) if !options.force !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), warning) { return 0, , nil } report, err : dockerCli.Client().VolumesPrune(context.Background(), pruneFilters)值得注意的细节是command.PruneFilters除了命令行传入的--filter它还会读取 CLI 配置文件config.json中的pruneFilters字段该字段在components/cli/cli/config/configfile/file.go中声明JSON key 为pruneFilters。合并规则在components/cli/cli/command/utils.go中实现config.json里的过滤条件被追加进参数集合且命令行过滤条件优先于配置文件——当命令行含label!且与配置中的label冲突时跳过配置项反之亦然。这意味着即使每次命令不带--filter配置了pruneFilters的客户端也会按固定规则清理。2. 客户端发起 HTTP 请求CLI 通过components/cli/vendor/github.com/docker/docker/client/volume_prune.go中的VolumesPrune方法向 daemon 发起请求先以NewVersionError(1.25, volume prune)校验 API 版本是否支持该操作将过滤条件序列化为 query 参数向/volumes/prune发送POST请求解码响应为VolumesPruneReport结构。响应结构体定义在components/engine/api/types/types.go中包含两个字段字段类型含义VolumesDeleted[]string被删除卷的名称列表SpaceReclaimeduint64回收的字节数3. 引擎侧路由与卷服务实现daemon 侧的 HTTP 路由在components/engine/api/server/router/volume/volume.go中注册POST /volumes/prune映射到volume_routes.go的postVolumesPrune该函数解析filters表单参数后调用后端Prune最后以 JSON 返回报告。真正的删除逻辑在components/engine/volume/service/service.go的Prune方法中其关键行为有三点并发保护通过atomic.CompareAndSwapInt32保证同一时刻只有一个 prune 操作在运行若已有 prune 进行中返回Conflict错误a prune operation is already running。双重条件筛选Find查找时组合了ByDriver(volume.DefaultDriverName)仅本地驱动local、ByReferenced(false)仅未被引用以及用户过滤条件此外还有一个内置的CustomFilter跳过带挂载选项mount options的卷——源码注释明确说明这类卷即使删除也不会回收空间因此被刻意排除。这也解释了为什么volume prune实际回收量可能小于du统计值。逐卷删除与统计对每个候选卷先统计目录大小再执行删除单个卷删除失败仅记录 warning 并跳过不影响其余卷的清理最后汇总SpaceReclaimed并记录prune事件日志。4. 输出格式CLI 收到报告后先输出Deleted Volumes:列表每行一个卷名最后打印Total reclaimed space:与人类可读的大小经units.HumanSize格式化如36 B、2kB。若没有可删除的卷则只输出Total reclaimed space: 0B不打印Deleted Volumes标题。该输出格式被prune_test.go的测试与 golden 文件见components/cli/cli/command/volume/testdata/volume-prune.yes.golden等精确锁定可在改造成行后作为回归依据。四、与相关命令的协作docker volume prune是 Docker 清理体系的一环。在components/cli/docs/reference/commandline/volume_prune.md的“Related commands”章节中与它配套的命令包括volume create创建卷volume ls列出卷支持danglingtrue过滤器查看未被引用的卷作为 prune 前的“预检”volume inspect查看卷元数据与标签volume rm按名称逐个删除卷system df统计镜像、容器、卷与缓存占用的磁盘空间用于判断是否需要清理container prune、image prune、network prune分别清理容器、镜像、网络system prune一站式清理容器、网络、镜像需加--volumes才会连同卷一起清理。其中system prune --volumes与volume prune共用引擎层的VolumesService.Prune。在 CLI 源码prune.go中还暴露了RunPrune辅助函数强制force: true供system prune内部调用避免重复实现。五、最佳实践与注意事项先查后删执行 prune 前先用docker volume ls -f danglingtrue见 volume ls确认待清理范围再决定是否添加label过滤。善用标签做保护对需要保留的卷在创建时打标签如--label keeptrue清理时用--filter label!keep排除实现“默认清理、指定保留”的安全策略。这一模式在源码层面有完整支持引擎端acceptedPruneFilters仅放行label与label!两类过滤键见components/engine/volume/service/service.go。脚本场景必加-f交互式确认在自动化脚本中会阻塞或导致误删使用docker volume prune -f --filter ...可避免人工干预。注意“已停止容器仍引用卷”ByReferenced(false)的判定标准是“是否被任何容器引用”而非“是否被运行中容器使用”。已停止但未docker rm的容器仍会保住其挂载的卷因此若发现卷迟迟清不掉检查是否有残留容器。带挂载选项的卷不会被清理这是引擎源码中的刻意设计len(dv.Options()) 0才纳入候选遇到这类卷需用docker volume rm单独处理。并发限制同一 daemon 同时只允许一个 prune 操作编排工具并发触发时后到者会收到a prune operation is already running冲突错误需重试。配置化默认过滤可在~/.docker/config.json中写入pruneFilters如{pruneFilters: [label!keep]}让所有 prune 类命令默认遵守该规则命令行过滤条件优先级更高。六、小结docker volume prune是一个看似简单但内部精心设计的清理命令CLI 侧负责参数合并、交互确认与结果格式化引擎侧通过并发锁、双重引用检查与挂载选项排除保证删除安全label/label! 过滤器则赋予其精准控制能力。配合 volume ls 的事前检查与 system prune 的一站式清理可构成完整、可控的磁盘空间回收方案。赞分享容器运行时云原生【免费下载链接】docker-ce:warning: This repository is deprecated and will be archived (Docker CE itself is NOT deprecated) see the https://github.com/docker/docker-ce/blob/master/README.md :warning:项目地址https://gitcode.com/gh_mirrors/do/docker-ce点击查看免费下载相关推荐Docker CLI 实战docker network prune 清理未使用网络全指南Docker CLI 实战 docker network prune 清理未使用网络全指南 导读 docker network prune 是 DockerCLI开发工具Docker CLI volume 命令组完全指南从 create、ls、inspect 到 prune 与集群卷管理Docker CLI volume 命令组完全指南从 create、ls、inspect 到 prune 与集群卷管理 本篇基于 Docker CLImobCLI开发工具Docker CLI 镜像清理实战docker image prune 命令详解与底层实现Docker CLI 镜像清理实战docker image prune 命令详解与底层实现 docker image prune 是 Docker CLI 中CLI开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考