镜像与容器之间的关系:

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被 创建、启动、停止、删除、暂停等。

为什么使用数据卷(Volume):

容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。

按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储 层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者 绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷 后,容器可以随意删除、重新 ,数据却不会丢失。

鲸鱼图标中的鲸鱼叫 Moby

1.获取镜像:

命令:

docker pull [选项] [Docker Registry地址]<仓库名>:<标签> 

具体的选项可以通过 命令看到,这里我们说一下镜像名称 的格式。

  • Docker Registry地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。
  • 仓库名:如之前所说,这里的仓库名是两段式名称,既<用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为library ,也就是官方镜 像。软件名即ubuntu等

说明:

镜像是Docker运行容器的前提。
    用户可以使用docker pull 命令从网络上下载镜像。对于镜像来说,如果不显式地指定tag,则默认会选择latest标签,即下载仓库中最新版本的镜像。

默认是从docker官方下载的。只有docker官方的可以不需要增加命名空间直接进行下载。

举例:

userdeMBP:~ user$ docker pull ubuntu:14.04
14.04: Pulling from library/ubuntu
aa1a66b8583a: Pull complete
aaccc2e362b2: Pull complete
a53116a2808f: Pull complete
b3a7298e318c: Pull complete
Digest: sha256:f961d3d101e66017fc6f0a63ecc0ff15d3e7b53b6a0ac500cd1619ded4771bd6
Status: Downloaded newer image for ubuntu:14.04

上面的命令中没有给出 Docker Registry 地址,因此将会从 Docker Hub 获取镜像。而镜像名称是ubuntu:14.04,因此将会获取官方镜像library/ubuntu仓库中标签为14.04的镜像。

从下载过程中可以看到我们之前提及的分层存储的概念,镜像是由多层存储所构 成。

下载也是一层层的去下载,并非单一文件。

下载过程中给出了每一层的 ID 的前 12 位。并且下载结束后,给出该镜像完整的sha256 的摘要,以确保下载一 致性。

运行

打算启动ubuntu里面的bash,并且进行交互式操作的话:

userdeMBP:~ user$ docker run -ti --rm ubuntu:14.04 bash
root@b18485192e24:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="14.04.5 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.5 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
root@b18485192e24:/# exit
exit
userdeMBP:~ user$

解释:

  • -ti : 这是两个参数,一个是-i :交互式操作,一个是 -t:终端。我们 这里打算进入 bash执行一些命令并查看返回结果,因此我们需要交互式终端
  • --rm : 这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 运行docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 --rm 可以避免浪费空间。
  • ubuntu:14.04 :这是指用 ubuntu:14.04镜像为基础来启动容器。
  • bash :放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是bash。

在这个例子中,我们执行了 cat /etc/os-release ,这是 Linux 常用的查看当前系统版本的命令,从返回的结果可以看到容器内是 Ubuntu 14.04.5 LTS系统。

最后我们通过 exit退出了这个容器。

2.列出镜像

要想列出已经下载下来的镜像,可以使用 docker images命令

userdeMBP:~ user$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04 f17b6a61de28 weeks ago 188MB
alpine latest 196d12cf6ab1 months ago .41MB
hello-world latest 4ab4c602aa5e months ago .84kB

列表包含了仓库名、标签、镜像 ID、创建时间以及所占用的空间

镜像 ID 则是镜像的唯一 标识,一个镜像可以对应多个标签。

因此,ubuntu:14.04和 ubuntu:latest拥有相同的 ID,因为它们对应的是同一个镜像。

虚悬镜像 (dangling image)

上面的镜像列表中,还可以看到一个特殊的镜像,这个镜像既没有仓库名,也没有标签,均为<none>

 REPOSITORY         TAG        IMAGE ID            CREATED             SIZE
<none> <none> 00285df0df87 days ago MB
mongo 3.2 fe9198c04d62 days ago MB

这个镜像原本是有镜像名和标签的,原来为mongo:3.2,随着官方镜像维护,发布了新版本后,重新docker pull mongo:3.2时,mongo:3.2 这个镜像名被转移到了新下载的镜像身上,而旧的同名镜像上的这个名称则被取消,从而成为了<none>。除了docker pull可能导致这种情况, docker buil也同样可以导致这种现象。由于新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为<none>的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image) ,可 以用下面的命令专门显示这类镜像:

 userdeMBP:~ user$ docker images -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 00285df0df87 days ago MB
一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除:
$ docker rmi $(docker images -q -f dangling=true)

-f:过滤器,下面有讲

-q, --quiet   只展示镜像的IDs

即删除由$(docker images -q -f dangling=true)命令得到的镜像的IDs

中间层镜像

为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像。所以在使用一段时间后,可能会看到一些依赖的中间层镜像。

默认的 列表中只会显示顶层镜像,如果希望显示包括中间层镜像在内的所有镜像的话,需要加-a参数:

$ docker images -a

这样会看到很多无标签的镜像,与之前的虚悬镜像不同,这些无标签的镜像很多都是中间层镜像,是其它镜像所依赖的镜像。

