
容器运行时云原生【免费下载链接】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 plugin upgrade是 Docker 提供的插件在线升级命令允许在不删除插件、不影响既有引用如已创建的数据卷的前提下将已安装的插件镜像升级到指定版本或重新拉取最新版本。本文基于 docker-ce 仓库中的官方命令参考文档plugin_upgrade.md并结合 CLI 端、API 端与 daemon 端的真实源码实现系统讲解命令用法、每个参数的作用、升级全流程的底层原理、失败回滚机制以及完整的 sshfs 插件实战示例帮助你安全、正确地管理 Docker 插件生命周期。命令概览与用法docker plugin upgrade的完整用法如下Usage: docker plugin upgrade [OPTIONS] PLUGIN [REMOTE] Upgrade a pluginPLUGIN必填要升级的本地插件名称或 ID即当前已安装插件的引用例如vieux/sshfs:next。REMOTE可选目标远程插件镜像引用。如果省略Docker 会使用插件当前记录的原镜像引用重新拉取从而获取该镜像的更新版本例如将同一镜像 tag 对应的新构建内容拉取下来。从 CLI 源码看upgrade.go命令定义在components/cli/cli/command/plugin/upgrade.go中cmd : cobra.Command{ Use: upgrade [OPTIONS] PLUGIN [REMOTE], Short: Upgrade an existing plugin, Args: cli.RequiresRangeArgs(1, 2), RunE: func(cmd *cobra.Command, args []string) error { options.localName args[0] if len(args) 2 { options.remote args[1] } return runUpgrade(dockerCli, options) }, Annotations: map[string]string{version: 1.26}, }两点值得注意参数数量校验cli.RequiresRangeArgs(1, 2)表示必须传入 1 或 2 个位置参数多传或少传都会直接报错。最低 API 版本命令注解标记为version: 1.26即该功能自 Docker API 1.26 起提供。若客户端或 daemon 的 API 版本过低调用会得到版本不兼容的错误。选项详解命令支持以下四个选项选项说明默认值--disable-content-trust跳过镜像验证跳过内容信任签名校验true--grant-all-permissions自动授予运行该插件所需的全部权限不再逐个询问false--help打印用法帮助—--skip-remote-check不检查指定的远程插件镜像是否与现有插件镜像匹配false其中--disable-content-trust与--grant-all-permissions并非 upgrade 命令独有而是通过loadPullFlags从插件安装/拉取流程共享而来install.gofunc loadPullFlags(dockerCli command.Cli, opts *pluginOptions, flags *pflag.FlagSet) { flags.BoolVar(opts.grantPerms, grant-all-permissions, false, Grant all permissions necessary to run the plugin) command.AddTrustVerificationFlags(flags, opts.untrusted, dockerCli.ContentTrustEnabled()) }--disable-content-trust由command.AddTrustVerificationFlags注入默认值为true跳过验证。只有当仓库启用了内容信任Content Trust且插件镜像不是按摘要digest引用时CLI 才会对远程插件引用做签名解析与信任校验见 install.go 中的buildPullConfig逻辑。--skip-remote-check是 upgrade 命令特有的开关。CLI 在确认升级前会对比本地插件当前记录的原镜像引用p.PluginReference与目标 REMOTE 引用若两者不一致且未指定--skip-remote-check会弹出确认提示指定后则直接跳过该一致性检查详见下文“升级前置校验”。升级前置校验插件必须先禁用官方文档明确指出插件必须在升级前被禁用。这一点在 CLI 和 daemon 两端都有双重校验。CLI 端upgrade.go在发起升级前先调用PluginInspectWithRaw读取插件当前状态p, _, err : dockerCli.Client().PluginInspectWithRaw(ctx, opts.localName) if err ! nil { return errors.Errorf(error reading plugin data: %v, err) } if p.Enabled { return errors.Errorf(the plugin must be disabled before upgrading) }daemon 端backend_linux.go同样会在Manager.Upgrade入口处复查if p.IsEnabled() { return errors.Wrap(enabledError(p.Name()), plugin must be disabled before upgrading) }因此即使绕过 CLI 直接调用 API也无法对一个处于启用状态的插件执行升级。禁用插件的标准做法是使用docker plugin disable -f PLUGIN-f强制禁用见 disable.go 中--force选项升级完成后再用docker plugin enable PLUGIN重新启用enable.go。升级全流程源码剖析一次完整的插件升级请求会依次经过 CLI → Docker API 客户端 → daemon HTTP 路由 → 插件管理器 四条链路。下面按阶段拆解。阶段一CLI 解析引用与一致性确认在禁用校验通过后CLI 执行引用解析upgrade.goopts.localName p.Name if opts.remote { opts.remote p.PluginReference // 未指定 REMOTE 时沿用原镜像引用 } remote, err : reference.ParseNormalizedNamed(opts.remote) ... remote reference.TagNameOnly(remote) // 未带 tag 时补上 :latest old, err : reference.ParseNormalizedNamed(p.PluginReference) ... old reference.TagNameOnly(old) fmt.Fprintf(dockerCli.Out(), Upgrading plugin %s from %s to %s\n, p.Name, reference.FamiliarString(old), reference.FamiliarString(remote)) if !opts.skipRemoteCheck remote.String() ! old.String() { if !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), Plugin images do not match, are you sure?) { return errors.New(canceling upgrade request) } }要点未指定 REMOTE 时自动以p.PluginReference安装时记录的原镜像引用作为拉取目标实现“重新拉取当前镜像、获取更新版本”。引用统一经过ParseNormalizedNamed规范化并补全 tag保证新旧引用在同一基准上比较。若新旧镜像引用不一致且未开启--skip-remote-check会交互式询问Plugin images do not match, are you sure?选择n则直接取消升级。阶段二构建拉取配置并调用 API接下来调用buildPullConfig构建安装选项Registry 认证、远程引用、权限接受策略等见 install.go随后调用 APIresponseBody, err : dockerCli.Client().PluginUpgrade(ctx, opts.localName, options) if err ! nil { if strings.Contains(err.Error(), target is image) { return errors.New(err.Error() - Use docker image pull) } return err }API 客户端实现位于 plugin_upgrade.go先校验 remote 引用再通过checkPluginPermissions向服务端查询/协商插件所需权限最后以POST /plugins/{name}/upgrade发起请求并在请求头携带X-Registry-Auth认证信息。func (cli *Client) PluginUpgrade(ctx context.Context, name string, options types.PluginInstallOptions) (rc io.ReadCloser, err error) { if err : cli.NewVersionError(1.26, plugin upgrade); err ! nil { return nil, err } ... query.Set(remote, options.RemoteRef) privileges, err : cli.checkPluginPermissions(ctx, query, options) ... resp, err : cli.tryPluginUpgrade(ctx, query, privileges, name, options.RegistryAuth) ... }若目标实际上是一个普通镜像而非插件镜像API 会返回包含target is image的错误CLI 会追加提示Use docker image pull引导用户使用正确的镜像拉取命令。阶段三服务端路由处理服务端路由定义在 plugin.go处理函数位于 plugin_routes.go解析表单中的remote参数、解析请求体中的PluginPrivileges、从请求头解析认证信息最终调用后端pr.backend.Upgrade(...)并通过ioutils.NewWriteFlusher将拉取与升级进度实时以 JSON 流式写回给 CLICLI 端用jsonmessage.DisplayJSONMessagesToStream渲染进度条。阶段四daemon 拉取新镜像并原子化替换 rootfsdaemon 端核心逻辑在 backend_linux.go 与 manager_linux.go从本地 blob 存储拉取新版本插件的 config、manifest 与层数据pm.fetch并记录pull事件校验新配置中要求的权限setupNewPlugin→computePrivilegesvalidatePrivileges拒绝权限不足的请求进入upgradePlugin关键流程先对旧 rootfs 目录执行mount.RecursiveUnmount确保没有残留挂载点例如被docker plugin disable -f强制禁用但仍有活动的挂载将旧 rootfs重命名备份为rootfs-oldos.Rename(orig, backup)将新拉取的临时 rootfs 重命名为正式 rootfs成功后删除旧备份并更新插件的Configdigest、Blobsums、Manifest与PluginReference后持久化保存。整个过程采用“备份 → 替换 → 清理”的原子化策略若替换过程中任一步失败defer 中的回滚逻辑会自动删除已替换的半成品目录、把rootfs-old还原回正式目录并清理临时目录保证插件数据不会损坏manager_linux.go。升级完成后API 流式响应结束后CLI 输出Upgraded plugin name to remoteupgrade.go源码注释中注明该结果字符串有待未来 API 提供更准确的值。由于插件 ID 与本地名称保持不变所有既有的插件引用如已创建的数据卷、依赖该驱动的容器配置都继续有效无需重建。完整实战示例升级 sshfs 插件下面完整复现官方文档的 sshfs 插件生命周期示例plugin_upgrade.md演示“安装 → 使用 → 禁用 → 升级 → 重新启用 → 数据仍然可用”的完整闭环。1. 安装插件并设置 DEBUG 环境变量$ docker plugin install vieux/sshfs DEBUG1 Plugin vieux/sshfs:next is requesting the following privileges: - network: [host] - device: [/dev/fuse] - capabilities: [CAP_SYS_ADMIN] Do you grant the above permissions? [y/N] y vieux/sshfs:next2. 用该插件驱动创建并挂载一个数据卷$ docker volume create -d vieux/sshfs:next -o sshcmdroot1.2.3.4:/tmp/shared -o passwordXXX sshvolume sshvolume3. 在容器中向该数据卷写入数据$ docker run -it -v sshvolume:/data alpine sh -c touch /data/hello4. 禁用插件升级前的强制前置条件$ docker plugin disable -f vieux/sshfs:next vieux/sshfs:next此时由于插件被禁用docker volume ls不再显示由它驱动的卷驱动不可用$ docker volume ls DRIVER VOLUME NAME5. 执行升级REMOTE 与当前引用一致表示重拉该镜像的更新版本$ docker plugin upgrade vieux/sshfs:next vieux/sshfs:next Plugin vieux/sshfs:next is requesting the following privileges: - network: [host] - device: [/dev/fuse] - capabilities: [CAP_SYS_ADMIN] Do you grant the above permissions? [y/N] y Upgrade plugin vieux/sshfs:next to vieux/sshfs:next6. 重新启用插件并验证数据依然存在$ docker plugin enable vieux/sshfs:next vieux/sshfs:next $ docker volume ls DRIVER VOLUME NAME vieux/sshfs:next sshvolume $ docker run -it -v sshvolume:/data alpine sh -c ls /data hello该流程与仓库中的集成测试 TestPluginUpgrade 高度一致测试同样先plugin install --grant-all-permissions安装插件、创建卷并写入文件然后验证「插件启用时升级会报错包含disabled before upgrading」再执行plugin disable -f后使用--grant-all-permissions --skip-remote-check升级到新 tag最后检查新版本 rootfs 文件v2已落盘、旧卷数据仍可通过新版本驱动读取。这从测试层面印证了文档描述的完整行为链路。常见使用模式与注意事项只重拉不换 tag如果插件发布方在同一个 tag 下推送了更新重新构建则无需指定 REMOTEdocker plugin disable -f myplugin:latest docker plugin upgrade myplugin:latest docker plugin enable myplugin:latestCLI 会以p.PluginReference作为目标重新拉取此时新旧引用字符串一致不会触发Plugin images do not match的确认提示。跨版本升级到新 tagdocker plugin disable -f myplugin:1.0 docker plugin upgrade --grant-all-permissions --skip-remote-check myplugin:1.0 myplugin:2.0 docker plugin enable myplugin:2.0跨版本时新旧引用不一致CLI 会弹出确认询问用--skip-remote-check可跳过该提示适合非交互脚本。若新版本请求的权限与旧版本不同默认仍会逐个列出并询问在自动化场景中可用--grant-all-permissions一次性接受全部权限。需要注意的边界升级前必须禁用插件CLI 与 daemon 双重校验启用状态下执行升级会直接报错the plugin must be disabled before upgrading。禁用插件期间其驱动的资源不可见正如官方示例所示插件禁用期间docker volume ls不会列出由其驱动的卷升级完成后重新启用即恢复。这是预期行为不是数据丢失。强制禁用与残留挂载disable -f可能留下仍处于活动状态的挂载点daemon 升级流程会先递归卸载旧 rootfs若卸载失败会中止升级见 manager_linux.go。升级失败自动回滚rootfs 替换采用“备份-替换-回滚”机制失败时旧版本数据会被还原不会留下损坏的插件。目标必须是插件而非镜像若 REMOTE 指向普通镜像会得到含target is image的错误CLI 会提示改用docker image pull。相关命令插件管理的完整命令族可参考 plugin 总览文档其中upgrade与以下命令配合构成完整的插件生命周期管理plugin create从 rootfs 与配置创建插件插件数据目录需包含 config.json 与 rootfs 目录plugin disable禁用插件升级前的必要步骤支持-f强制plugin enable启用插件升级完成后恢复使用plugin inspect查看插件详情可用其确认当前镜像引用与启用状态plugin install安装并启用插件upgrade 复用其拉取与权限协商逻辑plugin ls列出已安装插件plugin push将插件推送到镜像仓库plugin rm删除插件plugin set修改插件设置如环境变量结合 install 文档 可以进一步了解插件安装时的权限协商、镜像分发对 registry 的最低版本要求2.3.0等前提条件这些机制同样约束着 upgrade 的可用性。赞分享容器运行时云原生【免费下载链接】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 plugin upgrade 命令用法与源码原理深度解析Docker CLI 插件升级实战 docker plugin upgrade 命令用法与源码原理深度解析 本篇技术指南以 Docker CLI 官方参考文档CLI开发工具docker plugin 命令详解Docker CE 插件全生命周期管理实战指南docker plugin 命令详解Docker CE 插件全生命周期管理实战指南 本篇技术指南以 docker ce 仓库中 docker plugin 命容器运行时云原生Docker CLI 插件启用实战docker plugin enable 命令详解与源码级原理Docker CLI 插件启用实战docker plugin enable 命令详解与源码级原理 导读 本文以 Docker CLI 仓库中 docs/refCLI开发工具上一篇FoldCraftLauncher重新定义Minecraft的游戏启动方式下一篇【亲测免费】 Pac-Bar 项目教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考