【Docker—基础】镜像

镜像是一个只读的 Docker 容器模板,包含启动容器所需要的所有文件系统结构和内容。简单来讲,镜像是一个特殊的文件系统,它提供了容器运行时所需的程序、软件库、资源、配置等静态数据。即镜像不包含任何动态数据,镜像内容在构建后不会被改变。

容器目的就是运行应用或者服务,这意味着容器的镜像中必须包含应用/服务运行所必需的操作系统和应用文件。但是,容器又追求快速和小巧,这意味着构建镜像的时候通常需要裁剪掉不必要的部分,保持较小的体积。例如,Docker镜像通常不会包含6个不同的Shell让读者选择——通常Docker镜像中只有一个精简的Shell,甚至没有Shell。镜像中还不包含内核——容器都是共享所在Docker主机的内核,所以有时会说容器仅包含必要的操作系统(通常只有操作系统文件和文件系统对象)。

镜像操作

image

拉取镜像

Docker 镜像的拉取使用 docker pull 命令, 命令格式一般为 docker pull [Registry]/[Repository]/[Image]:[Tag]。Linux Docker 主机本地镜像仓库通常位于/var/lib/docker/

  • Registry 为注册服务器,Docker 默认会从 docker.io 拉取镜像,如果你有自己的镜像仓库,可以把 Registry 替换为自己的注册服务器。
  • Repository 为镜像仓库,通常把一组相关联的镜像归为一个镜像仓库,library 为 Docker 默认的镜像仓库。
  • Image 为镜像名称。
  • Tag 为镜像的标签,如果你不指定拉取镜像的标签,默认为 latest。

注:标有latest标签的镜像不保证这是仓库中最新的镜像。

例如,我们需要获取一个 busybox 镜像,可以执行以下命令:

busybox 是一个集成了数百个 Linux 命令(例如 curl、grep、mount、telnet 等)的精简工具箱。
$ docker pull busybox

Using default tag: latest
latest: Pulling from library/busybox
61c5ed1cbdf8: Pull complete
Digest: sha256:4f47c01fa91355af2865ac10fef5bf6ec9c7f42ad2321377c21e844427972977
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest

实际上执行 docker pull busybox 命令,都是先从本地搜索,如果本地搜索不到 busybox 镜像则从 Docker Hub 下载镜像。

查看镜像

Docker 镜像查看使用 docker images 或者 docker image ls 命令。如果我们想要查询指定的镜像,也可以使用 docker image ls 命令来查询。

$ docker image ls busybox

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              018c9d7b792b        3 weeks ago         1.22MB

Docker 提供 --filter 参数来过滤 docker image ls 命令返回的镜像列表内容。Docker目前支持如下的过滤器:

  • dangling:可以指定true或者false,仅返回悬虚镜像(true),或者非悬虚镜像(false)。
  • before:需要镜像名称或者ID作为参数,返回在之前被创建的全部镜像。
  • since:与before类似,不过返回的是指定镜像之后创建的全部镜像。
  • label:根据标注(label)的名称或者值,对镜像进行过滤。docker image ls命令输出中不显示标注内容。

其他的过滤方式可以使用reference。

也可以使用 --format 参数来通过 Go 模板对输出内容进行格式化。如果需要更复杂的过滤,可以使用 OS 或者 Shell 自带的工具,比如 grep 或者 awk 。

重命名镜像

如果你想要自定义镜像名称或者推送镜像到其他镜像仓库,你可以使用 docker tag 命令将镜像重命名。docker tag 的命令格式为 docker tag SOURCE_IMAGE TARGET_IMAGE。

一个镜像可以根据用户需要设置多个标签,标签是存放在镜像元数据中的任意数字或字符串。

下面通过实例演示一下:

$ docker tag busybox:latest mybusybox:latest

执行完 docker tag 命令后,可以使用查询镜像命令查看一下镜像列表:

docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              018c9d7b792b        3 weeks ago         1.22MB
mybusybox           latest              018c9d7b792b        3 weeks ago         1.22MB

可以看到,镜像列表中多了一个 mybusybox 的镜像,busybox 和 mybusybox这两个镜像的 IMAGE ID 是完全一样的。实际上它们指向了同一个镜像文件,只是别名不同而已。

搜索镜像

docker search 命令允许通过 CLI 的方式搜索 Docker Hub。读者可以通过 “NAME” 字段的内容进行匹配,并且基于返回内容中任意列的值进行过滤。

$ docker search aipine
NAME                                      DESCRIPTION            STARS               OFFICIAL            AUTOMATED
wangyulong/aipine_go_jmeter_mysql_redis                          0                                       
anjia0532/alpine-package-mirror           aipine mirror server   0                                       [OK]
potachaidocker/aipineweb                  aipineweb              0           

可以使用 --filter "is-official=true",使命令返回内容只显示官方镜像。默认情况下,Docker 只返回 25 行结果。读者可以指定 --limit 参数来增加返回内容行数,最多为 100 行。

删除镜像

可以使用 docker rmi 或者 docker image rm 命令删除镜像。

$ docker rmi mybusybox

Untagged: mybusybox:latest

删除操作会在当前主机上删除该镜像以及相关的镜像层。这意味着无法通过 docker image ls 命令看到删除后的镜像,并且对应的包含镜像层数据的目录会被删除。但是,如果某个镜像层被多个镜像共享,那只有当全部依赖该镜像层的镜像都被删除后,该镜像层才会被删除。

如果被删除的镜像上存在运行状态的容器,那么删除操作不会被允许。再次执行删除镜像命令之前,需要停止并删除该镜像相关的全部容器。

镜像实现原理

Docker镜像由一些松耦合的只读镜像层组成,Docker负责堆叠这些镜像层,并且将它们表示为单个统一的对象。镜像底层的实现依赖于联合文件系统(UnionFS)。

image.png

一种查看镜像分层的方式是通过 docker image inspect 命令:

$ docker image inspect ubuntu:latest
[
    {
       "Id": "sha256:bd3d4369ae.......fa2645f5699037d7d8c6b415a10",
       "RepoTags": [
           "ubuntu:latest"

       ...

       "RootFS": {
           "Type": "layers",
           "Layers": [
               "sha256:c8a75145fc...894129005e461a43875a094b93412",
               "sha256:c6f2b330b6...7214ed6aac305dd03f70b95cdc610",
               "sha256:055757a193...3a9565d78962c7f368d5ac5984998",
               "sha256:4837348061...12695f548406ea77feb5074e195e3",
               "sha256:0cad5e07ba...4bae4cfc66b376265e16c32a0aae9"
           ]
       }
    }
]

所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。每一层根据镜像的内容都有一个唯一的 ID 值,当不同的镜像之间有相同的镜像层时,便可以实现不同的镜像之间共享镜像层的效果。在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合。

从 Docker 1.10 版本开始,镜像就是一系列松耦合的独立层的集合。镜像本身就是一个配置对象,其中包含了镜像层的列表以及一些元数据信息。镜像层才是实际数据存储的地方(比如文件等,镜像层之间是完全独立的,并没有从属于某个镜像集合的概念)。

你可能感兴趣的:(docker)