Docker教程:Docker镜像


Docker中的镜像是其重要组成部分,下面就来说说Docker镜像的工作原理。

Docker镜像的分层结构

每当使用docker pull的时候,我们都会看到docker会依次下载不同的层(layer),比如:

bash
xxxxxxxxxx: Pulling fs layer

UnionFS联合文件系统

UnionFS是Docker镜像的基础,它是一种轻量级的分层文件系统。通过UnionFS,可以将对文件系统的修改作为一次提交(Commit)来一层层的叠加。UnionFS会将不同目录挂载到同一个虚拟文件系统中。

分层的镜像系统就有点像OO中的继承,比如在Java中,所有类的父类是Objcet,其余类都是在其基础上不断继承得到的。

之所以叫做分层文件系统,是因为Docker会同时加载多个文件系统。但从外部看来,只能看到一个多层文件叠加之后的结果,也就是同一个文件系统。

这个分层文件系统包括:

  • bootfs:这是Linux系统的起点,通过这个bootfs,可以加载Linux内核,不同Linux发行版本可以共用bootfs
  • rootfs:它包含了Linux中最基本的目录和文件,比如:/dev, /bin, /etc等

在使用某个具体镜像时,可以根据需要选择不同的镜像进行组合,达到最大程度的重用。

如果多个镜像都需要使用一个基本镜像,Docker只需要存储一份就可以了,这样能够最大程度的节省磁盘空间。

Docker中的镜像都是只读的,只有容器才是可写的。

可以使用以下命令查看docker镜像的不同层:

bash
docker history redis

使用docker commit增强容器功能并生成新的镜像

在默认的Redis镜像中是不包含curl命令的,下面演示如何创建一个新的docker镜像:

首先启动一个redis容器:

bash
docker run redis

以交互模式进入容器:

bash
docker exec -it CONTAINER_ID /bin/bash

安装curl:

bash
apt-get update
apt-get -y install curl

在host上运行如下命令提交容器副本以生成新镜像:

bash
docker commit -m "add curl" -a=lcoding cbca7ef86c63 lcoding/redis:7.0.4

再查看docker镜像,就能看到新创建的镜像了:

bash
docker images

其运行结果:

bash
REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
lcoding/redis   7.0.4     0c6b694c84ec   3 seconds ago   141MB
redis           latest    dc7b40a0b05d   2 weeks ago     117MB
hello-world     latest    feb5d9fea6a5   11 months ago   13.3kB

这个时候如果使用新创建的镜像启动容器就能看到curl已经能够直接使用了:

bash
docker run -it lcoding/redis:7.0.4 bash

生成自己Docker镜像的两种方式

  • 通过前面提到的docker commit在现有docker镜像的基础上创建新镜像
  • 通过Dockerfile创建新镜像

搭建自己的私有Docker镜像仓库

拉取并启动registry容器:

bash
docker pull registry
docker run -d -p 5000:5000 -v /home/lcoding/myregistry:/tmp/registry --privileged=true registry

回到host进行测试:

bash
curl -XGET http://127.0.0.1:5000/v2/_catalog

添加新tag:

bash
docker tag lcoding/redis:7.0.4 127.0.0.1:5000/lcoding/redis:7.0.4

由于在默认方式下,docker不支持http方式推送到仓库,因此需要添加/更新文件:/etc/docker/daemon.json:

json
{
  "insecure-registries": ["127.0.0.1:5000"]
}

将自己的镜像推送到私有镜像仓库:

bash
docker push 127.0.0.1:5000/lcoding/redis:7.0.4

再次查看私有镜像仓库:

bash
curl -XGET http://127.0.0.1:5000/v2/_catalog

其运行结果为:

bash
{"repositories":["lcoding/redis"]}

删除本地的镜像后,重新从私有镜像服务器拉取:

bash
docker pull 127.0.0.1:5000/lcoding/redis:7.0.4

文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !