👨🎓作者:Java学术趴 🏦仓库:Github、Gitee ✏️博客:CSDN、掘金、InfoQ、云+社区 💌公众号:Java学术趴 🚫特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系小编授权。 🙏版权声明:文章里的部分文字或者图片来自于互联网以及百度百科,如有侵权请尽快联系小编。微信搜索公众号Java学术趴联系小编。
第三章 Docker镜像
3.1 镜像基础
3.1.1 镜像简介
- 镜像是一种轻量级、可执行的独立软件包,也可以说是一个精简的操作系统。镜像中包含应用软件及应用软件的运行环境。具体来说镜像包含运行某个软件所需的所有内容,包括:代码、库、环境变量和配置文件等。几乎所有应用,直接打包为Docker镜像后可以运行。
- 由于镜像的运行时是容器,容器的设计初中就是快速和小巧,所以镜像通常都比较小,镜像中不包含内核,其共享宿主机的内核:镜像中只包含简单的Shell,或者没有Shell。
3.1.2 Docker镜像分类
根据镜像发布者的不同,形成了四类不同的镜像仓库
- Docker Official Image : Docker的官方镜像。该类仓库由Docker官方直接发布,代码质量较高且安全,有完善的文档。官方镜像仓库名称软件名构成,形式为:
- Verified Publisher : 已验证发布者仓库。该类仓库中的镜像由非Docker官方的第三方发布。这种镜像一般是由大公司、团体或组织发布的,由Docker官方进行验证颁发 Verified Publisher 标识。这种仓库的质量还是有保证的。非官方镜像仓库名称一般由发布者用户名与软件名称两部分构成,形式为:/
- Sponsored OSS : 由Docker公司赞助发布的镜像仓库。
- 无认证仓库 :没有以上任何标识的仓库。这种仓库还是要谨慎使用。
3.1.3 第三方镜像中心
- 镜像中心默认使用的都是 Docker Hub。镜像中心是可配置的,可以使用指定的第三方镜像中心。对于镜像中心的仓库名称由三部分构成://。其中<domain_name>是指第三方镜像中心的域名或IP。
3.1.4 镜像定位
- 对于任何镜像,都可通过:进行唯一定位。其中tag代表的镜像的版本号。tag中存在一个特殊的版本号——latest(最新版)。如果不指定,默认tag就是使用的latest。
3.2 镜像相关命令
3.2.1 基本命令
- docker pull : 将指定的镜像从 docker hub 拉去到本地。如果没有指定镜像则会抛出一个Error。
- docker images : 列出本地主机上可用的Docker镜像。该命令将显示每个Docker镜像的名称、标签、镜像ID、创建时间和大小等信息。
- docker search : 该命令可以查看指定名称的镜像。
- docker rmi : remove images。该命令用于删除指定的本地镜像。镜像通过:指定。如果省略tag,默认删除的是 lastest 版本。删除全部的镜像: docker rmi -f $(docker images -q)
- docker history 镜像名(镜像ID) : 显示 Docker 镜像的历史记录。通过运行 docker history 命令,可以查看 Docker 镜像的构建历史,了解 Docker 镜像的构建过程和各层之间的依赖关系。
- docker inspect 镜像名(镜像ID) :查看 Docker 对象(包括容器、镜像、网络等)的详细信息。通过运行 docker inspect 命令,可以获取 Docker 对象的所有属性和配置信息。
3.2.2 自动化镜像
- Docker 中的自动化镜像是一种自动构建和发布 Docker 镜像的机制,允许开发人员将代码提交到源代码管理库中,然后通过 CI/CD 工具链自动构建和部署 Docker 镜像。
- 这种自动化镜像构建和发布的机制,可以实现 Docker 镜像的持续集成和持续部署,从而提高了开发和部署效率,并且可以更加方便地管理和维护 Docker 镜像。自动化镜像还可以与其他工具集成,例如容器编排工具(如 Kubernetes、Docker Swarm 等),以实现更高级的自动化部署和管理。
- 通常,自动化镜像构建和发布的过程需要使用 Dockerfile 和 CI/CD 工具链(例如 Jenkins、GitLab CI、Travis CI 等)。开发人员可以在 Dockerfile 中定义 Docker 镜像的构建过程,然后通过 CI/CD 工具链将代码提交到源代码管理库中,并触发自动化构建和发布过程。
3.2.3 导出/导入镜像
我们在本地生成一个镜像,想将其导出后在另一台电脑是使用,则可以通过导出/导入镜像来完成。
- docker sava : 将镜像打包到本地。
复制代码docker save -o my.tar redis:3.7 tomcat:8.5
- docker load : 将一个镜像包解压为镜像。
css复制代码docker load -i my.tar
3.2.4 镜像打标签
docker tag
命令是 Docker 中的一个命令,用于给镜像打标签,即为镜像指定一个新的名称和标签。通过运行docker tag
命令,可以创建一个新的镜像标签,并将该标签与指定的镜像关联。
docker tag
命令的语法如下:
css复制代码docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
其中,SOURCE_IMAGE
参数指定要打标签的源镜像名称和标签,可以是镜像名称、镜像 ID 或者带有标签的镜像名称。如果未指定标签,则默认使用 latest
标签。TARGET_IMAGE
参数指定为源镜像创建的新的目标镜像名称和标签。
例如,以下命令可以为名为 my-image 的镜像打上 v1.0 的标签,并将其关联到新的镜像名称 my-repo/my-image:
perl复制代码docker tag my-image:latest my-repo/my-image:v1.0
运行 docker tag
命令后,Docker 会为指定的源镜像创建一个新的标签,并将该标签与新的目标镜像名称关联。可以通过运行 docker images
命令来查看新的镜像标签。
需要注意的是,docker tag
命令只是给镜像打上标签,不会创建新的镜像。因此,如果需要将新的标签上传到 Docker 镜像仓库,则需要使用 docker push
命令将镜像上传到仓库中。
使用 docker tag
命令可以方便地为 Docker 镜像打上标签,使镜像更加易于识别和管理,便于进行镜像版本控制和发布。
3.2 镜像分层
3.2.1 什么是分层
- Docker镜像由一些松耦合的 只读 镜像组成,Docker Deamon负责堆叠这些镜像层,并将他们关联为一个统一的整体,即对外表现出的是一个独立的对象。
- 通过 docker pull 拉去镜像时,每个pull complete 结尾的行就代表下载完毕了一个镜像层。
3.3.2 分层是有序的
- Docker 镜像中的分层是有序的,这是因为每个层都是基于先前层的文件系统的增量修改。每个层都记录了对前一个层所做的更改,这些更改以文件的形式存储在该层中。因此,层之间的顺序是非常重要的,因为它们确定了文件系统的最终状态。
- 如果层之间的顺序不正确,可能会导致镜像的构建失败或镜像中的一些文件丢失或损坏。例如,如果一个层中的文件在后续的层中被删除或更改,可能会导致镜像中的应用程序出现问题或无法正常运行。
- 此外,层之间的顺序还影响镜像的构建速度和大小。如果层之间的顺序不正确,可能会导致构建时间变长或镜像变得更大。
3.2.3 分层的优势
- 减小镜像大小 : Docker 镜像的分层设计使得每个层都包含一个文件系统中的文件和目录。这些层是单独存储的,因此每个层只包含与该层相关的文件和目录。这种设计可以减小镜像的大小,因为相同的文件和目录可以被多个层共享。
- 提高镜像的重用性 : 分层设计使得 Docker 镜像具有良好的重用性。每个层都可以被独立地重用和更新,而不会影响其他层,可以在其他镜像中进行使用。
- 优化镜像构建和更新 : Docker 镜像的每个层都可以被独立地构建和更新。这意味着,如果您需要更新镜像中的某些文件或目录,您可以只更新那些受影响的层,而不需要重新构建整个镜像。
- 方便镜像分发和下载 :由于 Docker 镜像采用分层的设计,因此镜像可以被分发和下载为多个层。这种设计使得镜像的分发和下载变得更加容易,因为只需要下载那些缺失的层,而不需要下载整个镜像。
3.2.4 分层的劣势
- 镜像的复杂性增加 : 镜像的分层设计增加了镜像的复杂性。每个层都包含该层的文件和目录,而这些文件和目录可能会互相依赖。如果设计不当,可能会导致镜像的构建和管理变得更加困难。
- 镜像的可靠性降低 : 镜像的分层设计可能会降低镜像的可靠性。如果一个层中的文件或目录被删除或更改,可能会影响其他层中的文件或目录。
- 镜像的安全性降低 : 由于 Docker 镜像采用分层的设计,因此每个层都可以包含不同的文件和目录。这可能会导致镜像中包含不必要或不安全的文件和目录。如果不小心在镜像中包含了敏感信息或漏洞,可能会导致安全问题。
- 镜像的可移植性降低 : 由于 Docker 镜像采用分层的设计,因此镜像可能会因为依赖不同的文件和目录而不可移植。
3.2.5 镜像层构成
每个镜像层由两部分组成: 镜像文件系统FS 和 镜像json文件。这两个部分具有相同的imageID。
- 镜像文件系统就是对镜像占有的磁盘空间进行管理的文件系统,拥有镜像所有镜像层的数据内容。而镜像json文件则是用于描述镜像的相关属性的集合,通过 docker inspect [镜像] 可以直接查看到。
3.2.6 镜像FS构成
一个docker镜像的文件系统FS由多层只读的镜像层组成,每层都完成了特定的功能。
- 基础层:基础层是一个最基本的文件系统层,它包含了操作系统的核心文件和目录。
- 依赖层:依赖层是基于基础层构建的,它包含了应用程序运行所需的所有依赖项,如库文件、运行时环境等。
- 应用程序层:应用程序层是基于依赖层构建的,它包含了应用程序的所有文件和目录。
3.3 镜像摘要
3.3.1 摘要的概念
- 摘要,即 digest,是镜像内容的一个Hash值,即所谓的Content Hash(内容散列)。只要镜像内容发生了便共呢,其内容散列值就一定会发生变化。也就是说,一个镜像一旦创建完毕,其 digest 就不会发生变化了,因为镜像是只读的。
- Docker默认采用的Hash算法是SHA256,即Hash值是一个长度为256位的二进制值。Docker使用16进制表示,即变为长度为64位的字符串。
- 它是由Docker对镜像的内容(即镜像的文件系统和元数据)计算得出的唯一标识符。
3.3.2 查看摘要
- 在 docker pull 镜像结束后会给出拉去该镜像的摘要 digest。
- 通过 docker inspect 命令可以查看指定镜像的详细信息。其中就包含该镜像的摘要信息。
- 使用 docker images --digests 查看摘要。
3.3.3 摘要的作用
- Docker镜像摘要的作用是确保镜像的完整性和一致性。当您使用Docker拉取镜像时,Docker会计算该镜像的摘要并将其与Docker Hub或私有镜像仓库上的摘要进行比较。如果两个摘要不匹配,则意味着镜像可能已被篡改或损坏,Docker会拒绝拉取该镜像。
- 使用镜像摘要可以确保您拉取的镜像与预期的完全一致,而不受中间人攻击的影响。因此,在拉取镜像时,建议使用镜像的摘要而不是标签,以确保您获取的是正确的镜像。
xml复制代码// 标签拉取
docker pull <repository>:<tag>
// 摘要拉取(在使用摘要拉去时,要带上前边的 sha256 )
docker pull <repository>@<digest>
3.3.4 分发散列值
- 在 push 或 pull 镜像时,都会对镜像进行压缩以减少网络带宽和传输时长。但压缩会改变镜像内容,一定内容发生变化,镜像所对应的digest就会发生变化,这就会导致镜像内容和digest不符,出现问题。
- 为了避免该问题,Docker又为镜像配置了 Distribution Hash(分发散列值)。在镜像被压缩后立即计算分发散列值,然后使该值随压缩过的镜像一同进行发送。在接收方接收后,立即计算压缩镜像的分发散列值,再与携带的分发散列值进行对比。如果相同,则说明传输没有问题。
3.5 多架构镜像
3.5.1 什么是多镜像结构
- Docker中的多架构镜像(multi-architecture images)是指一个镜像可以在多个不同的处理器架构下运行,例如x86、ARM、PowerPC等。这种镜像可以让开发者将应用程序打包成一个单一的镜像,然后在不同的处理器架构下运行,而无需为每个架构创建不同的镜像。这对于跨平台应用程序的开发和分发非常有用。
3.5.2 多架构镜像原理
- 无论用户使用的是什么操作系统/系统结构,其通过 docker pull 命令拉取到的一定是一个针对该操作系统/系统结构的镜像,无需用户自己考虑操作系统/系统结构问题。 Docker Hub 能够根据提交 pull 请求的,自动选择其对应的镜像进行拉取。
- 为了创建多架构镜像,需要使用Docker的manifest文件来描述镜像在不同处理器架构下的映像。Docker在v2.2版本中引入了manifest文件格式,使得开发者可以将多个镜像标记为同一名称的单个多架构镜像。当用户拉取这个多架构镜像时,Docker会自动选择最适合用户处理器架构的映像来运行应用程序。
- 在创建多架构镜像时,需要确保所有的映像都有相同的镜像名称和标签,并且都已经上传到Docker镜像仓库。然后使用Docker命令行工具或者Docker API来创建描述多架构镜像的manifest文件,并将其上传到Docker镜像仓库。
- 在 pull 的时候,会将拉取系统的信息存储到 manifest 文件中,Docker Hub 会去检测这个文件,拉取指定系统/架构的镜像。
3.6 玄虚镜像
- 玄虚镜像 : 是指那些处于 "dangling" 状态的镜像,也就是没有被任何容器使用的镜像。这些镜像通常是由于构建新镜像、更新镜像或者删除容器而产生的。通常TAG被标记为 :“",处于"dangling"状态的镜像不会对现有镜像产生影响,但是会占用大量的磁盘空间,因此需要及时清理。
- 可以使用 docker images -f dangling=true 命令筛选出玄虚镜像,然后进行处理。
以上项目的源代码,点击星球进行免费获取 星球 (Github地址)