我是Docker的新手,正在尝试准确理解Docker映像是什么。Docker映像的每个定义都使用术语“层”,但似乎没有定义层的含义。
从Docker官方文件:
我们已经看到Docker图像是只读模板,从中启动Docker容器。每个图像由一系列层组成。Docker利用union文件系统将这些层合并到单个图像中。Union文件系统允许透明地覆盖单独文件系统(称为分支)的文件和目录,形成单个连贯的文件系统。
所以我问,什么是层(确切地说);有人能举几个具体的例子吗?这些层是如何“咬合在一起”形成图像的?
他们用一个例子对我来说最有意义...
让我们以Dockerfile为例:
FROM busybox
RUN mkdir /data
# imagine this is downloading source code
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/one
RUN chmod -R 0777 /data
# imagine this is compiling the app
RUN dd if=/dev/zero bs=1024 count=1024 of=/data/two
RUN chmod -R 0777 /data
# and now this cleans up that downloaded source code
RUN rm /data/one
CMD ls -alh /data
每个dd命令都会将一个1M文件输出到磁盘。让我们用一个额外的标志来构建图像,以保存临时容器:
docker image build --rm=false .
在输出中,您将看到每个正在运行的命令都发生在我们现在保留的临时容器中,而不是自动删除:
...
Step 2/7 : RUN mkdir /data
---> Running in 04c5fa1360b0
---> 9b4368667b8c
Step 3/7 : RUN dd if=/dev/zero bs=1024 count=1024 of=/data/one
---> Running in f1b72db3bfaa
1024+0 records in
1024+0 records out
1048576 bytes (1.0MB) copied, 0.006002 seconds, 166.6MB/s
---> ea2506fc6e11
如果在每个容器id上运行docker diff,您将看到在这些容器中创建了哪些文件:
$ docker diff 04c5fa1360b0 # mkdir /data
A /data
$ docker diff f1b72db3bfaa # dd if=/dev/zero bs=1024 count=1024 of=/data/one
C /data
A /data/one
$ docker diff 81c607555a7d # chmod -R 0777 /data
C /data
C /data/one
$ docker diff 1bd249e1a47b # dd if=/dev/zero bs=1024 count=1024 of=/data/two
C /data
A /data/two
$ docker diff 038bd2bc5aea # chmod -R 0777 /data
C /data/one
C /data/two
$ docker diff 504c6e9b6637 # rm /data/one
C /data
D /data/one
以A
为前缀的每一行都在添加文件,C
表示对现有文件的更改,D
表示删除。
上述每个容器文件系统差异都进入一个“层”,当您将映像作为容器运行时,该层将被组装。当有添加或更改时,整个文件都在每一层中,因此这些chmod命令中的每一个都会导致整个文件被复制到下一层,尽管只是更改了一个权限位。删除的/数据/一个文件仍在前几层中,事实上有3次,当你拉取图像时,它将通过网络复制并存储在磁盘上。
您可以使用docker历史记录
命令查看创建现有映像图层的命令。您还可以在图像上运行docker镜像检查
并查看RootFS部分下的图层列表。
以下是上图的历史记录:
IMAGE CREATED CREATED BY SIZE COMMENT
a81cfb93008c 4 seconds ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "ls -… 0B
f36265598aef 5 seconds ago /bin/sh -c rm /data/one 0B
c79aff033b1c 7 seconds ago /bin/sh -c chmod -R 0777 /data 2.1MB
b821dfe9ea38 10 seconds ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
a5602b8e8c69 13 seconds ago /bin/sh -c chmod -R 0777 /data 1.05MB
08ec3c707b11 15 seconds ago /bin/sh -c dd if=/dev/zero bs=1024 count=102… 1.05MB
ed27832cb6c7 18 seconds ago /bin/sh -c mkdir /data 0B
22c2dd5ee85d 2 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:2a4c44bdcb743a52f… 1.16MB
最新的图层列在顶部。值得注意的是,底部有两层相当古老。它们来自busybox图像本身。当您构建一个图像时,您将继承您在“来自”行中指定的图像的所有层。还添加了一些层来更改图像元数据,如CMD行。它们几乎不占用任何空间,更多的是用于记录应用于正在运行的图像的设置。
这些层有几个优点。首先,它们是不变的。一旦创建,由sha256哈希标识的层将永远不会更改。这种不变性使图像能够安全地构建并相互分叉。如果两个DockerFile具有相同的初始行集,并且构建在同一台服务器上,那么它们将共享相同的初始层集,从而节省磁盘空间。这也意味着,如果重建图像,Dockerfile的最后几行发生更改,则只需要重建这些层,其余层可以从层缓存中重用。这可以快速重建docker图像。
在容器中,您可以看到映像文件系统,但该文件系统没有被复制。在这些映像层的顶部,容器挂载它自己的读写文件系统层。文件的每一次读取都经过这些层,直到它到达一个已将文件标记为删除的层,该层中有一个文件副本,或者读取用完了要搜索的层。每次写入都会在容器特定的读写层中进行修改。
这些层的一个缺点是生成复制文件的图像,或者发送在以后的层中删除的文件。解决方案通常是将多个命令合并为单个运行命令。尤其是在修改现有文件或删除文件时,您希望这些步骤在最初创建它们的同一命令中运行。上述Dockerfile的重写如下所示:
FROM busybox
RUN mkdir /data \
&& dd if=/dev/zero bs=1024 count=1024 of=/data/one \
&& chmod -R 0777 /data \
&& dd if=/dev/zero bs=1024 count=1024 of=/data/two \
&& chmod -R 0777 /data \
&& rm /data/one
CMD ls -alh /data
如果比较结果图像:
只需将人为示例中的一些行合并在一起,我们就可以在图像中获得相同的结果内容,并将图像从5MB压缩到您在最终图像中看到的1MB文件。
docker容器映像是使用dockerfile创建的。dockerfile中的每一行都将创建一个层。考虑以下虚拟示例:
FROM ubuntu #This has its own number of layers say "X"
MAINTAINER FOO #This is one layer
RUN mkdir /tmp/foo #This is one layer
RUN apt-get install vim #This is one layer
这将创建一个最终的图像,其中总层数为X 3
我可能会迟到,但这是我的10美分(补充ashishjain的回答):
基本上,层或图像层是对图像或中间图像的更改。您在Dockerfile中指定的每个命令(来自
、运行
、复制
等)都会导致上一个图像发生更改,从而创建一个新层。当你使用git的时候,你可以把它看作是一个暂存更改:你添加一个文件的更改,然后再添加一个,然后再添加一个。。。
考虑以下Dockerfile:
FROM rails:onbuild
ENV RAILS_ENV production
ENTRYPOINT ["bundle", "exec", "puma"]
首先,我们选择一个起始图像:rails:onbuild,它又有许多层。我们在开始图像的顶部添加了另一层,使用命令设置环境变量RAILS\u ENV。然后,我们告诉docker运行bundle exec puma(启动rails服务器)。这是另一层。
在构建图像时,层的概念非常有用。由于层是中间图像,如果您对Dockerfile进行更改,docker将仅重建更改后的层和更改后的层。这称为层缓存。
你可以在这里读到更多。
我对Docker是全新的,我正在努力理解Docker形象到底是什么。Docker图像的每个定义都使用术语“层”,但似乎没有定义层的含义。
我需要了解docker图像注册表的脱机使用情况 当docker图像从microsoft官方网站中提取、调整,然后推送到注册表时,它是完整的图像还是缺少图层 当其他主机从注册表中提取图像(可能脱机使用)时,客户端主机是否仍需要internet连接才能从microsoft服务器中提取缺失/机密层?(或者是从microsoft提取的完整图像,然后推送到注册表?) 签名呢?当图像被调整、存储在其中的应用程
我正在尝试编写一个程序,以确保容器的父(或祖父母或曾祖父母等)是已批准的容器列表中的容器。(以确保我的公司仅使用经批准的容器。) 当我在我的图像上运行命令时,我得到一些json响应。json的一部分如下所示: 我以为这些就是我容器图像的层次。但该列表不包含容器映像的父级。所谓父级,我指的是在子句中用于创建我检查过的图像的容器图像。)(我使用命令进行了检查。) 这些价值观是什么? 更重要的是,有没有
在这种情况下,这些rest层ID是否与其他一些图像相对应呢?如果是真的,我可以视图层为图像吗?
让我们以whalesay图片为例<代码>docker history显示以下内容: 我想提取显示为的层。有这样做的工具/方法吗?
这个问题的根源是从docker私有注册表中提取的速度非常慢。 然后我发现通过注册表远程API的速度是可以的。 现在我得到一个图像的层。如何将其作为映像加载到docker守护程序? ps: 我试着加载docker 结果如下。 FATA[0015]错误:打开 /home/docker/data/docker/tmp/docker-import-087506163/repo/etc/json:没有这样的