我是Docker的新手,我试图准确理解Docker 图像是什么.Docker镜像的每个定义都使用术语"图层",但似乎并未定义图层的含义.
从官方Docker文档:
我们已经看到Docker镜像是从中启动Docker容器的只读模板.每个图像由一系列图层组成.Docker利用联合文件系统将这些层组合成一个图像.联合文件系统允许透明地覆盖单独文件系统的文件和目录(称为分支),形成单个连贯的文件系统.
所以我问,什么是一层(确切地说); 有人能给出一些具体的例子吗?这些图层如何"拼合"形成图像?
Dav*_*llo 109
我可能会迟到,但这是我的10美分(补充ashishjain的答案):
基本上,图层或图像层是图像或中间图像的变化.每一个命令指定(FROM,RUN,COPY等),在您的Dockerfile导致前面的图像发生变化,从而创建一个新层.当您使用git时,您可以将其视为暂存更改:添加文件的更改,然后添加另一个,然后添加另一个...
考虑以下Dockerfile:
FROM rails:onbuild
ENV RAILS_ENV production
ENTRYPOINT ["bundle", "exec", "puma"]
Run Code Online (Sandbox Code Playgroud)
首先,我们选择一个起始图像:rails:onbuild反过来又有很多层.我们在起始图像的顶部添加另一个图层,RAILS_ENV使用该ENV命令设置环境变量.然后,我们告诉docker运行bundle exec puma(启动rails服务器).那是另一层.
层的概念在构建图像时派上用场.因为图层是中间图像,所以如果对Dockerfile进行更改,则docker将仅构建已更改的图层以及之后的图层.这称为层缓存.
你可以在这里阅读更多相关信息.
ash*_*ain 67
使用dockerfile创建docker容器映像.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
Run Code Online (Sandbox Code Playgroud)
这将创建一个最终图像,其中总层数将为X + 3
BMi*_*tch 23
他们用一个例子对我最有意义......
让我们来看一个人为的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
Run Code Online (Sandbox Code Playgroud)
每个dd命令都会向磁盘输出1M文件.让我们使用额外的标志来构建图像以保存临时容器:
docker image build --rm=false .
Run Code Online (Sandbox Code Playgroud)
在输出中,您将看到每个正在运行的命令都发生在我们现在保留的临时容器中,而不是自动删除:
...
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
Run Code Online (Sandbox Code Playgroud)
如果您docker diff在每个容器ID上运行一个,您将看到在这些容器中创建了哪些文件:
$ 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
Run Code Online (Sandbox Code Playgroud)
每个前缀为a的行A都是添加文件,C表示对现有文件的更改,并D表示删除.
上面的每个容器文件系统差异进入一个"层",当您将图像作为容器运行时,它将被组合.当存在添加或更改时,整个文件位于每个层中,因此chmod尽管只更改了权限位,但每个命令都会导致整个文件被复制到下一层.删除的/ data/one文件仍然在前面的图层中,实际上是3次,并且当您拉动图像时,它将通过网络复制并存储在磁盘上.
您可以使用该命令查看创建现有图像图层的docker history命令.您还可以docker image inspect在图像上运行a 并查看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
Run Code Online (Sandbox Code Playgroud)
最新的图层列在顶部.值得注意的是,底部有两层相当陈旧.它们来自busybox图像本身.构建一个图像时,将继承FROM在行中指定的图像的所有图层.还有一些图层被添加用于图像元数据的更改,如CMD线.它们几乎不占用任何空间,更多用于记录适用于您正在运行的图像的设置.
这些层有几个优点.首先,它们是不可改变的.一旦创建,由sha256哈希标识的那个层将永远不会改变.这种不变性允许图像安全地构建并彼此分离.如果两个dockerfiles具有相同的初始行集,并且构建在同一服务器上,则它们将共享同一组初始层,从而节省磁盘空间.这也意味着如果重建一个图像,只有Dockerfile的最后几行经历更改,只需要重建那些图层,其余图层可以从图层缓存中重复使用.这可以非常快速地重建docker图像.
在容器内部,您可以看到图像文件系统,但不会复制该文件系统.在这些图像层之上,容器安装了它自己的读写文件系统层.文件的每次读取都会在图层中向下,直到它到达已标记要删除的文件的图层,该图层中包含该文件的副本,或者读取的图层用于搜索.每次写入都会在容器特定的读写层中进行修改.
这些图层的一个缺点是构建复制文件的图像或发送在后续图层中删除的文件.解决方案通常是将多个命令合并为一个RUN命令.特别是在修改现有文件或删除文件时,您希望这些步骤在首次创建它们的同一命令中运行.重写上面的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
Run Code Online (Sandbox Code Playgroud)
如果您比较结果图像:
仅仅通过合并设计示例中的一些行,我们在图像中得到了相同的结果内容,并将我们的图像从5MB缩小到您在最终图像中看到的1MB文件.
Rui*_* Ma 17
自Docker v1.10以来,随着内容可寻址存储的引入,'layer'的概念变得非常不同.图层没有图像概念或属于图像,它们只是文件和目录的集合,可以跨图像共享.图层和图像分离.
例如,在基本图像的本地构建图像上,假设ubuntu:14.04该docker history命令产生图像链,但是某些图像ID将显示为"缺失",因为不再加载构建历史记录.组成这些图像的图层可以通过以下方式找到
docker inspect <image_id> | jq -r '.[].RootFS'
Run Code Online (Sandbox Code Playgroud)
/var/lib/docker/aufs/diff如果存储驱动程序选择是,则存储图层内容aufs.但这些图层是使用随机生成的缓存ID命名的,出于安全原因,图层与其缓存ID之间的链接似乎只为Docker Engine所知.我仍在寻找一种方法来找出答案
这篇博客提供了很多见解.
我认为官方文档给出了非常详细的解释:https: //docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/.

