docker 镜像操作

目录

获取镜像

运行镜像

列出镜像

虚悬镜像

中间层镜像

以特定格式显示

删除本地镜像


获取镜像

Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会从镜像仓库下载该镜像。

Docker Hub上有大量的高质量的镜像可以用;

从 Docker 镜像仓库获取镜像的命令是 docker pull 。其命令格式为:

docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
  • 地址:地址的格式一般是 [:端口号] 。默认地址是 Docker Hub。
  • 仓库名:仓库名是两段式名称,即 / 。对于 Docker Hub,如果不给出用户名,则默认为 library ,也就是官方镜像。

例如:

[root@docker ~]# docker pull ubuntu:16.04
16.04: Pulling from library/ubuntu
e80174c8b43b: Pull complete
d1072db285cc: Pull complete
858453671e67: Pull complete
3d07b1124f98: Pull complete
Digest: sha256:bb5b48c7750a6a8775c74bcb601f7e5399135d0a06de004d000e05fd25c1a71c
Status: Downloaded newer image for ubuntu:16.04
docker.io/library/ubuntu:16.04

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

运行镜像

以上面的 ubuntu:16.04 为例,启动里面的 bash 并且进行交互式操作的话:

[root@docker ~]# docker run -it --rm ubuntu:16.04 bash
root@3a31439393f0:/# cat /etc/os-release 
NAME="Ubuntu"
VERSION="16.04.6 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.6 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
root@3a31439393f0:/# ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr
root@3a31439393f0:/# exit
exit
[root@docker ~]# 

docker run:运行容器的命令。如果没有此镜像,会先pull再运行

参数说明:

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

进入容器后,可以在 Shell 下操作,执行任何所需的命令。

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

列出镜像

列出已经下载下来的镜像:docker image ls   或   docker images

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

[root@docker ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               5f2bf26e3524        11 days ago         123MB
ubuntu              new-tag             5f2bf26e3524        11 days ago         123MB
hello-world         latest              fce289e99eb9        10 months ago       1.84kB

镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个标签。在上面的例子中, ubuntu:16.04 和 ubuntu:new-tag拥有相同的 ID,因为它们对应的是同一个镜像。

修改标签命令

[root@docker ~]# docker tag IMAGEID(镜像id) REPOSITORY:TAG(仓库:标签)
[root@docker ~]# docker tag 5f2bf26e3524 ubuntu:new-tag

删除标签命令

# docker rmi -f REPOSITORY:TAG(仓库:标签)

查看镜像容器数据卷所占用的空间:

[root@docker ~]# docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              2                   1                   122.6MB             122.6MB (99%)
Containers          1                   0                   0B                  0B
Local Volumes       0                   0                   0B                  0B
Build Cache         0                   0                   0B                  0B
 docker system df -v 命令可以进一步查看空间占用细节,以确定是哪个镜像、容器或本地卷占用过高空间

 扩展

[root@docker ~]# docker image ls ubuntu
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               5f2bf26e3524        11 days ago         123MB
ubuntu              new-tag             5f2bf26e3524        11 days ago         123MB
[root@docker ~]# docker image ls ubuntu:16.04
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              16.04               5f2bf26e3524        11 days ago         123MB

虚悬镜像

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

可以用下面的命令专门显示这类镜像:

[root@docker ~]# docker image ls -f dangling=true
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              00285df0df87        12 days ago         340MB

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

一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除:

[root@docker ~]# docker image prune

该命令所清理的对象如下:

已停止的容器
未被任何容器使用的卷
未被任何容器所关联的网络
所有悬空的镜像

中间层镜像

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

# docker image ls -a

这样会看到很多无标签的镜像,与之前的虚悬镜像不同,这些无标签的镜像很多都是中间层镜像,是其它镜像所依赖的镜像。这些无标签镜像不应该删除,否则会导致上层镜像因为依赖丢失而出错。实际上,这些镜像也没必要删除,相同的层只会存一遍,而这些镜像是别的镜像的依赖,因此并不会因为它们被列出来而多存了一份,无论如何你也会需要它们。只要删除那些依赖它们的镜像后,这些依赖的中间层镜像也会被连带删除。

以特定格式显示

列出 镜像 ID :

[root@docker ~]# docker image ls -q
5f2bf26e3524
5f2bf26e3524
fce289e99eb9

列出 镜像ID、仓库名 和 标签:

[root@docker ~]# docker image ls --format "{{.ID}}: {{.Repository}}  {{.Tag}}"
5f2bf26e3524: ubuntu  16.04
5f2bf26e3524: ubuntu  new-tag
fce289e99eb9: hello-world  latest

以表格等距显示,有标题行,自己定义列:

[root@docker ~]# docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID            REPOSITORY          TAG
5f2bf26e3524        ubuntu              16.04
5f2bf26e3524        ubuntu              new-tag
fce289e99eb9        hello-world         latest

删除本地镜像

docker image rm [选项] <镜像1> [<镜像2> ...]

其中, <镜像> 可以是 镜像短 ID镜像长 ID 镜像名 或者 镜像摘要

删除所有仓库名为 xx 的镜像:

# docker image rm $(docker image ls -q xx)

可以用 docker image ls 命令来配合 docker image rm,实现批量删除

例如:

# 需要停止容器,解除容器对镜像的依赖,才可删除
[root@docker ~]# docker image rm fce289e99eb9
Error response from daemon: conflict: unable to delete fce289e99eb9 (must be forced) - image is being used by stopped container 4e6514cbf838
# 停止所有容器
[root@docker ~]# docker stop $(docker ps -a -q)
4e6514cbf838
# 短ID 来删除镜像;一般取前3个字符以上,只要足够区分于别的镜像就可以了。
[root@docker ~]# docker image rm fce289
Untagged: hello-world:latest
Untagged: hello-world@sha256:c3b4ada4687bbaa170745b3e4dd8ac3f194ca95b2d0518b417fb47e5879d9b5f
Deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e
Deleted: sha256:af0b15c8625bb1938f1d7b17081031f649fd14e6b233688eea3c5483994a66a3

观察上面删除输出信息的话,会发现到删除行为分为两类,一类是 Untagged ,另一类是 Deleted

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

因此当我们使用上面命令删除镜像的时候,实际上是在要求删除某个标签的镜像。所以首先需要做的是将满足我们要求的所有镜像标签都取消,这就是我们看到的 Untagged 的信息。 因为一个镜像可以对应多个标签,因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么 Delete 行为就不会发生。所以并非所有的 docker rmi 都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已。

当该镜像所有的标签都被取消了,该镜像很可能会失去了存在的意义,因此会触发删除行为镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。 镜像的多层结构让镜像复用变动非常容易,因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层。这就是为什么,有时候会奇怪,为什么明明没有别的标签指向这个镜像, 但是它还是存在的原因,也是为什么有时候会发现所删除的层数和自己 docker pull 看到的层数不一样的源。

除了镜像依赖以外,还需要注意的是容器对镜像的依赖。如果有用这个镜像启动的容器存在 (即使容器没有运行),那么同样不可以删除这个镜像。容器是以镜像为基础, 再加一层容器存储层,组成这样的多层存储结构去运行的。因此该镜像如果被这个容器所依赖的,那么删除必然会导致故障。如果这些容器是不需要的,应该先将它们删除,然后再来删除镜像。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值