晓夏

YoungCheung

Zhang Sir's technical way

Docker之镜像

浏览量:1387

镜像是Docker的三大核心概念之一。Docker运行容器前需要本地存在对应的镜像,如果镜像不在本地,docker会尝试先从默认镜像仓库下载(默认使用Docker Hub 公共注册服务器的仓库),用户也可以通过配置,使用自定义仓库。

一、获取镜像

镜像是Docker运行容器的前提,可以使用docker pull命令从网络上下载镜像。

格式:

docker pull NAME[:TAG]

对于Docker镜像来说,如果不显示的指定TAG,则默认会选择latest标签,即下载仓库中最新版本的镜像。

下面,演示从Docker Hub的Ubuntu仓库下载一个最新的Ubuntu操作系统镜像

$ sudo  docker pull ubuntu

Using default tag: latest
Trying to pull repository docker.io/library/ubuntu ... 
latest: Pulling from docker.io/library/ubuntu
b6f892c0043b: Pull complete 
55010f332b04: Pull complete 
2955fb827c94: Pull complete 
3deef3fcbd30: Pull complete 
cf9722e506aa: Pull complete 
Digest: sha256:382452f82a8bbd34443b2c727650af46aced0f94a44463c62a9848133ecb1aa8

该命令实际上下载的就是ubuntu:latest镜像,目前最新的是16.04

下载过程中我们可以看出,镜像一般由若干层组成,行首的b6f892c0043b这有的数字代表了各层ID,下载过程中会获取并输出镜像的各层信息。层(layer)其实是AUFS(Advance Union File System,一种联合文件系统)中的重要概念,是实现增量保存与更新的基础。

其实,还可以通过制定标签下载特定的某个镜像,例如:16.01标签的镜像。

$ sudo  docker pull ubuntu:16.04

上面两条命令都相当于

$ sudo  docker pull registry.hub.docker.com/ubuntu:latest

即从默认的注册服务器registry.hub.docker.com中的Ubuntu仓库来下载标记为latest的镜像

用户可以选择从其他注册服务器的仓库下载,此时,需要在仓库名称前指定完整的仓库注册服务器地址。例如从Dockerpool社区的镜像源dl.dockerpool.com下载最新Ubuntu镜像

$ sudo  docker pull dl.dockerpool.com:5000/ubuntu

下载到本地后,即可随时使用该镜像了,例如利用该镜像创建一个容器,在其中运行bash应用。

$ sudo  docker  run -t -i ubuntu /bin/bash
root@e29a9a911ae7:/#


二、查看镜像信息

使用docker images命令可以列出本地主机上已经有的镜像。

例如,列出本地刚从官方下载Ubuntu:16.04镜像.

$ sudo docker images

REPOSITORY              TAG        IMAGE ID          CREATED           SIZE
docker.io/ubuntu        latest     ebcd9d4fca80      11 days ago       117.9 MB
docker.io/hello-world   latest     c54a2cc56cbb      10 months ago     1.848 kB

在列出信息中心,可以看到几个字段信息:

  • 1、来自于那个仓库,比如Ubuntu

  • 2、镜像的标签信息,比如 latest

  • 3、镜像的ID号(唯一)

  • 4、创建时间

  • 5、镜像大小

其中镜像的ID信息十分重要,它唯一标识了镜像。例如Ubuntu仓库中有多少个镜像,通过TAG信息来区分发行版本,包括10.04、11.04、12.04、13.04、15.04、16.04等标签。

为了方便后续工作中使用这个镜像,还可以使用docker tag命令为本地镜像添加新的标签。例如添加一个新的Ubuntu:latest镜像标签如下:

$ sudo docker tag docker.io/ubuntu:latest ubuntu:latest

再次使用docker images列出本地主机上的镜像信息,可以看到多一个ubuntu:latest标签镜像。

$ sudo docker images