图像由通常从Dockerfile生成的许多层组成,Dockerfile中的每一行都将创建一个新图层,结果是一个图像,由表单表示repo:tag,如ubuntu:15.04.
有关更多信息,请考虑阅读上面的官方文档.
我曾经认为它们就像之前层的差异。读完这里的一些答案后,我不太确定;它们被描述为文件系统的一组更改。我编写了一些 Dockerfile 来表明它们更像是差异,即它们确实依赖于先前的层。
\n\n给定这两个 Dockerfile
\n\nFROM bash\nRUN mkdir /data\nRUN dd if=/dev/zero bs=1024 count=1024 of=/data/one\nRUN dd if=/dev/zero bs=1024 count=1024 of=/data/two\nRUN dd if=/dev/zero bs=1024 count=1024 of=/data/three\nRun Code Online (Sandbox Code Playgroud)\n\n和
\n\nFROM bash\nRUN mkdir /data\nRUN dd if=/dev/zero bs=1024 count=1024 of=/data/three\nRUN dd if=/dev/zero bs=1024 count=1024 of=/data/two\nRUN dd if=/dev/zero bs=1024 count=1024 of=/data/one\nRun Code Online (Sandbox Code Playgroud)\n\n如果它们只是关于文件系统的更改,人们会期望相同的层集,但事实并非如此:
\n\n$ docker history img_1\nIMAGE CREATED CREATED BY SIZE\n30daa166a9c5 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102\xe2\x80\xa6 1.05MB\n4467d16e79f5 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102\xe2\x80\xa6 1.05MB\nc299561fd031 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102\xe2\x80\xa6 1.05MB\n646feb178431 6 minutes ago /bin/sh -c mkdir /data 0B\n78664daf24f4 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B\n<missing> 2 weeks ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry\xe2\x80\xa6 0B\n<more missing...>\nRun Code Online (Sandbox Code Playgroud)\n\n和
\n\n$ docker history img_2\nIMAGE CREATED CREATED BY SIZE\nf55c91305f8c 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102\xe2\x80\xa6 1.05MB\n29b3b627c76f 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102\xe2\x80\xa6 1.05MB\n18360be603aa 6 minutes ago /bin/sh -c dd if=/dev/zero bs=1024 count=102\xe2\x80\xa6 1.05MB\n646feb178431 6 minutes ago /bin/sh -c mkdir /data 0B\n78664daf24f4 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B\n<missing> 2 weeks ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry\xe2\x80\xa6 0B\n<more missing...>\nRun Code Online (Sandbox Code Playgroud)\n\n您可以看到,即使在两种情况下对文件系统的更改相同,顺序也很重要。
\n| 归档时间: |
|
| 查看次数: |
46317 次 |
| 最近记录: |