Docker镜像指南:从核心命令到离线迁移实战

文章目录

Docker镜像是什么?

Docker镜像本质是一个只读文件。它包含了创建Docker容器所需的全部文件和配置信息,除应用程序本身(例如一个编译好的Jar包),还包含了应用程序运行所需的所有依赖项(如操作系统、运行时环境、系统工具、库文件等)。

核心特性与详细解释

分层结构

  • 镜像是由一系列只读层(Layers) 堆叠而成的。
  • 每一层代表镜像Dockerfile中的一条指令(例如:RUN apt-get update, COPY . /app)。
  • 这种结构带来了巨大的好处:
    • 共享和复用:如果两个镜像基于同一个基础层(如Ubuntu),那么它们可以共享这一层,节省磁盘空间和下载时间。
    • 高效构建:当你修改Dockerfile并重新构建镜像时,Docker只会重新构建那些发生改变的层及其之后的层,大大加快了构建速度。

只读性(Read-Only)

  • 镜像本身是只读的。当你从一个镜像启动一个容器时,Docker会在镜像的所有层之上添加一个可写的容器层(Container Layer)。
  • 所有对运行中容器的修改(如创建新文件、修改文件、安装软件)都发生在这个可写层上。这使得容器可以随意更改,而不会影响到底层的基础镜像。
  • 当某个容器需要修改这个共享层里的文件时,写时复制机制会触发,为该容器单独复制一份文件到其可写层进行修改,而其他容器仍然读取原始文件。

内容可寻址(Content-Addressable)

  • 每个镜像都有一个唯一的标识符,称为镜像ID(一个SHA256哈希值)。这个ID是根据镜像每一层的内容计算出来的。
  • 这意味着只要镜像的内容完全相同,它们的ID就一定会相同。这保证了镜像的唯一性和完整性。

基于联合文件系统(Union File Systems)

  • 分层和只读的特性是通过联合文件系统(如Overlay2、AUFS) 来实现的。这种文件系统能够将多个不同的目录(层)透明地叠加在一起,形成一个统一的视图,呈现给容器。

为什么要使用镜像?

最核心的理由是:镜像提供了一种标准化的、轻量级的、不可变的交付物,它保证了应用在任何环境中都能以完全一致的方式运行,从而实现了"构建一次,随处运行"。

下面我们从几个关键角度来详细拆解为什么要使用镜像:

  1. 解决环境一致性难题("在我这儿是好的!")
    这是使用镜像最首要、最直接的原因。

传统痛点:

  • 开发环境:代码跑通了。
  • 测试环境:测试说有问题,依赖的库版本不对。
  • 生产环境:运维部署失败,系统配置有差异。

这就是经典的" works on my machine "问题。

镜像的解决方案:

  • 镜像将应用代码、运行时环境、系统工具、系统库、配置全部打包在一起,形成一个完整的、独立的软件包。
  • 这个包在开发、测试、生产任何环节都完全一致。
  • 结果:只要在开发机能运行成功,那么在任何装有Docker的机器上(测试、预生产、生产),它都能以完全相同的方式运行,彻底消除了环境差异带来的问题。
  1. 实现极致的标准化和交付简化

镜像成为一种通用的、标准的软件交付物。

  • 传统方式:交付物可能是一份代码、一个War/Jar包,再加上一长串的、复杂的、可能还不全的"环境配置说明文档"。
  • 镜像方式:交付物就是一个镜像文件(或一个镜像名称和标签)。部署命令简单到极致:docker run our-app:latest。

这个命令包含了下载、解压、配置、运行所有步骤。它极大地简化了部署流程,降低了运维成本和对运维人员技能的要求。

镜像相关的命令

关于loginpullpush等命令的解析请参考:Docker核心概念与镜像仓库操作指南

docker rmi

功能:删除镜像。

语法:

shell 复制代码
docker rmi [OPTIONS] IMAGE [IMAGE...]  

别名:docker image rmdocker image remove

关键参数:

  • -f:强制删除;
  • --no-prune:不移除该镜像的过程镜像,默认移除。