REPOSITORY              TAG       IMAGE ID          CREATED             SIZE
docker.io/ubuntu        latest    ebcd9d4fca80      11 days ago         117.9 MB
ubuntu                  latest    ebcd9d4fca80      11 days ago         117.9 MB
docker.io/hello-world   latest    c54a2cc56cbb      10 months ago       1.848 kB

可以看到这两个不同标签的镜像ID是完全一致的。说明它实际上指向的是同一个镜像文件,只是别名不同而已。标签在这里起了引用或快捷方式的作用。

使用docker inspect命令可以获取该镜像的详细信息。

$ sudo docker inspect ebcd9d4fca80

[
    {
        "Id": "sha256:ebcd9d4fca80e9e8afc525d8a38e7c56825dfb4a220ed77156f9fb13b14d4ab7",
        "RepoTags": [
            "docker.io/ubuntu:latest",
            "ubuntu:latest"
        ],
    ............................
]

docker inspect返回的是一个JSON格式信息,如果我们只要其中一项内容时,可以使用-f参数来指定,例如,获取镜像的Architecture信息:

$ sudo docker inspect -f {{".Architecture"}}  ebc
amd64

在指定镜像ID的时候,如果使用该ID的前若干个字符串组成的可区分字符串来代替完整ID。


三、搜寻镜像

使用docker search命令可以搜索远程仓库中共享的镜像,默认搜索Docker Hub官方仓库中的镜像,用法为docker search TERM,支持的参数包括:

--automated=false   #仅显示自动创建的镜像

--no-trunc=false       #输出信息不截断显示

-s ,--stars=0              #指定显示评价为指定星级以上的镜像

例如,搜索带MySQL关键词的镜像如下所示:

$ sudo docker search mysql
INDEX       NAME                                      DESCRIPTION                                     STARS OFFICIAL   AUTOMATED
docker.io   docker.io/mysql                           MySQL is a widely used, open-source relati...   4382  [OK]       
docker.io   docker.io/mysql/mysql-server              Optimized MySQL Server Docker images. Crea...   300              [OK]
docker.io   docker.io/centurylink/mysql               Image containing mysql. Optimized to be li...   51               [OK]
...........
docker.io   docker.io/captomd/mysql                   CaptoMD mysql configuration                     0                [OK]
docker.io   docker.io/cloudposse/mysql                Improved `mysql` service with support for ...   0                [OK]
docker.io   docker.io/nanobox/mysql                   MySQL service for nanobox.io                    0                [OK]
docker.io   docker.io/projectomakase/mysql            Docker image for MySQL                          0                [OK]

可以看到返回很多包含关键字的镜像,其中包括镜像的名字,描述,星级(表示该镜像的受欢迎程度)。是否官方创建,是否自动创建等。

默认的输出结果9将按照星级评价进行排序。官方的镜像说明是官方项目组创建和维护的,automated资源则允许用户验证镜像的来源和内容。


四、删除镜像

使用镜像的标签删除镜像

使用docker rmi命令可以删除镜像,命令格式为docker rmi IMAGE[IMAGE...],其中IMAGE可以为标签或者ID。

例如删除docker.io/ubuntu镜像,可以使用以下命令

$ sudo docker rmi docker.io/ubuntu
Untagged: docker.io/ubuntu:latest
Untagged: docker.io/ubuntu@sha256:382452f82a8bbd34443b2c727

查看镜像

$ sudo docker images
REPOSITORY              TAG       IMAGE ID        CREATED             SIZE
ubuntu                  latest    ebcd9d4fca80    11 days ago         117.9 MB
docker.io/hello-world   latest    c54a2cc56cbb    10 months ago       1.848 kB

当只剩下一个标签的时候要小心了。此时再使用docker rmi命令会彻底删除该镜像。

假设本地存在一个mysql:latest的镜像,且没有额外的标签指向它,执行docker rmi命令,可以看出它会删除这个镜像文件的所有AUFS层

$ sudo docker rmi mysql:latest
Untagged: mysql:latest
Untagged: docker.io/mysql@sha256:2f4b1900c0ee53f344564db8d85733bd8d70b0a78cd00e
Deleted: sha256:e799c7f9ae9cd01c2e78e26952767b96aef59a5e62f02305610448da47f8ca6b
Deleted: sha256:58876001b0c678675f58541cbd1f514ebdaac635da49a70c2d2168b6784f7ee8
Deleted: sha256:801e53b66e953dd4a4ea3bccce4fbdbe0fa5334065fb4c2a8e5b3a1c8e19cbc4
Deleted: sha256:bf5392d6855851dc449c8d62abce834c3e513c2515c4472e7fcf5c4bb253e641
Deleted: sha256:a47e14b81e4c40fa89c078dc6851aab95a1a505e6358afdba065150a53345875
Deleted: sha256:61c7c052dda6f7b2f8d123af9d2ccec7cbe2cd95add91687bb95adb0bb3c3502
Deleted: sha256:f441186a7f06991389303e4034c24abd131aa9a46c02a76df2f6f1d2022e93cd
Deleted: sha256:31afe1e3e87c20e365f7d019c747f4af2463726daef5183cf8ee47f692272526
Deleted: sha256:ba779192baede4aadd009c269406b5e8fd885c653ce19719316bf40cc66a6cf3
Deleted: sha256:2302bd8bbdd530199aa432c357a4da9eab2621c3ba4c4dacb4ea0f4afecbcae7
Deleted: sha256:00771f8e1e12bdfc9d47bc52a78e3f5ce5306a1caa5dd6237731cff9ca106040
Deleted: sha256:8d4d1ab5ff74fc361fb74212fff3b6dc1e6c16d1e1f0e8b44f9a9112b00b564f


使用镜像ID删除镜像

当使用docker rmi 命令后面跟上镜像的ID(也可以是ID能进行区分的部分前缀)时候=,会先尝试删除所有指向该镜像的标签,然后删除该镜像的本身。

注意:当有该镜像创建的容器存在时,镜像文件默认是无法删除的。例如

先利用Ubuntu镜像创建一个简单的容器,输出一句话"hello ! I am here!" 

$ sudo docker run ubuntu echo 'hello! I am here!'
hello! I am here!

使用docker ps -a 命令可以看到本机上存在的所有容器

 $ sudo docker ps -a
CONTAINER ID  IMAGE       COMMAND                 CREATED             STATUS                       PORTS  NAMES
2513e3394ffb  ubuntu      "echo 'hello! I am he"  52 seconds ago      Exited (0) 51 seconds ago          sick_dijkstra
e29a9a911ae7  ubuntu      "/bin/bash"             About an hour ago   Exited (0) About an hour ago       backstabbing_turing
ccc0659fbf64  hello-world  "/hello"                4 months ago        Exited (0) 4 months ago            thirsty_swanson

可以看到后台存在一个退出状态的容器,是刚基于Ubuntu:latest镜像创建的。

试图删除该镜像,docker会提示容器正在运行,无法删除

$ sudo docker rmi ubuntu

Error response from daemon: conflict: unable to remove repository reference "ubuntu"
 (must force)- container e29a9a911ae7 is using its referenced image ebcd9d4fca80

如果想强制删除镜像,可以使用-f参数:

$ sudo docker rmi -f  ubuntu

Untagged: ubuntu:latest
Deleted: sha256:ebcd9d4fca80e9e8afc525d8a38e7c56825dfb4a22

注意:正确的删除方法是先删除依赖该镜像的容器,再来删除镜像

此时查看会发现镜像已经被删除:

 $ sudo docker images
REPOSITORY          TAG        IMAGE ID       CREATED             SIZE


五、创建镜像

创建镜像的方法有三种:

1、基于已经有镜像的容器创建

2、基于本地模板导入

3、基于Dockerfile创建

我们这里介绍前两种,最后一种后面单独介绍。


基于已有镜像的容器创建

该方法是使用docker commit 命令,其格式为:

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

主要选项包括:

1、-a ,--author=""            #作者信息

2、-m,--message=“”  #提交信息

3、-p,--pause=true        #提交时暂停容器运行

下面将演示如何使用该命令创建一个新的镜像。首先启动一个镜像,并在其中修改操作,例如创建一个test文件,之后退出:

$ sudo docker run -ti ubuntu:14.04 /bin/bash
root@c14c52a30a6c:/# touch test
root@c14c52a30a6c:/# exit
exit

记住容器的ID为c14c52a30a6c

此时该容器和原有的镜像相比发生了变化,可以使用docker commit 命令来提交一个新的镜像。提交时可以使用ID或者名称来指定容器:

$ sudo docker commit -m "new commit" -a 'zhangyang' c14c52a30a6c test
sha256:1210f8e9a7c99796c89b1958fc9fad53fea706ac6ed04a921385aa8b95966830

此时查看镜像列表,即可以看到最新创建的镜像

 $ sudo docker images
REPOSITORY          TAG           IMAGE ID            CREATED             SIZE
test                latest        1210f8e9a7c9        58 seconds ago      188 MB
docker.io/ubuntu    14.04         2ff3b426bbaa        11 days ago         188 MB

基于本地模板导入

这里我们下载一个centos7的镜像,然后导入:

镜像下载地址:http://download.openvz.org/template/precreated/centos-7-x86_64.tar.gz

$ sudo cat centos-7-x86_64.tar.gz|docker import - centos:7

然后查看导入的镜像,已经存在了。

 $ sudo docker images
REPOSITORY          TAG        IMAGE ID            CREATED             SIZE
centos              7          5205f1ad0f34        4 seconds ago       589.2 MB
test                latest     1210f8e9a7c9        18 minutes ago      188 MB
docker.io/ubuntu    14.04      2ff3b426bbaa        11 days ago         188 MB


六、存出和载入镜像

可以使用docker save 和docker load命令来存出和载入镜像。


存出镜像

如果要将镜像存出到本地,可以使用docker save命令,例如:存出本地的centos:7镜像为centos.7.tar.gz

 $ sudo docker images
 
REPOSITORY          TAG        IMAGE ID            CREATED             SIZE
centos              7          5205f1ad0f34        4 seconds ago       589.2 MB
test                latest     1210f8e9a7c9        18 minutes ago      188 MB
docker.io/ubuntu    14.04      2ff3b426bbaa        11 days ago         188 MB

$ sudo docker save -o centos_7.tar.gz centos


载入镜像

可以使用docker load从存出的本地文件再导入到本地仓库镜像,例如从文件centos.7.tar.gz导入镜像到镜像列表

$ sudo docker load --input centos_7.tar.gz

或者

$ sudo docker load < centos_7.tar.gz

这将导入镜像以及其相关的元数据信息(包括标签等)。可以使用docker images查看。


七、上传镜像

上传镜像可以使用docker push命令上传到镜像仓库,默认上传到dockerHub官方仓库(需要登录),命令格式为:docker push NAME[:TAG]

用户需要到DockerHub注册后才可上传自制镜像,例如用户user上传本地的centos:7.3.1611镜像,可以先添加新的标签188xxxxxxx/centos:7.3.1611,然后用docker push命令上传镜像

$ sudo docker pull centos:7.3.1611
$ sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
18813001922/study   latest              5205f1ad0f34        24 hours ago        589.2 MB
centos              7                   5205f1ad0f34        24 hours ago        589.2 MB
docker.io/ubuntu    latest              ebcd9d4fca80        12 days ago         117.9 MB
docker.io/centos    7.3.1611            67591570dd29        5 months ago        191.8 MB

$ sudo docker tag centos:7.3.1611 188xxxxxxxx/centos:7.3.1611
$ sudo docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: 188xxxxxxx
Password: 
Login Succeeded
$ sudo docker push 18813001922/centos:7.3.1611


神回复

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。