Docker 学习 | 第二篇:使用镜像

前言

在Docker的概念中,镜像是非常重要的概念,因为Docker在运行容器之前需要本地存在对应的镜像,一个镜像可以创建多个容器。如果本地没有相应的镜像,会先从Docker Hub仓库中先把镜像下载回到本地,再运行容器。

本篇文章主要介绍镜像的一系列操作方式:

  • 搜索镜像
  • 下载镜像
  • 查看镜像信息
  • 删除镜像
  • 创建镜像
  • 镜像迁移
  • 上传镜像

本篇例子使用的Docker版本如下:

[root@VM_0_14_centos ~]# docker -v
Docker version 18.02.0-ce, build fc4de44

搜索镜像

用户可以根据关键字搜索Docker Hub存在的相关镜像,使用如下命令:

docker search [OPTIONS] TERM

该命令支持的参数如下:

  1. -f,--filter filter 根据过滤条件输出信息
  2. --format string 根据一种go模板输出内容
  3. --no-trunc 不要截断显示输出

下面一个例子表示搜索nginx镜像,评价为星级为100以上的镜像,并且不截断输出

[root@VM_0_14_centos ~]# docker search --no-trunc --filter=stars=100 nginx
NAME                                     DESCRIPTION                                                                      STARS               OFFICIAL            AUTOMATED
nginx                                    Official build of Nginx.                                                         8157                [OK]
jwilder/nginx-proxy                      Automated Nginx reverse proxy for docker containers                              1296                                    [OK]
richarvey/nginx-php-fpm                  Container running Nginx + PHP-FPM capable of pulling application code from git   530                                     [OK]
jrcs/letsencrypt-nginx-proxy-companion   LetsEncrypt container to use with nginx as proxy                                 331                                     [OK]
kong                                     Open-source Microservice & API Management layer built on top of NGINX.           168                 [OK]

可以看到镜像输出都stars列都是100以上的,并且输出结果是按照星级评价排序的

输出的结果包括了5列。分别的意思是:

  • 镜像名字
  • 镜像描述
  • 镜像星级(受欢迎程度)
  • 是否官方创建
  • 是否自动创建。

下载镜像

这里我们以上面搜索出来的镜像进行下载,命令如下:

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

参数如下:

  1. -a,--all-tag 下载所有标签的镜像
  2. --disable-content-trust 跳过镜像验证(默认true)

下面例子下载nginx镜像:

[root@VM_0_14_centos ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
2a72cbf407d6: Pull complete
eccc107d7abd: Pull complete
76aa3935d77c: Pull complete
Digest: sha256:f6e250eaa36af608af9ed1e4751f063f0ca0f5310b1a5d3ad9583047256f37f6
Status: Downloaded newer image for nginx:latest

对于拉取镜像,如果不指定TAG,则默认使用latest标签。使用latest标签意味着镜像内容会跟踪最新非稳定版本,内容是不稳定的。从稳定性来说,不要在生产环境使用latest标签。

镜像一般由若干个层组成,上面输出的2a72cbf407d6实际上就是该层的唯一id,这个id有64个字符,此处输出省略了。当不同的镜像使用相同的层,本地仅仅存储一份内容,减少了所需的空间。上面的这个nginx镜像中共下载了3层镜像。

如果不是很明白层的概念,请看Docker学习 | 第一篇:Docker简介以及安装中关于镜像的描述。

此外,上述命令中,镜像的名字应该添加仓库地址,以区分本地仓库和Docker Hub,只不过使用Docker Hub可以省略仓库地址,上述命令的完全形式如下:

docker pull registry.docker-cn.com/library/nginx:latest

查看镜像信息

列出镜像

使用如下命令列出所有镜像

docker images
[root@VM_0_14_centos ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              73acd1f0cfad        5 days ago          109MB

列出的信息每一列的信息为:仓库名/标签/镜像ID/创建时间/镜像大小

镜像的ID为镜像的唯一ID,一般在使用镜像ID的时候,可以使用ID的前几个字符来区分不同的镜像。

镜像的标签标记了同一个仓库中不同的镜像。

关于镜像大小信息只是表示镜像的逻辑大小,由于镜像是由若干个层组成的,所以如果和其他镜像共用同一个层,所占的存储空间会更小。

更多的命令参数查看帮助文档

docker images --help
查看镜像详细信息

命令如下:

docker inspect NAME|ID

使用该命令可以查看镜像的详细信息,可以通过镜像名称或者镜像id查看。

比如,nginx镜像的ID为:73acd1f0cfadf6f56d30351a…

可以通过如下命令查看详细信息:

docker inspect 73ad
docker inspect nginx

上述两个命令都可以,输出信息很多,这里就不贴出来了。

查看镜像历史

命令如下:

docker history IMAGE

比如我要查看nginx的镜像历史:

docker history nginx 

这样就可以看到镜像中每一层的内容。

删除镜像

命令如下:

docker rmi  IMAGE | ID

删除镜像可以使用镜像名字或者镜像ID来删除,使用镜像名字删除请带上标签。

创建镜像

创建镜像有3中方式:

  • 使用commit命令创建
  • 使用模板创建
  • 使用Dockfile创建
使用commit命令创建

使用commit来创建容器是这样的一种场景:使用某个镜像运行了一个容器,然后进入了这个容器操作了某些命令导致该容器的环境(可以理解为文件变化)发生变化的时候。你就可以使用commit命令来根据该容器当前的状态来构建一个镜像。

我们以上述下载的nginx镜像为例。执行命令(下面命令是容器相关的,如果一时不明白可以先不用理解,笔者会添加一些说明)

docker run --name nginx -d -p 80:80 nginx

上述命令是以nginx运行了一个容器,命名为nginx,并且映射了80端口。

然后我们通过浏览器访问:http://localhost/则会出现Welcome to nginx!的界面。

我们想改了这个欢迎页面,执行如下命令:

docker exec -it nginx /bin/bash

这个命令的意思是,进入正在运行的nginx容器。并执行bash shell程序

这个时候我们发现已经进入了容器。那么开始修改nginx的欢迎页面吧。nginx镜像的欢迎页面存储路径在/usr/share/nginx/html/index.html

我们只需要修改了这个文件就可以了

输入以下命令:

echo '<h1>Hello, World!</h1>' > /usr/share/nginx/html/index.html

然后输入exit命令退出容器。

然后刷新浏览器,会发现浏览器显示变成了 Hello World!了。

到了目前为止。我们修改了容器的环境。此时我们就可以根据这个容器来建立一个新的镜像。

docker commit -a "wangjianfeng" -m "修改了主页" nginx nginx:v2

上述命令中-a表示修改这个镜像的作者,-m表示修改的描述信息,后面的nginx表示容器的名字(不是镜像的名字)nginx:v2表示新的镜像的名称以及TAG.

屏幕输出如下内容:

[root@VM_0_14_centos ~]# docker commit -a "wangjianfeng" -m "修改了主页" nginx nginx:v2
sha256:50d55f455c893662a59bafc86a3ebedfb2312c08652d647d5eb00ecf6a1e55a2

输出了一个很长的ID,这个ID就是新的镜像的ID

此时已经创建了一个新的镜像,我们通过docker images会看到nginx的TAG多了一个v2.

通过命令:

docker history nginx:v2

可以看到多了一层名为 “修改了主页” 的提交。至此,我们拥有了两个镜像:nginx:latestnginx:v2

慎用commit命令

慎用commit命令

慎用commit命令

慎用commit命令

慎用commit命令

重要事情说五遍

commit命令使用于一些特殊的应用场合,比如被入侵后保存现场,虽然可以使用commit来创建新的镜像。但是通常不推荐使用这个命令来创建镜像。

通常来说,建议使用Dockfile来创建镜像。原因如下:

  • 在Dokcer容器中做的修改并不简单,比如我们仅仅修改了index.html。但是这个操作会导致其他的很多文件被改动了。你可以使用docker diff nginx来查看容器的变化。会发现有很多文件被改变了。这还是修改了一个文件这么简单的操作,如果是安装软件等等其他复杂的操作,会有更多内容被修改。最终会导致镜像很臃肿。
  • 使用commit命令,对于容器的操作,是进入容器之后执行的,具体执行了什么命令,具体怎么生成镜像只有操作者知道,可能过了一点时间之后操作者也会忘记了。使用docker diff以及docker history可以找到一些线索,但是没有具体的操作内容记录,维护起来非常麻烦。
使用模板创建

这种方式是由于历史原因,但是笔者在实际使用Docker的情况下基本没有使用这个镜像。。所以这里不介绍了。

使用Dockerfile创建

使用Dockerfile创建的知识内容比较多,篇幅过多,后面会有文章专门介绍这种方式。这里只需有一种基本认识即可。

镜像迁移

镜像迁移这个功能通常用于将镜像从一台机器移到另一台机器

导出镜像
docker save -o filename IMAGE

这个命令只有一个参数。-o表示输出到文件,如下命令:

docker save -o nginx.tar nginx

表示保存到nginx.tar文件中.

导入镜像

命令如下:

docker load --input filename
[root@VM_0_14_centos ~]# docker load --input nginx.tar
3358360aedad: Loading layer [==================================================>]  58.44MB/58.44MB
c632afbadb38: Loading layer [==================================================>]  53.91MB/53.91MB
180ab8f004dc: Loading layer [==================================================>]  3.584kB/3.584kB
Loaded image: nginx:latest

上传镜像

有些时候我们想要把镜像上传到Docker Hub或者私有的仓库,可以使用如下命令:

docker push NAME[:TAG]

默认情况下会上传到Docker Hub, 上传Docker Hub需要你有一个账号密码,会提示你输入。如果上传私有仓库有则需要带上地址.

总结

此篇文章主要记录了Docker对于镜像的基本操作,在这里对各个命令做了简单的介绍。如果想深入了解,每个命令都可以使用 --help来查看使用文档。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