这些无标签镜像不应该删除,否则会导致上层镜像因为依赖丢失而出错。

实际上,这些镜像也没必要删除,因为之前说过,相同的层只会存一遍,而这些镜像是别的镜像的依赖,因此并不会因为它们被列出来而多存了一份,无论如何你也会需要它们。只要删除那些依赖它们的镜像后,这些依赖的中间层镜像也会被连带删除。


列出部分镜像

不加任何参数的情况下, 会列出所有顶级镜像,但是有时候我们 只希望列出部分镜像。 有好几个参数可以帮助做到这个事情。

1.根据仓库名列出镜像 ,即 docker images +仓库名:

$ docker images ubuntu

2.列出特定的某个镜像,也就是说指定仓库名和标签 ,即 docker images +仓库名:标签

$ docker images ubuntu:16.04

3.使用过滤器参数 --filter(或-f)

比如,我们希望看到在镜像hello-world之后建立的镜像,可以用下面的命令:

userdeMBP:~ user$ docker images -f since=hello-world
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04 f17b6a61de28 weeks ago 188MB
alpine latest 196d12cf6ab1 months ago .41MB

想查看某个位置之前的镜像也可以,只需要把since换成before即可

此外,如果镜像构建时,定义了LABEL,还可以通过 LABEL来过滤:

 docker images -f label=com.example.version=0.1

以特定格式显示

默认情况下, 会输出一个完整的表格,但是我们并非所有时候都 会需要这些内容。

比如,刚才删除虚悬镜像的时候,我们先是需要利用docker images命令把所有的虚悬镜像的 ID 列出来,然后才将这些值交给 命令docker rmi ,作 为其参数来删除指定的这些镜像。

这个时候就用到了-q参数,即只得到镜像的IDs值:

userdeMBP:~ user$ docker images -f since=hello-world
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04 f17b6a61de28 weeks ago 188MB
alpine latest 196d12cf6ab1 months ago .41MB userdeMBP:~ user$ docker images -q -f since=hello-world
f17b6a61de28
196d12cf6ab1

另外一些时候,我们可能只是对表格的结构不满意,希望自己组织列;或者不希望有标题,这样方便其它程序解析结果等,这就用到了 Go 的模板语法:

比如,下面的命令会直接列出镜像结果,并且只包含镜像ID和仓库名:

userdeMBP:~ user$ docker images --format "{{.ID}}: {{.Repository}}"
f17b6a61de28: ubuntu
196d12cf6ab1: alpine
4ab4c602aa5e: hello-world

--format string  : Pretty-print images using a Go template 使用Go模版打印镜像

或者打算以表格等距显示,并且有标题行,和默认一样,不过自己定义列:

userdeMBP:~ user$ docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID REPOSITORY TAG
f17b6a61de28 ubuntu 14.04
196d12cf6ab1 alpine latest
4ab4c602aa5e hello-world latest

3.删除本地镜像

格式:docker rmi [选项] <镜像1> [<镜像2>...]

⚠️docker rm命令是删除容器

用 ID、镜像名(即<仓库名>:<标签>)、摘要(DIGEST)都能删除镜像,一般ID取前3个字符,足够区分于别的镜像即可

一般的docker images命令隐藏了DIGEST信息,如果要查看镜像的摘要,要使用--digests参数,如:

userdeMBP:~ user$ docker images --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
nginx v3 <none> beda48ecf85b hours ago 109MB
nginx v2 <none> 5dda481d7ed1 hours ago 109MB
nginx latest sha256:5d32f60db294b5deb55d078cd4feb410ad88e6fe77500c87d3970eca97f54dba 568c4670fa80 weeks ago 109MB

然后你就可以删除nginx:

userdeMBP:~ user$ docker rmi -f nginx@sha256:5d32f60db294b5deb55d078cd4feb410ad88e6fe77500c87d3970eca97f54dba
Untagged: nginx@sha256:5d32f60db294b5deb55d078cd4feb410ad88e6fe77500c87d3970eca97f54dba

Untagged 和 Deleted

之前有说过,镜像的唯一标识是其 ID 和摘要,而一个镜像可以有多个标签。

所以如果删除时使用的是镜像名(即<仓库名>:<标签>)的方法,那么可能会出现两类删除行为:

  • Untagged:即镜像的所有标签都取消了,该镜像被删除了
  • Deleted:即可能只是删除了指定的镜像的某个标签

因为一个镜像可以对应多个标签,因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么 删除行为就不会发生。

所以并非所有的docker rmi都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。

用 docker images 命令来配合

可以使用 docker images -q来配合使用 ,这样可以成批的删除希望删除的镜像。比如之前我们介绍过的,删除虚悬镜像的指令是:

 $ docker rmi $(docker images -q -f dangling=true)

比如,我们需要删除所有仓库名为 redis的镜像:

 $ docker rmi $(docker images -q redis)

或者删除所有在 mongo:3.2 之前的镜像:

 $ docker rmi $(docker images -q -f before=mongo:3.2)

