Docker容器镜像与容器
Docker容器镜像与容器
在使用Docker时,我们从一个基础镜像开始。我们启动它,进行更改,这些更改会被保存在层中,形成另一个镜像。
因此,最终我有一个用于PostgreSQL实例的镜像和一个用于Web应用程序的镜像,对其进行的更改会不断持久化。
什么是容器?
来自我关于自动化Docker部署 (已存档)的文章:
Docker镜像与容器
在Dockerland中,有镜像和容器。它们两者有着密切的联系,但又是不同的。对于我来说,理解这个二分法极大地澄清了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
。因此,如果您计划将名为my-application
的图像存储在docker.example.com
的注册表中,您应该对该图像进行标记docker.example.com/my-application
。 - TAG列只是完整标记的[:TAG]部分。这是很不幸的术语。
latest
标记不是神奇的,它只是在未指定标记时的默认标记。- 您可以具有仅可通过它们的IMAGE ID进行识别的未贴标签的图像。这些将获取
什么是容器?
如果用编程的比喻,那么镜像就是一个类,而容器则是该类的一个实例——一个运行时对象。容器是使用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注册表,以便我有一个私人存储我的镜像的地方。还要注意以下几点:
- 像IMAGE ID一样,CONTAINER ID是容器的真正标识符。它具有相同的形式,但标识不同的对象。
docker ps
只输出正在运行的容器。您可以使用docker ps -a
查看所有容器(正在运行或已停止)。- NAMES可以用于通过
--name
标志标识启动的容器。
如何避免镜像和容器的堆积
最初我对Docker的一个恼人的问题是似乎不断堆积的未标记的镜像和已停止的容器。在一些情况下,这种堆积导致我的笔记本电脑硬盘空间满了,减慢了速度,或者停止了我的自动构建流水线。简直是“到处都是容器”!
我们可以通过将docker rmi
与最近的dangling=true
查询结合使用来删除所有未标记的镜像:
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]
删除无用的已停止容器背后的镜像。