Files
docker_practice/04_image/4.6_other.md
T
2026-04-27 09:15:19 -07:00

86 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 4.6 其它制作镜像的方式
除了标准的使用 `Dockerfile` 生成镜像的方法外由于各种特殊需求和历史原因还提供了一些其它方法用以生成镜像
### 4.6.1 rootfs 压缩包导入
格式`docker import [选项] <文件>|<URL>|- [<仓库名>[:<标签>]]`
压缩包可以是本地文件远程 Web 文件甚至是从标准输入中得到压缩包将会在镜像 `/` 目录展开并直接作为镜像的文件系统内容导入若还需要补充 `CMD``ENV` 等元数据可以通过 `--change` 追加但它不支持 `RUN``COPY` 这类依赖构建上下文或会生成新文件系统层的 Dockerfile 指令
例如在 Debian/Ubuntu 主机上可以先用 `debootstrap` 生成 Ubuntu 24.04`noble` rootfs再通过标准输入导入为基础镜像
> **版本提示**示例中的 Ubuntu 16.04 (Xenial) 已于 2021 4 月停止支持如果用于生产环境建议更新至 Ubuntu 22.04 LTS 或更新版本
```bash
$ sudo debootstrap noble noble > /dev/null
$ sudo tar -C noble -c . | docker import - ubuntu:noble
sha256:81ec9a55a92a5618161f68ae691d092bf14d700129093158297b3d01593f4ee3
```
这组命令会先得到 `noble/` 目录下的 rootfs再把它打包后导入成镜像 `ubuntu:noble`这种方式更适合制作自定义基础镜像或把现成的根文件系统快速封装成镜像
导入成功后我们可以用 `docker image ls` 看到这个导入的镜像
```bash
$ docker image ls ubuntu
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu noble 81ec9a55a92a 5 seconds ago 78MB
```
如果需要在导入时补上镜像元数据可以配合 `--change` 选项
```bash
$ docker import \
--change 'CMD ["/bin/bash"]' \
--change 'ENV LANG=C.UTF-8' \
rootfs.tar \
custom/base:noble
```
### 4.6.2 Docker 镜像的导入和导出 `docker save` `docker load`
Docker 还提供了 `docker save` `docker load` 命令用以将镜像保存为一个归档文件然后传输到另一个位置上再加载进来它们仍然适合离线备份气隙环境分发或在两台主机之间手工迁移镜像如果是团队常规分发版本管理和协作优先使用 Docker Registry无论是 Docker Hub 还是内网私有 Registry会更合适
#### 保存镜像
使用 `docker save` 命令可以将镜像保存为归档文件归档中会包含镜像的父层以及所指定的标签如果本地镜像仓库里已有多个平台变体还可以通过 `--platform` 仅导出某个平台版本
比如我们希望保存这个 `alpine` 镜像
```bash
$ docker image ls alpine
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest baa5d63471ea 5 weeks ago 4.803 MB
```
> **版本提示**`alpine:latest` 为最新版本的 Alpine Linux如果需要特定版本号 `alpine:3.20`),可以明确指定以确保可重现性
保存镜像的命令为
```bash
$ docker image save -o filename alpine
$ file filename
filename: POSIX tar archive
```
这里的 filename 可以为任意名称甚至任意后缀名但文件的本质都是归档文件
**注意如果同名则会覆盖 (没有警告)**
若使用 `gzip` 压缩
```bash
$ docker image save alpine | gzip > alpine-latest.tar.gz
```
然后我们将 `alpine-latest.tar.gz` 文件复制到了另一个机器上可以用下面这个命令加载镜像
```bash
$ docker image load -i alpine-latest.tar.gz
Loaded image: alpine:latest
```
`docker load` 会恢复归档中的镜像和标签同样地在需要时也可以通过 `--platform` 只加载其中一个平台变体
如果我们结合这两个命令以及 `ssh` 甚至 `pv` 的话利用 Linux 强大的管道我们可以写一个命令完成从一个机器将镜像迁移到另一个机器并且带进度条的功能
```bash
docker save <镜像名> | bzip2 | pv | ssh <用户名>@<主机名> 'cat | docker load'
```