1 引言
将docker与汽车生产线类比,若是说docker引擎是汽车生产车间,那么容器就是最终的产品——汽车,而本节要介绍的镜像就如同汽车设计图纸,其重要性不言而喻——只有有了设计图(镜像),才能生产汽车(汽车)。
2 镜像管理
2.1 获取镜像
刚安装好的docker里面是没有镜像的,但咱们能够从开源的镜像仓库中下载镜像,docker官方提供的docker hub就是最大的一个docker仓库,里面有全球各地用户提供的各式各样的docker镜像供咱们下载使用。在下载镜像以前,咱们先来熟悉一下docker镜像下载命令和相关知识。
docker [image] pull 仓库名[:标签]
上行命令就是咱们经常使用的docker镜像下载命令,其中,仓库名指定咱们要从哪一个仓库下载的镜像,标签是指镜像便签,一般指代的是版本信息,例如:ubuntu:16.04和ubuntu:18.04分别指代ubuntu仓库中16.04版本的ubuntu和18.04版本的ubuntu镜像。命令中image和标签参数可加可不加,当省略标签参数时,即指使用默认的latest标签,也就是说,下载指定仓库中的的最新版本。下载ubuntu最新版本:
注意:latest标签会动态跟随最新版本变动,这意味着镜像内容也是动态变化的,因此出于稳定性考虑,在生产环境中,不要在生产环境中使用latest标签。
pull命令默认从官方docker hub仓库中下载镜像,因此,上行命令中并无指定完整仓库名,若是须要从其余非官方仓库下载镜像,则须要指定完整仓库名,例如,从网易很是的镜像源中下载ubuntu:18.04镜像:
$ docker pull hub.c.163.com/public/ubuntu18.04
2.2 查看及查找镜像
(1)查看本机上全部镜像基本信息:
(2)查看指定镜像详细信息
$ docker [image] inspect 仓库名:标签
例:查看上文中下载的ubuntu:18.04镜像详细信息
$ docker inspect ubuntu:18.04
(3)查看镜像各层建立信息
(4)搜索镜像
$ docker search [选项] 关键词
命令中,能够经过选项指定输出内容格式、数量、部分过滤条件等,关键词是指搜索关键字。
例如:查找ubuntu相关镜像
$ docker search ubuntu
2.3 删除镜像
删除镜像可使用一下两种命令格式:
$ docker rmi 仓库名:标签或镜像id
$ docker image rm 仓库名:标签或镜像id
定位一个镜像能够经过"仓库名:标签"和镜像id两种方式,因此,在删除镜像时,咱们也能够经过这两种方式来指定要删除的镜像,也便是上面两行命令中的仓库名:标签或镜像id。
删除镜像时须要注意,每次运行删除镜像命令事实上只是删除指定镜像的一个标签,只有当该镜像仅有一个标签时,使用删除镜像命令才会真正删除镜像。啥?一个镜像还有多个标签,没错,人类除了真名都还有网名、小名、外号呢。在演示删除镜像前,咱们先尝试给镜像添加标签。
先查看本地有哪些镜像:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 18.04 7698f282e524 7 days ago 69.9MB hello-world latest fce289e99eb9 4 months ago 1.84kB
给hello-World镜像添加一个标签:
$ docker tag hello-world:latest bye-world:8000
若是成功,没有任何提示,再次查看本地全部镜像:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 7698f282e524 7 days ago 69.9MB
bye-world 8000 fce289e99eb9 4 months ago 1.84kB
hello-world latest fce289e99eb9 4 months ago 1.84kB
看,出现了bye-world镜像,但咱们可没有新建或者下载镜像,这就是咱们刚才为hello-World建立的新标签,看着他们相同的镜像id你就知道他们是同一个镜像了。接下来尝试删除镜像:
$ docker rmi bye-world:8000
Untagged: bye-world:8000
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 7698f282e524 7 days ago 69.9MB
hello-world latest fce289e99eb9 4 months ago 1.84kB
果真如上文所说,bye-world:8000被删除了,但事实上它所指向的镜像被没有被真正删除,由于这个镜像还有一个标签存在。咱们继续参数删除hello-world:latest镜像:
$ docker rmi hello-world:latest
Error response from daemon: conflict: unable to remove repository reference "hello-world:latest" (must force) - container 53c855a9d4a9 is using its referenced image fce289e99eb9
懵逼了,失败了,咋回事?由于尚有依赖于该镜像的容器存在,因此产生冲突。这时候要删除镜像,就必须添加-f参数,强制执行:
$ docker rmi -f hello-world:latest
Untagged: hello-world:latest
Untagged: hello-world@sha256:6f744a2005b12a704d2608d8070a494ad1145636eeb74a570c56b94d94ccdbfc
Deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 7698f282e524 7 days ago 69.9MB
只剩下一个ubuntu镜像,证实删除成功。
3 建立镜像
建立镜像的方法有三种:基于已有镜像的容器建立镜像、基于dockerfile建立、基于本地模板导入,这里咱们只介绍前两种。
3.1 基于已有镜像容器建立镜像
基于已有镜像容器建立镜像需经过docker commit命令,命令格式以下:
$ docker commit [选项] 容器名或容器id [<仓库名>[:<标签名>]]
在使用docker commit命令建立镜像以前,咱们先得有一个容器。
$ docker run -it ubuntu:18.04 /bin/bash
root@001b647aad4e:/#
docker run命令时使用镜像建立一个容器的命令,具体个参数什么含义,咱们后面继续学习。能够看到,运行这一命令后,启动了一个id为001b647aad4e的容器,记住这一id,后面要用到。
咱们继续在这一容器里git环境:
root@001b647aad4e:/# git --version
bash: git: command not found
能够看到,刚建立的容器里面刚开始是没有git的,咱们安装一个:
root@001b647aad4e:/# apt-get update
root@001b647aad4e:/# apt install git
root@001b647aad4e:/# git --version
git version 2.17.1
能够看到,git安装成功。
退出容器,而后使用刚才的容器建立一个镜像。
root@001b647aad4e:/# exit
exit
$ docker commit -m "Add git in ubuntu18.04" -a "God" 001b647aad4e ubuntu_git:1.0
sha256:30e6c7c480dc44743f0f030f4904089fb8568ad2333f8de3a22c4f6a71fdb451
成功建立镜像,并返回了镜像id信息。
查看一下本地镜像:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu_git 1.0 30e6c7c480dc About a minute ago 189MB
ubuntu 18.04 7698f282e524 8 days ago 69.9MB
能够看到,镜像建立成功。以ubuntu_git为基础,建立一个容器,新容器也会有git环境,换句话说,docker commit至关因而对001b647aad4e进行了一次备份。
docker commit命令建立镜像虽然简单直观,可是在时间生产中并不建议用,由于使用docker commit命令建立的镜像没法追踪镜像的建立过程,形成镜像建立过程难以重复、维护困难,且容易出现镜像臃肿的镜像。因此,在实际应用中,更推荐使用下一小节要说到的使用dockerfile文件建立镜像的方法。
3.2 使用dockerfile建立镜像
dockerfile是一个文本文件,经过每一条指令构建镜像一层,或者说dockerfile每一条指令定义了镜像每一层如何构建,因此,使用dockerfile建立镜像的过程彻底是透明的、可重复的,很好的你不了docker commit命令建立镜像的不足。
还以上一小节中定制一个包含git环境的镜像为例,不过此次咱们使用dockerfile来建立。
首先建立一个目录做为建立镜像的上下文路径,并进入该目录:
$ mkdir ubuntu_dockerfile_git
$ cd ubuntu_dockerfile_git/
而后建立建立dockerfile文件:
开始编辑dockerfile,在dockerfile内写入一下内容:
FROM ubuntu:18.04
RUN apt-get update \
&& apt-get install -y git \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
先来解释一下上面写入dockerfile文件的内容:
FROM ubuntu:18.04的意思是以ubuntu:18.04镜像为基础来构建新的镜像,每个新的镜像,都必须有一个基础镜像,FROM命就是用于指定基础镜像,并且须要注意的是,FROM命令必须位于整个过程的第一行。
第二行的RUN命令是用来执行命令行操做。那为什么上面的RUN命令执行的4条命令行操做都用一个RUN命令来执行呢?事实上,每一个命令行操做都使用一个RUN命令来执行也不会出错,但,上面提到过,dockerfile中,每一条指令都会建立一层,若是每一条命令行操做的用一个RUN命令执行,这种写法就建立了4层,建立出来的镜像就显得臃肿,也增长了部署时间,另外从功能上来讲,这4条命令行操做都是为了安装一个git,不必拆分。docker镜像总层数不得操做127层。
如今能够用建立好的dockerfile文件建立镜像了,使用的是docker build命令,命令格式以下:
docker build [选项] <上下文路径/URL>
假定咱们将要建立镜像的镜像名为ubuntu_dockerfile_git,使用docker build以下:
$ docker build -t ubuntu_dockerfile_git:1.0 .
在一大段的输出以后能够看到:
Successfully built 6e703a3b11e2
Successfully tagged ubuntu_dockerfile_git:1.0
说明镜像建立成功。再次查看本地镜像:
$ docker images
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu_dockerfile_git 1.0 6e703a3b11e2 About a minute ago 163MB
ubuntu_git 1.0 30e6c7c480dc 20 hours ago 189MB
ubuntu 18.04 7698f282e524 9 days ago 69.9MB
果真有刚建立的ubuntu_dockerfile_git,咱们用它来建立一个容器:
$ docker run -it ubuntu_dockerfile_git:1.0 /bin/bash
root@18c03ae954ab:/# git --version
git version 2.17.1
能够看到,刚启动的容器里果真有git。
dockerfile是用的最多的一种镜像建立方法,涉及到的内容也较多,在上面的应用中,咱们只介绍了FROM、RUN指令,除此以外还有COPY、CMD、ADD等众多指令没有涉及到,你们能够参考纯洁的微笑前辈的
这篇博客,写得很详细且通俗易懂。
4 总结
本篇博文介绍了对docker镜像的管理,包括镜像查看、删除、建立等操做。但做为docker的核心内容,镜像管理可毫不仅仅包含这点点只是,例如镜像存出、载入、上传等内容就没有涉及到。本文只做为入门阶段抛砖引玉吧。