如何为docker创建基础镜像(用于创建用户定义的镜像)?

pjngdqdw  于 2023-08-03  发布在  Docker
关注(0)|答案(1)|浏览(106)

假设我们有以下Dockerfile:

FROM alpine:latest
...
ENTRYPOINT ["./main"]

字符串
alpine:latest是如何创建的?
我找到的解释是关于使用scratch来使docker镜像变小,但它们还是使用了一些其他的镜像来执行初始操作,例如:

FROM alpine:latest as build
# Do some stuff
# Get compiled binary ./main
FROM scratch
COPY ./main .
# Copy whatever we need to make our binary work
ENTRYPOINT ["./main"]


但是他们是如何创建alpine:latestscratch的呢?

qv7cva1a

qv7cva1a1#

Docker Hub alpine image page有指向Dockerfiles的链接。例如,这给了你this Dockerfile for Alpine 3.18(全文引用):

FROM scratch
ADD alpine-minirootfs-3.18.2-x86_64.tar.gz /
CMD ["/bin/sh"]

字符串
所以这个镜像实际上是从scratch开始的,但是两个重要的细节是它在tar文件中有一个完整的Alpine根文件系统,并且Dockerfile ADD指令可以解压缩和扩展归档。CMD只是一个默认的东西。
事实上,您可以构建自己的映像FROM scratch,但需要注意一些。大多数Linux二进制文件都是 * 动态链接的 *,这意味着它们至少需要两个部分,一个 * 动态加载器 *(例如/lib/ld-linux.so.2)和 * 共享库 *(如/lib/lib.so.6)。手工管理这些可能有点棘手。
如果你可以构建一个 *static二进制文件 ,这将把所有的共享库依赖项嵌入到二进制文件本身,你可以在FROM scratch映像中使用它。我觉得我最常看到的是Go应用程序,尽管你可以将它用于任何本机编译语言(也包括C,C++,Rust);这个答案有完整的例子。
如果您不能构建静态二进制文件,或者确实需要一些语言运行时(无论你使用的是像Python或JavaScript这样的解释性语言,还是像Java或Elixir这样的字节码语言),那么你可能会发现使用alpinedebian,或ubuntu基础,而不是尝试构建映像FROM scratch(如果您还不熟悉Linux共享库的话)。
如果你想学习或实验,你可以从一个busybox图像开始。BusyBox是一个静态编译工具(因此没有共享库依赖),包含大量的核心Unix工具;对应的Docker镜像不包含C共享库基础结构。这意味着即使你破坏了系统C库,(a)它在一个容器中,不会影响你的主机,(b)你有静态链接的sh,`ls,
等 *,仍然可以尝试调试。

相关问题