4.docker镜像及相关命令

目录

[1 查看所有镜像 docker images](#1 查看所有镜像 docker images)

[1.1 基本用法](#1.1 基本用法)

[1.2 docker images -q 只显示所有镜像ID](#1.2 docker images -q 只显示所有镜像ID)

[1.3 docker images -f 筛选条件 -q 只显示符合条件的所有镜像ID](#1.3 docker images -f [筛选条件] -q 只显示符合条件的所有镜像ID)

[1.4 docker images --no-trunc 显示完整的IMAGE ID](#1.4 docker images --no-trunc 显示完整的IMAGE ID)

[1.5 docker images --format 模板 使用模板](#1.5 docker images --format [模板] 使用模板)

[2 从源拉取镜像 docker pull](#2 从源拉取镜像 docker pull)

[3 从源查找镜像 docker search](#3 从源查找镜像 docker search)

[4 移除本地镜像 docker rmi](#4 移除本地镜像 docker rmi)

[4.1 基本使用](#4.1 基本使用)

[4.2 强制删除 -f](#4.2 强制删除 -f)

[5 将镜像保存为tar文件 docker save](#5 将镜像保存为tar文件 docker save)

[6 将docker save生成的tar文件加载为镜像 docker load](#6 将docker save生成的tar文件加载为镜像 docker load)

[7 查看镜像的元数据 docker inspect](#7 查看镜像的元数据 docker inspect)

[8 查询镜像的多架构信息 docker manifest inspect](#8 查询镜像的多架构信息 docker manifest inspect)

[9 查看镜像历史记录(分层) docker history](#9 查看镜像历史记录(分层) docker history)

[10 通过dockerfile构建镜像 docker build](#10 通过dockerfile构建镜像 docker build)

[11 给镜像贴标签 docker tag](#11 给镜像贴标签 docker tag)

[12 删除虚悬镜像 docker image prune](#12 删除虚悬镜像 docker image prune)


docker的镜像体积比较小,我们以mysql为例,在docker中mysql仅有516M。你正常安装一个mysql是要大于516M的

docker镜像可以分为4类

  • Docker Official Image :docker官方镜像。镜像的名称就是软件的名称,比如redis就叫redis
  • Verified Publish :已验证发布者发布的镜像。这种镜像不是docker自己做的,但是也是比较重量级的作者做的,比如阿里,华为这种。镜像的名称是 作者/软件的名称 比如 ubuntu/nginx
  • Sponsored OSS:由docker公司赞助的作者开发的仓库。oss的意思是open source software 镜像的名称是 作者/软件的名称 比如 linuxserver/nginx
  • 无认证仓库,这种仓库实际上就是我们自己写的仓库

可以使用第三方的镜像中心,我们在公司自己开发镜像的时候不会把资源发到官方的镜像中心中,而是会自己整一个。在第三方的镜像中心中镜像的命名一般为 域名(或IP)/上传镜像人的名字/软件的名称

docker镜像有一些松耦合(相互的关联性不强)的只读镜像层组成,Docker Daemon负责堆叠这些镜像层并将它们关联为一个统一的整体。

每个分层都是只读的,对分层的修改都是以新分层的形式出现,并不会破坏原分层内容。每个分层只记录变更内容,有利于节省储存空间。

采用分层可以实现不同镜像间的资源共享。比如redis与mysql可能都有A层。如果pull完redis再pull mysql的时候就不用再下载A层了(pull的时候会显示Already exists)。同时存储也只存储一个A层,这个A层既可以给redis使用也可以给mysql

每个镜像层由 镜像文件系统与镜像json文件 构成。镜像的文件系统(file system简称fs)由多个只读的镜像层组成,每层都完成了特定的功能,根据位置与功能可以分为基础镜像层与扩展镜像层

所有镜像的最下层都由一个基础镜像层,这个基础镜像层的文件系统称为根文件系统rootfs。rootfs是建立在Linux系统的文件引导系统bootfs之上(无论你的宿主机是什么,docker的容器都是linux系统,如果是非linux系统安装docker可以理解为宿主先虚拟出一个linux然后给docker的容器用)

基础镜像层之上的镜像层称为扩展镜像层。在Dockerfile中,每条指令都会生成一个扩展镜像层,所以尽可能在把多个指令合成一个指令来写

容器是 基础镜像层与扩展镜像层 之上可读写的容器层,对文件的任何更改只存在于容器层而不会影响镜像本身。如果你像修改镜像层的东西,那么会首先从镜像层复制一份到容器层,然后改复制后的东西。如果容器层与镜像层存储的内容发生冲突,容器层的内容会覆盖镜像层的内容

很多镜像都是多架构(比如amd,arm)的,以便能在多个架构中运行,比如redis。镜像中的部分层是专门处理架构的,在拉取镜像的时候,架构的信息会自动发送给镜像中心,镜像中心根据不同的架构给你返回不同的镜像,如果没有你正在使用的架构那么就会拉取失败

1 查看所有镜像 docker images

1.1 基本用法

如果没有下载过镜像就是这样的

加载过就像就会把相关的信息显示出来

  • 如果一个镜像没有REPOSITORY与TAG我们称这个镜像为虚悬镜像(Dangling Image)
  • 镜像默认是按照 镜像作者的创建时间(不是你拉取的时间)排序的

可以追加名称筛选出想要的信息,比如我想在只想看mysql相关的信息,那么就写 docker images mysql

docker images可以配合参数,应用场景常为批量处理镜像的时候,比如我现在想删除所有的镜像我可以输入 docker rmi $(docker images -q)

$(docker images -q)作为一个变量,意思是全部镜像的ID

1.2 docker images -q 只显示所有镜像ID

1.3 docker images -f 筛选条件 -q 只显示符合条件的所有镜像ID

比如 docker images -f since=mysql:latest -q 筛选出晚于 mysql:latest的CREATED 的镜像ID

-f可以跟的筛选条件常用的有

  • dangling=true 筛选出所有虚悬镜像
  • since=mysql:latest 筛选出晚于 mysql:latest的CREATED 的镜像。比如镜像A的CREATED的创建时间是1 months ago,镜像B:latest的CREATED的创建时间是2 months ago,镜像C的CREATED的创建时间是3 months ago,如果写 since=B:latest 那么就会只显示A镜像(不会显示B,也不会显示C)
  • before=mysql:latest 筛选出早于 mysql:latest的CREATED 的镜像。比如镜像A的CREATED的创建时间是1 months ago,镜像B:latest的CREATED的创建时间是2 months ago,镜像C的CREATED的创建时间是3 months ago,如果写 before=B:latest 那么就会只显示C镜像(不会显示B,也不会显示A)

reference也是-f的筛选条件这个参数只会查官方的镜像,所以这个命令应用不多

  • reference=*:latest 可以查到所有tag为latest的镜像
  • reference=*llo* 可以查看 RESPOSITORY或TAG中含有llo的镜像

1.4 docker images --no-trunc 显示完整的IMAGE ID

IMAGE ID实际上就是digest

1.5 docker images --format 模板 使用模板

比如 docker images --format {{.Repository}} 就是只显示Repository这一列

我们再做个例子 docker images --format {{.Repository}}:{{.Tag}}:{{.Size}}

2 从源拉取镜像 docker pull

比如我想从源拉一个最新的mysql,那你就输入docker pull mysql 拉取的过程是这样的

  • 默认拉取latest版本
  • 如果你要拉取指定的版本,那你就写 docker pull mysql:指定的版本
  • 对于非官方镜像也可以带用户名比如 docker pull suyu/mysql:指定的版本
  • 也可以使用digest值 比如 docker pull openanolis/mysql@sha256:78b2c0e8da2a374094d20aa521ca483c5b7c41de4b6f62fecf67f7582e9aa7d7 用digest值下载之后的镜像默认情况下没有tag
  • 如果要拉取的镜像在源上没有会响应not found

拉下来之后是这样的

  • Digest表示的是镜像的摘要,在下载之前会将要下载的内容与之前下载的内容进行比对(如果之前下载过)。如果比对结果相同就不进行下载,如果比对结果不同再进行下载。digest实际上就是IMAGE ID。每一个镜像都有一个长度为64位的16进制字符串摘要。本质上摘要是一个哈希值,具体来说是Content Hash(内容散列)。只要镜像内容发生了变更,digest也会发生改变。Docker默认采用的Hash算法是SHA256,SHA的意思是 Secure Hash Algorihm 安全哈希算法。SHA256本身是一个256位的二进制值,在Docker中改为了16进制表示,就变成了长度为64位的字符串
  • Digeset可以让客户端与镜像中心传递镜像的时候可以放置信息丢失。比如A的镜像digist是123,那么客户端会先把123发给镜像中心,之后再把镜像传给镜像中心,之后镜像中心会校验一遍传过来的镜像,如果校验结果是123证明镜像没有信息丢失,如果不是123,那么会自动重新传输
  • 为了节省带宽,pull或push的时候镜像会被压缩,之后传输。压缩后的镜像与压缩前的镜像digist是不同的。为了解决这个问题Docker采用了分发散列值(Distribution Hash),分发散列值在镜像压缩后立即计算。客户端与镜像中心使用分发散列值校验镜像

每一个pull complete代表这个镜像的每一个层,每一次下载的时候层都是有顺序的,第一层是72a6,第二层是9361。它是一层一层压上去,层太多了我就不每个都画上了,我们可以大概像下面图一样理解,一层一层往上盖,e043是最后一层

查看镜像列表可以发现mysql

可以追加一些参数,比如

  • docker pull -a zookeeper 这个就是把zookeeper镜像的所有版本都拉到你本地
  • docker pull -q zookeeper 这个是静默模式,静默模式就是在终端上不打印任何的东西

比如说我想找 redis 这个镜像,排序是根据综合得分排序的

  • NAME 镜像名称
  • DESCRIPTION 镜像描述
  • STARS 收藏数
  • OFFICIAL 写了OK的是官方的镜像
  • AUTOMATED 写了OK的是通过dockerfile自动构建的镜像。如果dockerfile有变动AUTOMATED为OK的镜像也会变动。AUTOMATED写了OK的可以理解为也是可以被信任的镜像,但不是官方自己做的

docker search可以配合参数比如-f是筛选

  • docker search -f is-official=true redis 这个可以筛选出redis的官方镜像
  • docker search -f is-automated=true redis 这个可以筛选出redis通过dockfile自动化构建的镜像
  • docker search -f stars=100 redis 这个可以筛选出redis的stars值大于100的镜像

--limit 是显示多少条数据,默认为25

  • docker search --limit=5 redis 只显示redis的前5条数据

--no-trunc 是不删减显示的信息,基本上只有描述比较长,会被删减一点

  • docker search --no-trunc redis 显示每一个redis的完整信息

--format 是按照模板显示

  • docker search --format {{.Name}} 只显示redis这一列

4 移除本地镜像 docker rmi

4.1 基本使用

比如我想删除mysql:latest这个镜像,那么就输入 docker rmi mysql:latest

  • 如果不写tag默认是latest,删除的时候建议写全了
  • 也可以写IMAGE ID,比如 docker rmi 3218b38490ce

4.2 强制删除 -f

如果你有容器正在使用镜像,你只写rmi是删除不了的

加上 -f 就能删了

镜像没有了,但是容器还有

5 将镜像保存为tar文件 docker save

保存可以保存一个或者多个,我们目前有两个镜像

我们可以将这两个镜像保存为一个tar文件,输入 docker save -o /home/suyu/my.tar mysql:latest hello-world:latest

  • 也可以分开保存

也可以这样写,效果与上面的命令相同

tar文件大小与所保存的镜像大小之和基本一致

6 将docker save生成的tar文件加载为镜像 docker load

我首先把这两个镜像存为了tar文件

然后我删掉这两个镜像

之后我进行加载,输入 docker load -i my.tar

加载完成后是这样的

我们查询所有镜像,发现与保存前一致(包括镜像ID)

也可以这样加载 docker load < my.tar 效果一样

7 查看镜像的元数据 docker inspect

比如docker inspect mysql

8 查询镜像的多架构信息 docker manifest inspect

比如 docker manifest inspect redis

  • 这个是从源查询的,所以查的时候会慢一些
  • manifest本身一个文件,如果这个镜像不支持多架构就没有这个文件,没有这个文件执行 docker manifest inspect 就查不了。有的镜像支持多架构,但也没有manifest这个文件,那也查不了。

9 查看镜像历史记录(分层) docker history

比如我现在要查看 a7c6 这个镜像的历史记录

10 通过dockerfile构建镜像 docker build

我在/home/suyu下有Dockerfile这个文件,还有一个可执行文件hello,可执行文件在终端执行后会打印hello world

  • 可执行文件是通过gcc的静态编译编译出来的

内容如下

之后进入Dockerfile所在的目录,执行 docker build -t 镜像名 .

  • 注意最后有个点儿,这个点儿代表的就是Dockerfile
  • 如果不写tag默认为latest

之后执行docker images就可以看到构建的镜像了

运行这个镜像可以成功执行hello

如果镜像名:tag与之前的内容重复,且内容不一致。新的build的镜像会为你定义的名字,build前的同名镜像会变为虚悬镜像

如果你想指定其他的Dockerfile。比如路径下的Dockerfile2

那么就可以像下面这样写

  • 注意最后的 点 还是要写

11 给镜像贴标签 docker tag

比如我现在想把 suyu_hello_world:latest 改为 111:222

那么我可以执行 docker tag suyu_hello_world:latest 111:222

添加完 111:222 之后发现之前的 suyu_hello_world:latest 还在,这个时候我们删掉它就可以了

  • 注意不要用ID删除

12 删除虚悬镜像 docker image prune

我们现在有一个虚悬镜像

我可以通过docker image prune删掉所有的虚悬镜像

  • 如果该虚悬镜像生成了容器,即使容器为退出状态也删不掉该虚悬镜像
相关推荐
Wang's Blog24 分钟前
Java 项目部署之 Docker工具快速入门: Docker 是什么以及它如何解决部署环境问题
java·开发语言·docker
ajassi200037 分钟前
AI语音智能体开发日记(十八)智能体服务器xiaozhi-esp32-server源码部署指南
运维·服务器·人工智能·ai·ai编程
‎ദ്ദിᵔ.˛.ᵔ₎41 分钟前
linux 进程信号(下)
linux·运维·服务器
Mikko71 小时前
Linux 磁盘满了但 du 找不到?LVM 扩容 df 不变?fstab 写错开不了机?三台真机实测磁盘排查
linux·运维·centos
蓝胖的四次元口袋1 小时前
Jenkins知识梳理(2)
运维·jenkins
yumgpkpm1 小时前
Acceldata ODP 3.3.6.4 vs CDP Private Cloud Base 7.3.2 对比
大数据·运维·服务器·hadoop·华为·zookeeper·hbase
AIGC大时代1 小时前
LLM Agent 执行沙箱闸门:失败含义与当天最小实验
docker·沙箱·闸门·bubblewrap·llm agent
Liuqy-051 小时前
特殊进程——孤儿、僵尸、守护进程
linux·运维·服务器
考研保研资料分享2 小时前
自动化控制保研经验合辑:上交夏令营、北工大预推免与跨专业面试复盘(2025)
运维·面试·自动化
灯澜忆梦2 小时前
【docker】#2 | 基础命令
docker·容器·eureka