- CLI
- 开发工具
【免费下载链接】cli
The Docker CLI
导读
docker image load(别名docker load)是 Docker CLI 中与docker save配对的镜像迁移命令,用于从 tar 归档文件(支持 gzip、bzip2、xz、zstd 等压缩格式)或标准输入(STDIN)读取镜像数据,并将其连同标签一起恢复到本地 Docker 守护进程。本文以 Docker CLI 仓库中 docs/reference/commandline/image_load.md 为骨架,结合 cli/command/image/load.go 的源码实现与 cli/command/image/load_test.go 的测试用例,完整讲解命令用法、参数语义、平台过滤机制与底层调用链,让你掌握离线分发、跨机迁移与多架构镜像选择性导入的完整方案。
命令概述:作用、别名与基本语法
docker image load用于从 tar 归档(即使被 gzip、bzip2、xz 或 zstd 压缩)或 STDIN 加载镜像或仓库。它同时恢复镜像本身及其标签(tags)。在 Docker CLI 中该命令有两条可用路径:
docker image loaddocker load(顶层别名)
从源码看,命令注册在 cli/command/image/cmd.go 中通过commands.RegisterLegacy(newLoadCommand)注册,并以newLoadCommand挂载到docker image子命令组之下,同时保留了顶层docker load的历史用法。命令本身定义于 cli/command/image/load.go,其基本语法为:
docker image load [OPTIONS]需要注意命令不接受位置参数(源码中Args: cli.NoArgs),所有输入要么通过--input指向文件,要么来自 STDIN。
命令选项一览
以下选项表完整摘录自官方文档:
| 名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
-i,--input | string | (空) | 从 tar 归档文件读取,而非 STDIN |
--platform | stringSlice | (空) | 仅加载指定的平台。格式为以逗号分隔的os[/arch[/variant]]列表(例如linux/amd64,linux/arm64/v8) |
-q,--quiet | bool | false | 抑制加载过程输出 |
从源码 cli/command/image/load.go 可以看到,这三个选项被映射到loadOptions结构体:
type loadOptions struct { input string quiet bool platform []string }其中--platform被标记为 API 版本1.48新增(flags.SetAnnotation("platform", "version", []string{"1.48"})),即只有 Docker Engine API 1.48 及以上的守护进程才支持该选项。同时--platform注册了completion.Platforms()补全函数(见 cli/command/image/load.go),在支持 shell 补全的终端中可以直接 Tab 补全平台字符串。
从 STDIN 加载镜像
当不带--input时,命令从标准输入读取 tar 数据。典型用法是将docker save产生的归档通过管道直接喂给docker load,或重定向本地文件:
$ docker save busybox > busybox.tar $ docker load < busybox.tar Loaded image: busybox:latest官方文档给出的示例:
$ docker load < busybox.tar.gz Loaded image: busybox:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest 769b9341d937 7 weeks ago 2.489 MB注意:归档即使经过 gzip、bzip2、xz 或 zstd 压缩也可直接加载,Docker 会自动识别压缩格式。
源码视角:STDIN 输入的校验逻辑
在 cli/command/image/load.go 的runLoad中,输入源的选择逻辑非常关键:
var input io.Reader = dockerCli.In() switch opts.input { case "": // To avoid getting stuck, verify that a tar file is given either in // the input flag or through stdin and if not display an error message and exit. if dockerCli.In().IsTerminal() { return errors.New("requested load from stdin, but stdin is empty") } default: // We use sequential.Open to use sequential file access on Windows, avoiding // depleting the standby list un-necessarily. On Linux, this equates to a regular os.Open. file, err := sequential.Open(opts.input) ... input = file }也就是说:
- 如果未指定
--input且 STDIN 是一个终端(TTY),命令会直接报错requested load from stdin, but stdin is empty,避免进程挂起等待永远不会到来的输入; - 如果指定了
--input,则通过sequential.Open打开文件——该封装在 Windows 上使用顺序文件访问以节省系统缓存(standby list),在 Linux 上等价于普通的os.Open。
这一错误分支在测试 cli/command/image/load_test.go 的input-to-terminal用例中被显式验证:设置cli.In().SetIsTerminal(true)后执行命令,断言错误信息为requested load from stdin, but stdin is empty。此外wrong-args用例验证了命令拒绝位置参数(accepts no arguments)。
从文件加载镜像(--input)
当镜像归档保存在磁盘文件时,使用--input(短选项-i)显式指定:
$ docker load --input fedora.tar Loaded image: fedora:rawhide Loaded image: fedora:20 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest 769b9341d937 7 weeks ago 2.489 MB fedora rawhide 0d20aec6529d 7 weeks ago 387 MB fedora 20 58394af37342 7 weeks ago 385.5 MB fedora heisenbug 58394af37342 7 weeks ago 385.5 MB fedora latest 58394af37342 7 weeks ago 385.5 MB上面的输出清晰展示了一个核心特性:单个 tar 归档可以包含多个镜像及多个标签,加载后所有镜像与标签被逐一恢复。这也正是docker save支持一次导出多个镜像(docker save [OPTIONS] IMAGE [IMAGE...],见 cli/command/image/save.go)的原因——save 与 load 构成完整的离线镜像迁移闭环。
源码视角:文件打开与 quiet 自动降级
在 cli/command/image/load.go 中,输出行为有一个自动降级逻辑:
var options []client.ImageLoadOption if opts.quiet || !dockerCli.Out().IsTerminal() { options = append(options, client.ImageLoadWithQuiet(true)) }即:只要显式指定了--quiet,或者标准输出不是终端(例如输出被重定向到文件或管道),加载过程的状态输出都会被自动抑制。这意味着在脚本化场景中,即使不写-q也不会产生干扰性的进度输出。
ImageLoadWithQuiet对应的客户端函数选项定义在 vendor/github.com/moby/moby/client/image_load_opts.go,它最终写入请求体中的Quiet字段。
按平台选择性加载(--platform)
--platform选项用于在多平台(multi-platform)镜像归档中只加载指定的平台变体。默认情况下,docker load会加载归档中存在的所有平台变体;使用--platform后则只加载指定平台,若给定平台不在归档中,命令会报错。
该选项的取值格式为os[/arch[/variant]],例如:
linux/amd64linux/arm64/v8
架构和变体(variant)是可选的;省略时默认取守护进程的原生架构。
加载指定平台的示例
从包含多个平台变体的归档中只加载linux/amd64变体:
$ docker image load -i image.tar --platform=linux/amd64 Loaded image: alpine:latest平台不在归档中时的报错
尝试加载归档中不存在的linux/ppc64le平台:
$ docker image load -i image.tar --platform=linux/ppc64le requested platform (linux/ppc64le) not found: image might be filtered out源码视角:平台解析与多平台组合方式
--platform的类型是stringSlice,因此既可以用一个参数携带逗号分隔的多个平台,也可以重复传入多次。在 cli/command/image/load.go 中,每个平台串通过 containerd 的platforms.Parse解析为 OCI 规范平台结构体:
platformList := []ocispec.Platform{} for _, p := range opts.platform { pp, err := platforms.Parse(p) if err != nil { return fmt.Errorf("invalid platform: %w", err) } platformList = append(platformList, pp) } if len(platformList) > 0 { options = append(options, client.ImageLoadWithPlatforms(platformList...)) }解析失败会返回invalid platform: ...错误。随后平台列表通过ImageLoadWithPlatforms(定义于 vendor/github.com/moby/moby/client/image_load_opts.go)作为客户端选项传递;该选项仅对多平台镜像有效,单一平台镜像不受影响。
上述三种平台用法在测试 cli/command/image/load_test.go 中均有覆盖:
--platform linux/amd64(单个平台);--platform linux/amd64,linux/arm64/v8,linux/riscv64(逗号分隔多个平台);--platform linux/amd64 --platform linux/arm64/v8 --platform linux/riscv64(重复传入多个平台)。
三个用例分别对应 golden 文件 load-command-success.with-single-platform.golden、load-command-success.with-comma-separated-platforms.golden 与 load-command-success.with-multiple-platform-options.golden。
抑制输出(--quiet)
-q/--quiet选项用于抑制加载过程的输出。如前面源码分析所示,它有两种触发路径:
- 用户显式传入
--quiet; - 标准输出不是终端(重定向或管道场景)时自动启用。
在交互终端中不加-q时,命令会通过 internal/jsonstream/display.go 的Display函数逐条渲染守护进程返回的 JSON 消息流(如Loaded image: ...行),并正确处理上下文取消(context cancellation)时的事件流中断。测试 cli/command/image/load_test.go 通过 golden 文件(如 load-command-success.simple.golden、load-command-success.input-file.golden)验证了标准输出内容与格式的稳定性。
底层调用链与错误处理
综合 cli/command/image/load.go,docker image load的完整执行流程为:
- 确定输入源:
--input指定文件(sequential.Open)或 STDIN(终端时校验并报错); - 组装客户端选项:根据
quiet/ 输出非终端决定是否ImageLoadWithQuiet(true); - 解析
--platform列表(platforms.Parse),非空时追加ImageLoadWithPlatforms(...); - 调用
dockerCli.Client().ImageLoad(ctx, input, options...)向守护进程发起加载请求; - 通过
jsonstream.Display将守护进程返回的 JSON 消息流渲染到标准输出。
错误处理方面,测试覆盖了以下几类典型失败场景(见 cli/command/image/load_test.go):
- 传入了位置参数 →
accepts no arguments; - 未给输入且 STDIN 是终端 →
requested load from stdin, but stdin is empty; - 守护进程调用失败 → 透传底层错误;
- 平台字符串非法 →
invalid platform; --input指向不存在/不可打开的文件 → 透传open ...文件系统错误。
实战:save 与 load 的镜像离线迁移闭环
docker image load最常见的实战场景是与docker image save配合,在没有网络(air-gapped)环境或跨主机迁移时传递镜像:
# 在源主机导出镜像归档 $ docker image save -o myapp.tar myapp:1.0.0 # 在目标主机导入 $ docker image load -i myapp.tar Loaded image: myapp:1.0.0两者在源码上是严格对称的:docker save支持--output(默认写 STDOUT)与--platform(见 cli/command/image/save.go),其--platform同样标注为 API 1.48 新增;docker load则对应支持--input(默认读 STDIN)与--platform。因此对于多架构镜像,你可以用docker save --platform linux/amd64,linux/arm64/v8精确挑选要导出的变体,再用docker image load --platform linux/amd64在目标机只恢复所需平台,从而大幅节省磁盘与网络开销。
小结
docker image load从 tar(支持 gzip/bzip2/xz/zstd 压缩)或 STDIN 恢复镜像及其标签,无位置参数;-i, --input指定归档文件;缺省读 STDIN,且 STDIN 为终端时会主动报错避免挂起;--platform(API 1.48+)支持os[/arch[/variant]]格式,可逗号分隔或重复传入;平台不在归档中时返回requested platform (...) not found错误;-q, --quiet抑制输出;输出非终端时自动静默;- 源码实现位于 cli/command/image/load.go,测试用例见 cli/command/image/load_test.go,可与 cli/command/image/save.go 配合完成完整的离线镜像迁移。
- CLI
- 开发工具
【免费下载链接】cli
The Docker CLI
相关推荐
Docker CLI `docker image save` 命令完全指南:镜像导出、平台筛选与 tar 归档原理
Docker CLI docker image save 命令完全指南:镜像导出、平台筛选与 tar 归档原理 导读 docker image save (别名
CLI开发工具Docker CLI `docker context import` 命令详解:从 tar/zip 归档恢复 Docker Context
Docker CLI docker context import 命令详解:从 tar/zip 归档恢复 Docker Context docker conte
CLI开发工具Podman load 命令全解:从 tar 归档、目录与 URL 恢复镜像到本地容器存储
Podman load 命令全解:从 tar 归档、目录与 URL 恢复镜像到本地容器存储 导读 podman load 是 Podman 镜像生命周期管理中与
容器运行时云原生CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考