docker容器如何从头开始执行二进制文件?

docker容器如何从头开始执行二进制文件?,docker,shell,Docker,Shell,表示您可以构建此最小映像: FROM scratch ADD hello / CMD ["/hello"] 大概这种工作方式是CMD步骤使用默认shell(即bin/sh,per)运行hello可执行文件 但如果SCRATCH真的是完全空的,bin/sh从哪里来?为什么我的图像包含一个外壳?从scratch构建的容器在开始时没有任何内部内容,因此您的图像不包含/bin/sh 但是,这里有两种重要的CMD格式: CMD ["/hello"] CMD /he

表示您可以构建此最小映像:

FROM scratch
ADD hello /
CMD ["/hello"]
大概这种工作方式是
CMD
步骤使用默认shell(即
bin/sh
,per)运行
hello
可执行文件


但如果SCRATCH真的是完全空的,
bin/sh
从哪里来?为什么我的图像包含一个外壳?

scratch
构建的容器在开始时没有任何内部内容,因此您的图像不包含
/bin/sh

但是,这里有两种重要的
CMD
格式:

CMD ["/hello"]
CMD /hello
第一种格式指定完整的命令,并通过
execve(2)
直接调用。实际执行的过程与
[“/hello”]
完全相同(即
argc==1

第二种格式指定一个“entrypoint参数”,并作为单个参数传递给entrypoint,因此Docker将尝试运行
[“/bin/sh”、“-c”、“/hello”]
,并使用
argc==3
失败


您可以将CMD行替换为
CMD/hello
,并亲自观察。

scratch
构建的容器在开始时没有任何内部内容,因此您的图像不包含
/bin/sh

但是,这里有两种重要的
CMD
格式:

CMD ["/hello"]
CMD /hello
第一种格式指定完整的命令,并通过
execve(2)
直接调用。实际执行的过程与
[“/hello”]
完全相同(即
argc==1

第二种格式指定一个“entrypoint参数”,并作为单个参数传递给entrypoint,因此Docker将尝试运行
[“/bin/sh”、“-c”、“/hello”]
,并使用
argc==3
失败


您可以将CMD行替换为
CMD/hello
,然后自己观察它。

这很有意义!那么接下来的一个基本问题是——为什么我要将我的二进制文件作为容器分发,而不仅仅是作为二进制文件本身?是为了系统间的互操作性,如果是容器,任何人都可以提取我的映像并使用docker运行它,但二进制文件是针对特定的os/arch编译的吗?@sherz1如果二进制文件是静态链接的,那么单独分发与在容器中分发几乎没有区别。但是,如果体系结构不同,将其包装在容器中也无济于事。如果没有特殊的翻译帮助,您仍然无法在x86机器上运行ARM二进制。@sherz1但是,如果它是动态链接的或需要额外的库,容器可以确保执行环境保持一致,因此您不必担心丢失库的错误库版本等。这很有意义!那么接下来的一个基本问题是——为什么我要将我的二进制文件作为容器分发,而不仅仅是作为二进制文件本身?是为了系统间的互操作性,如果是容器,任何人都可以提取我的映像并使用docker运行它,但二进制文件是针对特定的os/arch编译的吗?@sherz1如果二进制文件是静态链接的,那么单独分发与在容器中分发几乎没有区别。但是,如果体系结构不同,将其包装在容器中也无济于事。如果没有特殊的翻译帮助,您仍然无法在x86机器上运行ARM二进制。@sherz1但是,如果它是动态链接的或需要额外的库,容器可以确保执行环境保持一致,因此您不必担心丢失库的错误库版本等。