由于您的 Dockerfile 中有一行读取 RUN yarn(即不使用 yarn 的离线选项),因此 yarn 会尝试确定互联网是否有可能在不发送任何数据包的情况下自动可用。
yarn如何查看在线状态?
这是通过使用节点的os.networkInterfaces() 枚举 docker builder 上下文中的可用网络接口来完成的,记录在 here 中。
这反过来又调用了由 libuv 的uv_interface_addresses 支持的GetInterfaceAddresses。 libuv 函数只返回分配了 IP 地址并设置了 IFF_UP 和 IFF_RUNNING 标志的接口。
要查看实际将哪些地址返回到 Javascript 代码,您可以暂时将此行添加到 Dockerfile:
RUN node -e 'const os = require("os"); const interfaces = os.networkInterfaces(); for (const interface in interfaces) {console.log(interface); const addrs = interfaces[interface]; for (const addr of addrs) {console.log(addr.address)}}'
至少在我的情况下,这只返回了环回地址,yarn 在1 中明确忽略了这个地址:
lo
127.0.0.1
::1
但是在 docker 镜像中运行 ifconfig 也会显示一个 eth0 接口。此接口的HWaddr 与运行 docker 守护程序的机器上的docker0 接口相匹配。这表明构建器上下文与 docker bridge 网络一起运行。
那么从 libuv 的列表中排除桥接网络的标准是什么?
在我的例子中,docker 网络没有设置IFF_RUNNING。这并不奇怪,因为Linux documentation 说这个字段是为了向后兼容。
要验证您的实例是否属于这种情况,您可以使用 this document 中示例程序的略微修改版本,在第一个 printf() 调用之后添加此代码:
printf("RUNNING: %s", (ifa->ifa_flags & IFF_RUNNING) ? "TRUE" : "FALSE");
为什么 docker 没有设置IFF_RUNNING?
设置接口标志是 docker 不会自行处理的低级操作。 Docker 的 libnetwork 委托给 netlink 库 here,但 netlink 只委托给 sets IFF_UP。
如何解决?
与此问题相关的活动部分是开源的!
netlink 是 changed 以公开 IFF_RUNNING 以供阅读 - 可以通过对 netlink 的进一步更改来启用 libnetwork(以及因此 docker)来设置该标志。
libuv 也可以在Github issue on the subject 之后扩展。这样一个新的 API 最终可以在 node.js 和 yarn 中使用,无论分配的 IP 地址和IFF_RUNNING 状态如何,都会列出接口。