docker篇——镜像

  • Post author:
  • Post category:其他




Docker镜像



(一)概述

  1. 定义

镜像由多层组成,每层叠加之后,从外部看来就如一个独立的对象。镜像内部是一个精简的操作系统,同时还包含应用运行所必须的文件和依赖包。

  1. 仓库

一般镜像是从镜像仓库中拉去的,常见的镜像仓库是Docker Hub等等

  1. 理解

镜像——————构建时(build-time)结构

容器——————运行时(run-time)结构

  1. 特点

容器设计的初衷是快速和小巧,镜像通常是比较小的。

  1. 命令

从某个镜像启动一个或多个容器

docker container run

docker service create



(二)操作

1.下载镜像

$docker image pull (镜像从远程镜像仓库服务的仓库中下载)
 -a 参数来拉取仓库中的全部镜像(注意如果包含多个平台或者架构镜像,则命令可能失败)
默认情况下,从Docker Hub中拉取

$docker image pull <repository>:<tag> (从镜像仓库拉取镜像)
(未指定版本,默认latest,当然latest不一定代表是最新版的代码)

Linux Docker主机本地镜像仓库通常位于: /var/lib/docker/

Windows Docker主机位置:C:\ProgramData\docker\windowsfilter

延伸知识点:

仓库服务(Image Registry);
镜像仓库服务包含多个镜像仓库(Image Repository)。同样,一个镜像仓库中可以包含多个镜像。
  1. 查看镜像

    $docker image ls (查看Docker主机的本地仓库是否含有镜像)

    –digests参数,可查看镜像摘要

  2. 构建镜像

    $docker image build(构建镜像)

  3. 移除全部悬虚镜像

    $docker image prune (移除悬虚镜像)

    -a 额外移除没有被使用的镜像

  4. 过滤

    $docker image ls –filter dangling=true

    (悬虚dangling镜像拉取,没有标签的镜像叫做悬虚镜像,列表中展示为:)

    出现原因是:为镜像打一个已经存在的标签,发现有相同的之后,会把将旧镜像的标签移除,然后将标签用到新镜像上。

目前支持的过滤器:

(1)dangling:指定true和false, 仅返回悬虚镜像(true)或者非悬虚镜像(false)

(2)before:需要镜像名称或者ID作为参数,返回在之前被创建的全部镜像

(3)since:返回的是指定镜像之后创建的全部镜像

(4)label:根据标注(label)的名称或者值,对镜像进行过滤。docker image

ls命令输出中不显示标注内容。

(5)reference:过滤显示条件镜像,例子reference=“*:latest”

(6)format:通过Go模板对输出内容进行格式化要求

(7)is-official 是否是官方,true是指的官方镜像

is-automated是自动创建的仓库

例子:docker image ls –format “{

{.Repository}:{.Tag}:{.Size}}”

返回全部镜像,但是只显示仓库、标签和大小信息。

  1. 通过CLI方式搜索Docker Hub

    $docker search name(通过搜索所”name”字段中包含特定字符串的仓库)

    “name” 字段是仓库名臣个,包含了Docker ID,或非官方仓库的组织名称。

    默认情况下只显示25行数据,通过–limit可增加内容行数,最多100行。




(三)镜像与分层

Docker镜像由一些松耦合的只读镜像层组成

$docker image inspect (查看镜像分层命令)
$docker history (查看历史操作命令)

所有docker的镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层上,创建新的镜像。

在额外添加的镜像层时,镜像始终保持是当前所有镜像的组合。

Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。

理解:说白了,就是镜像版本会覆盖原镜像版本,但是不是物理删除(完全删除原镜像)而是进行逻辑删除。无论覆盖了多少层镜像层,每一个镜像层的对外是保持一致的。

存储引擎:

  1. Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。(每种引擎都是基于linux中对应的文件系统和块设备技术,每种引擎都有其独立的性能特点)

  2. Docker在Windows上仅支持windowsfilter一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW。

    $docker image pull (镜像拉取)注意结尾出现Already exists的行,表示了当前镜像在本地已经存在了。

Docker在Linux上支持很多存储引擎(Snapshotter),每个存储引擎都有自己的镜像分层、镜像层共享以及写时复制(CoW)技术的具体实现。



(四)镜像散列值(摘要)

从Docker1.10版本开始,镜像就是一系列松耦合的独立层的集合。

镜像本身就是一个配置对象,其中包括了镜像层的列表以及一些元数据信息。

镜像层才是实际数据存储的地方(比如文件等,镜像层之间是完全独立的,并没有从属于某个镜像集合的概念)

镜像的唯一标识是一个加密的ID,即配置对象本身的散列值,每个镜像层也由一个加密ID区分,其值为镜像层本身内容的散列值。

这意味着修改镜像的内容或其中任意的镜像层,都会导致加密散列值的变化。所以,镜像和其镜像层都是不可变的,任何改动都能很轻松地辨别。这就是所谓的内容散列(Content Hash)

延伸:

在推送和拉取镜像的时候,都会对镜像层进行压缩来节省网络宽带以及仓库二进制存储空间。但是一旦对镜像压缩,会改变镜像内容,意味着镜像的内容散列值在推动或者拉取操作之后,会与镜像内容不相符。

解决:

为了完成校验,Docker Hub会根据镜像层重新算散列值,并与原散列值进行比较,因为镜像在传输过程中被压缩,所以散列值的校验也会失败,为了避免该问题,每个镜像层同时会包含一个分发散列值(Distribution Hash)。这是一个压缩版镜像的散列值,当从镜像仓库服务拉取或者推送镜像的时候,其中就包含分发散列值,该散列值会用于校验拉取的镜像是否被篡改过。

这个内容寻址存储模型极大地提升了镜像的安全性,因为在拉取和推送操作后提供了一种方式来确保镜像和镜像层数据时一直的。

该模型也解决了随机生成镜像和镜像层ID这种方式可能会导致的ID冲突问题。



(五)多层架构的镜像



多层架构的镜像(Multi-architecture Image)

一个标签下支持多个平台和架构,为了实现这个特性,镜像仓库服务API支持两种重要的结构:

  1. Manifest列表(新):是指某个镜像标签支持的架构列表,其支持的每种架构,都有自己的Mainfest定义,其中列举了该镜像的构成。

  2. Manifest:包含了镜像配置和镜像层数据。

    $docker container run –rm golang go version

    (拉取Golang镜像,以容器方式启动,执行go version命令,并且输出Go的版本和主机OS/CPU架构信息)



删除镜像

$docker image rm (命令从Docker主机删除该镜像,其中,rm是remove的缩写)
删除操作会在当前主机上删除该镜像以及相关的镜像层,无法通过docekr image ls命令看到删除后的镜像,并且对应的包含镜像层数据的目录被删除。
如果某个镜像层被多个镜像共享,那只有当全部依赖该镜像层的镜像都被删除后,该镜像层才会被删除。

$docker image rm ID
如果被删除的镜像上存在运行状态的容器,那么删除操作不会被允许。想要删除镜像,需停止并删除该镜像相关的全部容器。

Windows环境中:
$docker image rm $(docker image ls -q) -f
通过docker image ls -q 命令只返回了系统中本地拉取的全部镜像的ID列表,将这个列表作为参数传给docekr iamge rm会删除本地系统中的全部镜像。

个人学习使用


文章总结出处



版权声明:本文为u014112521原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。