使用包和依赖项手动构建图像
Manually build image with packages and dependencies
我正在尝试仅使用某些组件构建基本映像 - 在我的例子中,只是 运行 java 应用程序的一些包。这个想法是尽可能减少。
我的问题是如何获得获得最佳图像所需的最低限度并获得我的包的所有依赖项(如 openssl)到 运行 而没有问题?
我知道 。但是,它表明我们仍然需要手动复制所有依赖项。有更好的方法吗?这样我就可以自动将所有依赖项和可执行文件本身复制到新映像中。
我曾经写过一个名为 dockerize 的工具,它可以满足您的大部分需求。给定一条命令,它会读取嵌入在该命令中的动态链接器的名称,然后使用它来获取依赖项列表,并使用该列表构建 Docker 图像。
例如,运行 为 dockerize -o openssl /usr/bin/openssl
,这将生成一个包含 Dockerfile
和所有必要文件的目录:
openssl
├── Dockerfile
├── etc
│ ├── group
│ ├── nsswitch.conf
│ └── passwd
├── lib64
│ ├── ld-linux-x86-64.so.2
│ ├── libcrypto.so.1.1
│ ├── libc.so.6
│ ├── libdl.so.2
│ ├── libnss3.so
│ ├── libnssckbi.so
│ ├── libnss_compat-2.33.so
│ ├── libnss_compat.so.2
│ ├── libnss_dns-2.33.so
│ ├── libnss_dns.so.2
│ ├── libnss_files-2.33.so
│ ├── libnss_files.so.2
│ ├── libnss_libvirt_guest.so.2
│ ├── libnss_libvirt.so.2
│ ├── libnss_mdns4_minimal.so.2
│ ├── libnss_mdns4.so.2
│ ├── libnss_mdns6_minimal.so.2
│ ├── libnss_mdns6.so.2
│ ├── libnss_mdns_minimal.so.2
│ ├── libnss_mdns.so.2
│ ├── libnss_myhostname.so.2
│ ├── libnss_mymachines.so.2
│ ├── libnss_resolve.so.2
│ ├── libnss_sss.so.2
│ ├── libnsssysinit.so
│ ├── libnss_systemd.so.2
│ ├── libnssutil3.so
│ ├── libpthread.so.0
│ ├── libresolv-2.33.so
│ ├── libresolv.so
│ ├── libresolv.so.2
│ ├── libssl.so.1.1
│ └── libz.so.1
└── usr
└── bin
└── openssl
从该目录构建一个 Docker 图像会生成一个功能齐全的 openssl
二进制文件。
现在,您是在多阶段 Dockerfile
的背景下提出这个问题。这可能看起来像这样:
FROM ubuntu:bionic as base
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
openssl \
python3 \
python3-pip \
rsync \
&& \
apt-get clean
RUN pip3 install git+https://github.com/larsks/dockerize
RUN dockerize -o /tmp/openssl -n /usr/bin/openssl
FROM scratch
COPY --from=base /tmp/openssl/ /
ENTRYPOINT ["/usr/bin/openssl"]
这会在构建阶段安装 dockerize
,并使用它来生成包含目标命令及其依赖项的目录,然后在最后阶段将其复制到临时映像中。
dockerize
脚本没有什么特别之处;它主要是一个方便的包装器,我们可以实现类似的结果:
FROM ubuntu:bionic as base
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
openssl \
&& \
apt-get clean
RUN mkdir /tmp/openssl
# The following command (a) produces a list of files to copy into
# the target directory, and then (b) uses `xargs` and `cp` to copy
# them.
#
# We list the binary itself, the appropriate dynamic interpreter, and
# then we use `ldd` to get a list of dependencies from the binary.
RUN (echo /usr/bin/openssl; \
echo /lib64/ld-linux*; \
ldd /usr/bin/openssl | awk '/=>/ {print }') | \
xargs -iFILE sh -c 'mkdir -p /tmp/openssl/$(dirname FILE); cp FILE /tmp/openssl/FILE'
FROM scratch
COPY --from=base /tmp/openssl/ /
ENTRYPOINT ["/usr/bin/openssl"]
对于您的 特定 示例,这也会生成 运行nable openssl
图像。
我正在尝试仅使用某些组件构建基本映像 - 在我的例子中,只是 运行 java 应用程序的一些包。这个想法是尽可能减少。
我的问题是如何获得获得最佳图像所需的最低限度并获得我的包的所有依赖项(如 openssl)到 运行 而没有问题?
我知道
我曾经写过一个名为 dockerize 的工具,它可以满足您的大部分需求。给定一条命令,它会读取嵌入在该命令中的动态链接器的名称,然后使用它来获取依赖项列表,并使用该列表构建 Docker 图像。
例如,运行 为 dockerize -o openssl /usr/bin/openssl
,这将生成一个包含 Dockerfile
和所有必要文件的目录:
openssl
├── Dockerfile
├── etc
│ ├── group
│ ├── nsswitch.conf
│ └── passwd
├── lib64
│ ├── ld-linux-x86-64.so.2
│ ├── libcrypto.so.1.1
│ ├── libc.so.6
│ ├── libdl.so.2
│ ├── libnss3.so
│ ├── libnssckbi.so
│ ├── libnss_compat-2.33.so
│ ├── libnss_compat.so.2
│ ├── libnss_dns-2.33.so
│ ├── libnss_dns.so.2
│ ├── libnss_files-2.33.so
│ ├── libnss_files.so.2
│ ├── libnss_libvirt_guest.so.2
│ ├── libnss_libvirt.so.2
│ ├── libnss_mdns4_minimal.so.2
│ ├── libnss_mdns4.so.2
│ ├── libnss_mdns6_minimal.so.2
│ ├── libnss_mdns6.so.2
│ ├── libnss_mdns_minimal.so.2
│ ├── libnss_mdns.so.2
│ ├── libnss_myhostname.so.2
│ ├── libnss_mymachines.so.2
│ ├── libnss_resolve.so.2
│ ├── libnss_sss.so.2
│ ├── libnsssysinit.so
│ ├── libnss_systemd.so.2
│ ├── libnssutil3.so
│ ├── libpthread.so.0
│ ├── libresolv-2.33.so
│ ├── libresolv.so
│ ├── libresolv.so.2
│ ├── libssl.so.1.1
│ └── libz.so.1
└── usr
└── bin
└── openssl
从该目录构建一个 Docker 图像会生成一个功能齐全的 openssl
二进制文件。
现在,您是在多阶段 Dockerfile
的背景下提出这个问题。这可能看起来像这样:
FROM ubuntu:bionic as base
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
openssl \
python3 \
python3-pip \
rsync \
&& \
apt-get clean
RUN pip3 install git+https://github.com/larsks/dockerize
RUN dockerize -o /tmp/openssl -n /usr/bin/openssl
FROM scratch
COPY --from=base /tmp/openssl/ /
ENTRYPOINT ["/usr/bin/openssl"]
这会在构建阶段安装 dockerize
,并使用它来生成包含目标命令及其依赖项的目录,然后在最后阶段将其复制到临时映像中。
dockerize
脚本没有什么特别之处;它主要是一个方便的包装器,我们可以实现类似的结果:
FROM ubuntu:bionic as base
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
openssl \
&& \
apt-get clean
RUN mkdir /tmp/openssl
# The following command (a) produces a list of files to copy into
# the target directory, and then (b) uses `xargs` and `cp` to copy
# them.
#
# We list the binary itself, the appropriate dynamic interpreter, and
# then we use `ldd` to get a list of dependencies from the binary.
RUN (echo /usr/bin/openssl; \
echo /lib64/ld-linux*; \
ldd /usr/bin/openssl | awk '/=>/ {print }') | \
xargs -iFILE sh -c 'mkdir -p /tmp/openssl/$(dirname FILE); cp FILE /tmp/openssl/FILE'
FROM scratch
COPY --from=base /tmp/openssl/ /
ENTRYPOINT ["/usr/bin/openssl"]
对于您的 特定 示例,这也会生成 运行nable openssl
图像。