Docker技术入门与实战 第二版-学习笔记-1-镜像的更多相关文章

  1. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-2-driver

    1>使用的driver 1〉generic 使用带有SSH的现有VM/主机创建机器. 如果你使用的是机器不直接支持的provider,或者希望导入现有主机以允许Docker Machine进行管 ...

  2. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-3-容器访问控制和自定义网桥

    1)容器访问控制 容器的访问控制,主要通过 Linux 上的 iptables防火墙来进行管理和实现. iptables是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 ...

  3. Docker技术入门与实战 第二版-学习笔记-6-仓库

    仓库(Repository)是集中存放镜像的地方 一个容易混淆的概念是注册服务器(Registry). 实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像. ...

  4. Docker技术入门与实战 第二版-学习笔记-2-镜像构建

    3.利用 commit 理解镜像构成 在之前的例子中,我们所使用的都是来自于 Docker Hub 的镜像. 直接使用这些镜像是可以满足一定的需求,而当这些镜像无法直接满足需求时,我们就需要定制这些镜 ...

  5. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-1-cli

    Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境 Docker Machine是一种工具,它允许你在虚拟主机 ...

  6. Docker技术入门与实战 第二版-学习笔记-7-数据管理(volume)

    Docker 数据管理 为什么要进行数据管理呢?因为当我们在使用container时,可能会在里面创建一些数据或文件,但是当我们停掉或删除这个容器时,这些数据或文件也会同样被删除,这是我们并不想看见的 ...

  7. Docker技术入门与实战 第二版-学习笔记-5-容器-命令及限制内存与cpu资源

    1.启动容器 启动容器有两种方式: 基于镜像新建一个容器并启动 将在终止状态(stopped)的容器重新启动 1)新建并启动——docker run 比如在启动ubuntu:14.04容器,并输出“H ...

  8. Docker技术入门与实战 第二版-学习笔记-3-Dockerfile 指令详解

    前面已经讲解了FROM.RUN指令,还提及了COPY.ADD,接下来学习其他的指令 5.Dockerfile 指令详解 1> COPY 复制文件 格式: COPY  <源路径> .. ...

  9. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-1-单个host上的容器网络

    Docker 中的网络功能介绍 Docker 允许通过外部访问容器或容器互联的方式来提供网络服务 1) 外部访问容器 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -p或 -P参数 ...

随机推荐

  1. 积分之迷-2015决赛C语言B组第一题

    标题:积分之迷 小明开了个网上商店,卖风铃.共有3个品牌:A,B,C. 为了促销,每件商品都会返固定的积分. 小明开业第一天收到了三笔订单: 第一笔:3个A + 7个B + 1个C,共返积分:315 ...

  2. SqlSession对象之ResultSetHandler

    ResultSetHandler是Mybatis中的另一重要接口,它的代码如下所示: public interface ResultSetHandler { <E> List<E&g ...

  3. php魔术方法__tostring的应用

    当echo一个对象的时候,会报错误 Object of class Person could not be converted to string 我们可以通过魔术方法__tostring()  把对 ...

  4. Unix环境高级编程:文件 IO 原子性 与 状态 共享

    参考 UnixUnix环境高级编程 第三章 文件IO 偏移共享 单进程单文件描述符 在只有一个进程时,打开一个文件,对该文件描述符进行写入操作后,后续的写入操作会在原来偏移的基础上进行,这样就可以实现 ...

  5. mysql时间与字符串之间相互转换

    1.时间转字符串 DATE_FORMAT(日期,格式字符串) SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s'); 2.字符串转时间 STR_TO_DATE( ...

  6. javascript: 数组详细操作方法及解析合集(9个改变8个不变12个遍历)

    改变原数组的方法(9个): 1 2 3 4 5 let a = [1,2,3]; ES5: a.pop()/ a.shift()/ a.push()/ a.unshift()/ a.reverse() ...

  7. equals与hashcode区别

    哈希码:   hashCode的作用是用来获取哈希码,也可以称作散列码.实际返回值为一个int型数据.用于确定对象在哈希表中的位置. Object中有hashcode方法,也就意味着所有的类都有has ...

  8. 关于对DI和IOC的概念理解

    在spring框架学习过程中,涉及到两个新名词:DI和IOC.开始总是混淆两者的概念,稀里糊涂,后来上网搜了一下又和同学讨论之后,基本上理解了二者的概念.实际上DI(依赖注入)和IOC(控制反转)就是 ...

  9. Android Studio 关联 JDK Java 源码

    Android Studio 关联 Android 源码比较方便,一般下载后可自动关联,但是 Android Studio 默认使用的 JDK 是内嵌的,是不带源码的.所以在查看 JDK 源码时,看到 ...

  10. 加速JDBC的快捷方法

    JAVA 应用必须通过 JDBC 从数据库中取数,有时候我们会发现,数据库的负担一点也不重而且 SQL 很简单,但取数的速度仍然很慢.仔细测试会发现,性能瓶颈主要在 JDBC 上,比如 MySQL 的 ...