• docker镜像详解


    什么是docker镜像

    Docker镜像是Docker容器的基础组件,它包含了运行一个应用程序所需的一切,包括代码、运行时环境、系统工具、库和依赖等。Docker镜像的本质,可以分为以下几个方面来解释。

    1. 文件系统层:Docker镜像是由多个文件系统层(Filesystem Layers)组成的。每个层都是只读的,并且包含了文件和目录的变更。这种分层的文件系统结构使得镜像的构建和复用变得非常高效。每个层只需要存储差异部分,大大减小了镜像的体积。
    2. 只读性:Docker镜像是只读的,一旦创建就不能被修改。当需要修改一个镜像时,Docker会在原有的镜像上创建一个新的镜像,这个新镜像会包含原有镜像的所有层,并在其基础上添加新的层。
    3. 分层存储:Docker镜像的文件系统采用分层存储的方式。这意味着多个镜像可以共享同一个文件系统层,从而节省存储空间。当多个容器同时运行时,它们可以共享相同的基础镜像,只需在其基础上添加自己的可写层。
    4. 镜像的构建与复用:Docker镜像的构建是通过Dockerfile文件来定义的。Dockerfile中包含了一系列构建指令,用于描述如何从基础镜像中构建一个新的镜像。这种构建方式使得镜像的构建过程可自动化,并且易于复用和共享。

    从操作系统原理角度来看,Docker镜像可以从操作系统原理角度来看,Docker镜像可以类比为操作系统中的文件系统快照。一个Docker镜像可以看作是一个只读的文件系统快照,它包含了应用程序运行所需的所有文件和目录。每个镜像层都相当于文件系统中的一个增量变更,它们按照层级的方式进行组织,使得镜像的构建和复用更加高效。

    类似于操作系统中的进程,Docker容器是基于镜像创建的运行实体。当创建一个Docker容器时,Docker会在镜像的基础上添加一层可写的文件系统层,这个层称为容器层。容器层可以进行读写操作,而镜像层是只读的,这样就实现了镜像的复用和容器的隔离。

    镜像相关命令

    docker pull

    # 用法
    docker pull [OPTIONS] NAME[:TAG|@DIGEST]
    
    • 1
    • 2

    OPTIONS说明:

    • -a:拉取所有 tagged 镜像。
    • –disable-content-trust:忽略镜像的校验,默认开启。
    • -q: 可简化拉取过程中的日志输出。

    除此之外,docker pull 也可通过镜像的 digest 进行拉取。语法格式为 docker pull @

    digest,是镜像内容的一个 Hash 值,即所谓的 Content Hash(内容散列)。只要镜像内容发生了变更,其内容散列值就一定会发生改变。注意,digest 是包含前面的 sha256 的,表示该 digest 的产生所采用的 Hash 算法是 SHA256。

    image-20230906100931556

    docker images

    # 用法
    docker images [OPTIONS] [REPOSITORY[:TAG]]
    
    • 1
    • 2

    OPTIONS说明:

    • -a:列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);

    • –digests:显示镜像的摘要信息;

    • -f:显示满足条件的镜像;

      使用reference作为筛选条件

      image-20230906112155810

      在使用reference时可以使用通配符 * 进行筛选。需要注意的是,reference只能筛选经过认证的镜像,未经过认证的镜像即使满足条件也不会被筛选。

      使用before作为筛选条件

      image-20230906143827508

      -f before 用于列举出本地镜像中指定镜像创建时间之前创建的所有镜像。

      使用since作为筛选条件

      image-20230906144041234

      -f since 用于列举出本地镜像中指定镜像创建时间之后的创建的所有镜像。

    • –format:指定返回值的模板文件;

      image-20230906144255406

      {{ }}里面的内容与Go语言的模板语法一样。

    • –no-trunc:显示完整的镜像信息;

      image-20230906144122559

      默认的 docker images 显示的镜像 id 是经过截取后的显示结果,仅显示了前 12 位。使用 --no-trunc 参数后显示的是完整的镜像 id。

    • -q:只显示镜像ID。

    image-20230906144413589

    docker search

    # 用法
    docker search [OPTIONS] TERM
    
    • 1
    • 2

    OPTIONS说明:

    • –limit:对结果进行数量限制;
    • –format:指定返回值的模板文件;
    • –no-trunc:显示完整的镜像描述;
    • -f <过滤条件>:列出收藏数大于指定值的镜像。

    从 Docker Hub 查找所有镜像名包含 zookeeper,并且收藏数大于 10 的镜像。

    image-20230906152436421

    参数说明:

    • NAME: 镜像仓库源的名称

    • DESCRIPTION: 镜像的描述

    • OFFICIAL: 是否 docker 官方发布

    • STARTS: 类似 Github 里面的 star,表示点赞、喜欢的意思。

    • AUTOMATED: 自动构建。

    AUTOMATED 表示当前镜像是否是“自动化镜像”。什么是自动化镜像?就是使用 Docker Hub 连接一个包含 Dockerfile 文件(专门构建镜像用的文件)的 GitHub 仓库或 Bitbucket 仓库的源码托管平台,然后 Docker Hub 就会自动根据 Dockerfile 内容构建镜像。这种构建出的镜像会被标记为 AUTOMATED,这种构建镜像的方式称为 Trusted Build(受信构建)。只要 Dockerfile文件内容发生变化,那么 Docker Hub 就会构建出新的镜像。

    docker rmi

    基本使用

    rmi,remove images。该命令用于删除指定的本地镜像。镜像通过:指定。如果省略要删除镜像的 tag,默认删除的是 lastest 版本。

    image-20230906164608951

    删除多个镜像

    docker rmi 命令可一次性删除多个镜像,多个要删除的镜像间使用空格分隔。

    image-20230906164752636

    通过 ImageID 删除镜像

    image-20230906164934942

    强制删除镜像

    默认情况下,对于已经运行了容器的镜像是不能删除的,必须要先停止并删除了相关容器然后才能删除其对应的镜像。不过,也可以通过添加-f 选项进行强制删除。

    image-20230906165051369

    删除所有镜像

    使用组合命令删除所有镜像。当然,如果不携带-f 选项,则不会删除已打开容器的镜像。

    # 命令
    [root@centos ~]#docker rmi -f $(docker images -q)
    
    • 1
    • 2

    导出 / 导入镜像

    导出镜像 save

    docker save -o "导出的文件名" "多个镜像名,用空格分隔"
    
    • 1

    image-20230906193049287

    导入镜像 load

    docker load 用于将一个 tar 文件导入并加载为一个或多个镜像。

    docker load -i "要导入的tar文件"
    
    • 1

    image-20230906193553813

    镜像分层

    当构建一个Docker镜像时,Docker会将镜像分解为多个文件系统层,每个层都是只读的,并且包含了文件和目录的变更。这种分层的文件系统结构使得镜像的构建和复用变得非常高效。

    image-20230907101040056

    上面的示意图展示了一个由3个扩展镜像层和一个基础镜像层组成的Docker镜像。在基础镜像层之上的镜像层称为扩展镜像层。顾名思义,其是对基础镜像层功能的扩展。

    在 Dockerfile 中,每条指令都是用于完成某项特定功能的,而每条指令都会生成一个扩展镜像层。

    当创建一个新的Docker容器时,Docker会在只读层(扩展镜像层)的基础上添加一个可写层,这个可写层会包含容器运行时所需的文件和目录变更。这样,多个容器就可以共享同一个基础镜像层和多个只读层。分层存储的优势在于镜像的复用和共享。如果有多个镜像使用了相同的基础镜像层,它们可以共享这个基础层,只需在其基础上添加自己的可写层。这样就可以大大减小镜像的体积,并提高镜像的构建和复用效率。

    image-20230907101328450

    在上面的示意图中,Docker镜像的分层存储通过联合文件系统来实现。可写层是容器运行时的一部分,用于存储容器运行时的变更和数据。只读层包含了基础镜像的内容,它们是只读的,并且可以被多个容器共享。

    需要注意的是,这里的分层并不是物理上的分层,而是逻辑上的分层。在底层实现上,Docker使用了联合文件系统(UnionFS)来实现镜像的分层存储。联合文件系统是一种特殊的文件系统,它可以将多个不同的文件系统层合并为一个单一的文件系统。在Docker中,常用的联合文件系统有AUFS、OverlayFS和DeviceMapper等。

    镜像摘要

    Docker镜像摘要是镜像内容的唯一标识符,它是通过对镜像二进制数据进行哈希运算生成的。摘要可以确保所引用的映像在整个生命周期中始终是相同的。如果镜像内容发生改变,即使名字和标签相同,摘要也会发生改变。

    在 docker pull 镜像结束后会给出该拉取的镜像的摘要 digest。并且通过 docker images --digests 命令也可以查看到镜像的摘要信息。

    1

    镜像摘要的作用

    摘要的主要作用是区分相同:的不同镜像。

    例如某个镜像在生产运行过程中发现存在一个 BUG。现对其进行了修复,并使用原标签将其 push 回了仓库,那么原镜像被覆盖。但生产环境中遗留了大量运行中的修复前镜像的容器。此时,通过镜像标签已经无法区分镜像是修复前的还是修复后的了,因为它们的标签是相同的。此时通过查看镜像的 digest 就可以区分出修改前后版本,因为内容发生了变化,digest 一定会变。为了确保再次拉取到的是修复后的镜像,可通过 digest 进行镜像拉取。其用法是:docker pull @

    分发散列值

    在 push 或 pull 镜像时,都会对镜像进行压缩以减少网络带宽和传输时长。但压缩会改变镜像内容,会导致经过网络传输后,镜像内容与其 digest 不相符。为了避免该问题,Docker 又为镜像配置了 Distribution Hash(分发散列值)。在镜像被压缩后立即计算分发散列值,然后使该值随压缩过的镜像一同进行发送。在接收方接收后,立即计算压缩镜像的分发散列值,再与携带的分发散列值对比。如果相同,则说明传输没有问题。

  • 相关阅读:
    walmart沃尔玛美海淘攻,2024最新版walmart海淘教程
    含文档+PPT+源码等]精品基于SpringBoot的便捷网住宿预约系统的设计与实现包运行成功]Java毕业设计SpringBoot项目源码
    spring中的bean生命周期
    立即执行函数在前端国际化方案中的应用
    指纹面容识别登录流程概述
    Maven与IDEA版本兼容问题以及配置
    vue2条件渲染v-if VS v-show
    回文串问题
    <%=%>模板写法
    Spring Boot 并行任务,这才是优雅的实现方式!
  • 原文地址:https://blog.csdn.net/qq_54015483/article/details/132791281