新的Docker如何运作

For*_*ore 48 squash docker dockerfile

Docker 1.13中添加了新的--squash参数.

我现在希望减小图像的大小,以及能够"隐藏"我的图层中的秘密文件.

现在,您可以看到使用和不使用--squash参数进行构建的区别.

没有壁球

在此输入图像描述

用壁球

在此输入图像描述

现在问我的问题.

如果我在第一层中添加一个秘密文件,那么在我的第二层中使用秘密文件,最后在第三层中删除我的秘密文件,然后使用--squash标志进行构建.

现在有办法得到秘密文件吗?

Far*_*ahi 64

如果我在第一层中添加一个秘密文件,那么在我的第二层中使用秘密文件,最后在第三层中删除我的秘密文件,然后使用--squash标志进行构建.

现在有办法得到秘密文件吗?

答:您的图片没有秘密文件.

如何--squash工作:

构建完成后,Docker会创建一个新图像,将每个图层的差异加载到一个新图层中,并引用所有父图层.

换句话说:当压缩时,Docker将获取构建生成的所有文件系统层,并将它们折叠为单个新层.

这可以简化创建最小容器图像的过程,但是当移动图像时可能导致稍高的开销(因为压缩的图层不能再在图像之间共享).Docker仍然缓存单个层以快速进行后续构建.

请注意,此功能会将所有新构建的图层压缩成单个图层,而不会挤压到划痕.

附注:

Docker 1.13还支持使用该--compress标志压缩从CLI发送到守护程序的构建上下文.这将通过减少发送的数据量来加速在远程守护程序上完成的构建.

请注意,从Docker 1.13开始,此功能是实验性的.

  • 对于登陆这里并想知道为什么他们在“docker build --help”显示的选项中看不到“--squash”的人,您需要打开守护进程的实验性功能。在典型的 Linux 安装中,编辑 `/etc/docker/daemon.json` 并在块末尾添加 `"experimental": true`。重启docker守护进程使其生效。如何执行此操作取决于 Linux 发行版,Ubuntu/debian 的“sudo systemctl restart docker”。对于 Mac OS X,要编辑的 JSON 可以在首选项控制面板的 Docker Engine 部分中找到,单击桌面应用程序右上角的齿轮图标。 (5认同)
  • 如果您要在没有“--squash”的情况下执行此操作,是否可以通过读取文件系统上的层来以某种方式访问​​该文件?通过测试,我发现包含秘密文件的层“丢失”,我认为这意味着无法通过挖掘层来以某种方式访问​​秘密文件? (4认同)
  • 如果您发布或分发了该图像,是的,有人可以进入其他层之一并查看秘密文件。有没有注意到,当您拉取 Docker 映像时,您有时会看到它拉动了几层?您会注意到每一层都有一个哈希 ID - 您实际上可以直接使用这些哈希 ID 从堆栈中的任何层启动容器。从那里,用户可以覆盖入口点和命令,获取 shell 并进行探索。(或者他们可以直接查看 /var/lib/docker 文件夹并在那里查看。) (4认同)

Fee*_*Fee 9

2023年

对于 BuildKit,不存在像squash. 您可以运行docker build --squash=true .,但随后您会收到消息:

警告:实验性标志挤压已随 BuildKit 删除。为了提高效率,您应该使用多阶段 Dockerfile 压缩内部构建。

这是如何运作的?

FROM scratch简单地像这样开始:

FROM nice-image:latest AS base

RUN command-that-gives-huge-diff
RUN more-things

# can also do multiple times
FROM scratch #(AS something)

COPY --from=base / /
Run Code Online (Sandbox Code Playgroud)

实际例子

在(据我所知)上安装任何东西都archlinux:latest需要初始化 pacman 数据库。这将获取超级新的 pacman 存储库。在不升级的情况下安装任何东西可能行不通,因为它将引用新的存储库,而旧的存储库已安装。因此,要更新,请运行pacman -Syu,它显示:

总下载大小:87.56 MiB
总安装大小:359.99 MiB
网络升级大小:4.99 MiB

这是可以避免的容器尺寸的巨大增加!(由于保存了层之间的差异,容器大小的增加大约>360MiB,尽管文件系统的总大小只会增加~5MiB)

这是相关的 dockerfile,我在其中安装了 gpg1:

ARG BASE=archlinux:latest

FROM $BASE as base # use this stage for running system updates

RUN pacman -Syu --noconfirm

# start magic
FROM scratch as stage1

COPY --from=base / /
# end magic

# start arch build stuff
RUN pacman -Syu --noconfirm && \
    pacman -S --noconfirm base-devel bzip2 curl libldap libusb-compat pinentry readline zlib && \
    useradd --create-home --shell /bin/bash user

USER user
WORKDIR /home/user

RUN curl -L -O https://aur.archlinux.org/cgit/aur.git/snapshot/gnupg1.tar.gz && \
    tar -xvf gnupg1.tar.gz && \
    cd gnupg1 && \
    makepkg --skippgpcheck
#end arch build stuff

FROM scratch AS final

# so now this is the initial container
COPY --from=base / /

# copy built package from stage1
COPY --from=stage1 /home/user/gnupg1/gnupg1-1.4.23-1-x86_64.pkg.tar.zst /home/gnupg1-1.4.23-1-x86_64.pkg.tar.zst

#install the package (no need for -Syu, since we copied from base) and clean
RUN pacman -U --noconfirm /home/gnupg1-1.4.23-1-x86_64.pkg.tar.zst && \
    pacman -Scc --noconfirm && \
    rm -f /var/lib/pacman/sync/*

#this saves only like 10MB, so not really necessary
FROM scratch

COPY --from=final / /
Run Code Online (Sandbox Code Playgroud)