Docker镜像和容器之间有什么区别?
Docker镜像和容器之间有什么区别?
Docker使用基础镜像启动,创建更改并将这些更改保存在层中,形成另一个镜像。
最终,我拥有了一个用于PostgreSQL实例的镜像和一个用于Web应用程序的镜像,对它们的更改不断被保留。
什么是容器?
来自我关于自动化Docker部署(存档)的文章:
Docker镜像与容器
在Docker领域,有镜像和容器。两者密切相关,但却有所不同。对我来说,理解这个对立很好理解Docker。
什么是镜像?
镜像是一个不活动的、不可变的文件,基本上是容器的快照。镜像是使用build命令创建的,在使用run启动时会生成一个容器。镜像存储在Docker注册表中,如registry.hub.docker.com。由于镜像可能很大,因此设计为由其他镜像的层组成,当通过网络传输镜像时,允许发送最少量的数据。
可以通过运行docker images
来列出本地镜像:
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 13.10 5e019ab7bf6d 2 months ago 180 MB ubuntu 14.04 99ec81b80c55 2 months ago 266 MB ubuntu latest 99ec81b80c55 2 months ago 266 MB ubuntu trusty 99ec81b80c55 2 months ago 266 MB4ab0d9120985 3 months ago 486.5 MB
需要注意的一些事情:
- IMAGE ID是图像的真实标识符的前12个字符。您可以创建给定图像的许多标签,但它们的ID将相同 (如上所示)。
- VIRTUAL SIZE是虚拟的,因为它是将所有不同的底层层的大小相加。这意味着该列中所有值的总和可能比所有这些镜像使用的磁盘空间大得多。
- REPOSITORY列中的值来自
docker build
命令的-t
标志,或者来自对现有图像进行docker tag
标记。您可以使用适合自己的命名法对图像进行标记,但是请注意,Docker将使用标记作为docker push
或docker pull
中的注册表位置。 - 标记的完整形式是
[REGISTRYHOST/][USERNAME/]NAME[:TAG]
。对于上面的ubuntu
,REGISTRYHOST被推断为registry.hub.docker.com
。因此,如果您计划在docker.example.com
的注册表中存储名为my-application
的图像,则应将该图像标记为docker.example.com/my-application
。 - TAG列只是完整标记的[:TAG]部分。这是不幸的术语。
latest
标签并不神奇,它只是在您没有指定标签时的默认标签。- 您可以有未标记的图像,只能通过它们的图像ID进行识别。它们会得到
的TAG和REPOSITORY。很容易忘记它们。
什么是容器?
用编程的隐喻来说,如果一个镜像是一个类,那么一个容器就是一个类的实例 - 运行时对象。容器是您使用Docker的重点原因; 它们是轻量级和可移动的环境封装,其中运行应用程序。
使用docker ps
查看正在运行的本地容器:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f2ff1af05450 samalba/docker-registry:latest /bin/sh -c 'exec doc 4 months ago Up 12 weeks 0.0.0.0:5000->5000/tcp docker-registry
在这里,我正在运行docker注册表的docker化版本,因此我有一个私人存储图像的位置。 再次注意一些事项:
- 像镜像ID一样,容器ID是容器的真正标识符。 它具有相同的形式,但标识不同类型的对象。
docker ps
仅输出正在运行的容器。 您可以使用docker ps -a
查看所有容器(运行或停止)。- NAMES可以通过
--name
标志用于识别启动的容器。
如何避免镜像和容器的累积
我早期对Docker的不满之一是似乎不断积攒的未标记的镜像和已停止的容器。 在少数几次情况下,这种累积导致硬盘满载,减慢了我的笔记本电脑的速度,或停止了我的自动化构建流程。 谈论“无处不在的容器”!
我们可以通过将dangling=true
查询与docker rmi
结合使用来删除所有未标记的镜像:
docker images -q --filter "dangling=true" | xargs docker rmi
Docker无法删除在现有容器后面的镜像,因此您可能需要首先使用docker rm
删除已停止的容器:
docker rm `docker ps --no-trunc -aq`
这些是关于 Docker 的已知问题,可能会在未来的版本中得到解决。 但是,如果能清楚地理解镜像和容器的概念,那么可以通过以下几项实践来避免这些情况:
- 始终使用
docker rm [CONTAINER_ID]
来删除无用的停止容器。 - 始终使用
docker rmi [IMAGE_ID]
来删除处于无用的停止容器后面的镜像。