一. Docker镜像简介
Docker镜像就像停止运行的容器;我们可以将镜像理解为类(Class)。镜像需要从镜像仓库服务中拉取镜像。常见的镜像仓库服务是DockerHub,但是也存在其他镜像仓库服务。拉取操作会将镜像下载到本地 Docker主机。
镜像是多层的:
镜像由多个层组成,每层叠加之后,从外部看来就如一个独立的对象。镜像内部是一个精简的操作系统(OS),同时还包含应用运行所必须的文件和依赖包。因为容器的设计初衷就是快速和小巧,所以镜像通常都比较小。
构建时结构
我们可以停止某个容器的运行,并从中创建新的镜像(会保存当前执行的环境状况)。在该前提下,镜像可以理解为一种构建时(build-time)结构,而容器可以理解为一种运行时(run-time)结构,如图:
二. Docker镜像详解
1. 镜像和容器的关系
我们可以使用docker container run命令从某个镜像启动一个或多个容器。一旦容器从镜像启动后,二者之间就变成了互相依赖的关系,并且在镜像上启动的容器全部停止之前,镜像是无法被删除的。
尝试删除镜像而不停止或销毁使用它的容器,会导致下面的错误。
$ docker image rm
Error response from daemon: conflict: unable to remove repository reference \ "" (must force) - container is using its referenc\ ed image
2. 镜像通常比较小
容器追求快速和小巧,这意味着构建镜像的时候通常需要裁剪掉不必要的部分,保持较小的体积,比如:
- Docker镜像通常不会包含6个不同的Shell让读者选择:通常Docker镜像中只有一个精简的Shell,甚至没有Shell。
- 镜像不包含内核:容器都是共享所在Docker主机的内核(如cgroups和namespaces)。所以容器仅包含必要的操作系统(通常只有操作系统文件和文件系统对象)。
3. 拉取镜像
查看主机镜像列表
Docker主机安装之后,本地并没有镜像。使用以下命令检查Docker主机的本地仓库中是否包含镜像。
% docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
langgenius/dify-web 0.6.11 03ed4f2b51ea 8 weeks ago 229MB
langgenius/dify-api 0.6.11 38532784de04 8 weeks ago 2.55GB
...
通过下面的命令可以将镜像拉取到本地。
$ docker image pull ubuntu:latest
latest: Pulling from library/ubuntu
4. 镜像命名
4.1. 镜像仓库服务
Docker镜像存储在镜像仓库服务(Image Registry)当中。Docker客户端的镜像仓库服务是可配置的,默认使用Docker Hub。
镜像仓库服务包含多个镜像仓库(Image Repository)。同样,一个镜像仓库中可以包含多个镜像。如下图展示了包含3个镜像仓库的镜像仓库服务,其中每个镜像仓库都包含一个或多个镜像。
4.2. 官方和非官方镜像仓库
Docker Hub也分为官方仓库(Official Repository)和非官方仓库(Unofficial Repository)。
官方仓库中的镜像是由Docker公司审查的。这意味着其中的镜像会及时更新,由高质量的代码构成。这些代码是安全的,有完善的文档和最佳实践。
大部分流行的操作系统和应用在Docker Hub的官方仓库中都有其对应镜像。这些镜像很容易找到,基本都在Docker Hub命名空间的顶层。
4.3. 镜像的命名和标签
只需要给出镜像的名字和标签,就能在官方仓库中定位一个镜像(采用“:”分隔)。docker image pull命令的格式如下。
docker image pull <repository>:<tag>
$ docker image pull mongo:3.3.11 //该命令会从官方Mongo库拉取标签为3.3.11的镜像
$ docker image pull redis:latest //该命令会从官方Redis库拉取标签为latest的镜像
$ docker image pull alpine //该命令会从官方Alpine库拉取标签为latest的镜像
$ docker image pull nigelpoulton/tu-demo:v2
//该命令会从以我自己的Docker Hub账号为命名空间的tu-demo库中下载标签为v2的镜像
注意:如果没有指定镜像标签,则Docker会拉取标签为latest的镜像。但
标有latest标签的镜像不保证这是仓库中最新的镜像
!例如,Alpine仓库中最新的镜像通常标签是edge。通常来讲,使用latest标签时需要谨慎!
5. 为镜像打多个标签
一个镜像可以根据用户需要设置多个标签,如下