示例:

  1. 准备镜像:

    • docker pull busybox:1.36.0
    • docker pull busybox:1.35.0
  2. 查看镜像:docker images busybox

  3. 删除镜像

    • 方法一:通过ID删除
    • 方法二:通过tag删除


注意:被引用的镜像无法被删除,需要先关闭相应的容器。

示例:

  1. 重新拉取镜像:docker pull busybox:1.36.0 busybox:1.36.0
  2. 启动容器:docker run -it --name mybox busybox:1.36.0 sh
  3. 删除镜像:docker rmi busybox:1.36.0
  4. 删除容器:docker rm mybox
  5. 再次删除镜像:docker rmi busybox:1.36.0
  6. 查看镜像信息:docker images busybox


注意:镜像有多个标签时,指定镜像标签所删除的只是标签,镜像并没删除,在使用该镜像的容器在运行,只是不能再用标签管理,只能使用ID
docker save

功能:将指定镜像保存成 tar 归档文件。

语法:

shell 复制代码
docker save [OPTIONS] IMAGE [IMAGE...]  

别名:docker image save

关键参数:

  • -o:输出到的文件。

示例:

docker load

功能:导入使用 docker save 命令导出的镜像。

语法:

shell 复制代码
docker load [OPTIONS]  

别名:docker image load

关键参数:

  • --input, -i:指定导入的文件,代替 STDIN。
  • --quiet, -q:精简输出信息。

示例:

  1. 删除原有镜像
  2. 导入镜像

docker history

功能:展示的是镜像的构建历史记录

语法:

shell 复制代码
docker history [OPTIONS] IMAGE

别名:docker image history

关键参数:

  • -H, --human:大小和日期采用人容易读的格式展现
  • --no-trunc:显示全部信息,不要隔断
  • -q, --quiet:只显示镜像 ID 信息

示例:

docker image prune

功能:删除不使用的镜像。

语法:docker image prune [OPTIONS]

关键参数:

  • -a, --all:删除全部不使用的镜像;
  • --filter filter:指定过滤条件;
  • -f, --force:不提示是否删除。

离线迁移镜像

离线迁移镜像指的是在没有网络连接或无法直接访问镜像仓库(如Docker Hub、Harbor)的环境下,将Docker镜像从一台机器转移到另一台机器的过程。

它不通过网络拉取(docker pull),而是先将镜像打包成一个离线文件(如.tar归档文件),然后通过物理媒介(如U盘、移动硬盘)或内部文件传输方式,将这个文件复制到目标机器上,最后再加载到目标机器的Docker环境中。

这里使用scp把镜像从一个服务器拷贝到另一个服务器,这个过程的镜像数据流是在两个服务器之间直接通过SSH协议传输的,完全走的是内部的网络通道,与外部互联网隔离。

  1. 导出镜像:docker save -o mybox2.0 busybox:1.35.0
  2. 拷贝到另一台服务器:scp docker mybox2.0 root@服务器IP:要拷贝到的目录
  3. 另一台服务器把镜像导出:docker load -i mybox2.0

非常感谢您能耐心读完这篇文章。倘若您从中有所收获,还望多多支持呀!

相关推荐
是小崔啊15 小时前
极客学院-从零开始学架构
java·架构
Blessed_Li15 小时前
Higress云原生API网关详解 与 Linux版本安装指南
linux·运维·云原生·higress
EchoSam15 小时前
【Linux笔记】命令行与vim基础
linux·笔记·vim
礼拜天没时间.15 小时前
Rsync + Rsyncd 从入门到项目实战:自动化备份全攻略
linux·centos·rsync·文件传输·rsyncd
Linux技术芯15 小时前
阅读Linux 4.0内核RMAP机制的代码,画出父子进程之间VMA、AVC、anon_vma和page等数据结构之间的关系图。
linux
翻斗花园牛姥姥16 小时前
嵌入式系统与51单片机全解析
linux
金色天际线-16 小时前
Linux 文本处理四剑客:cut, sort, uniq, tr
linux·运维·服务器
kebeiovo17 小时前
Linux 环境配置 Boost 库详细步骤
linux·运维·服务器
科大饭桶17 小时前
C++入门自学Day17-- 模版进阶知识
c语言·开发语言·c++·容器