Docker: 最后的节点高山图像是否比完整节点图像小?
Docker: Are node alpine images at the end smaller then full node images?
我正在 运行 建立一个 nodeJS 应用程序集群 - 它应该非常小,因为它们 运行 作为微服务。他们中只有少数人需要额外的东西,比如 bcrypt 或 imagemagick - 这不时给我带来一些麻烦。
现在我正在使用 node:10.13-alpine
作为所有 Dockerfile 的基础映像来构建我的应用程序。对于其中一些,我需要通过 apk
等添加依赖项。所以这些图像变大了。这是使用 alpine 图像的最佳方法吗,它通过添加所需的包(例如 python、gcc...)变得更大?或者我应该使用完整图像?
如果我使用 node:10.13
,基本图像会大很多,但如果我的理解是正确的,我的应用程序将只添加一个小层,因为使用相同的基本图像。所以最后还是用一张大节点图片比较好??
Alpine 图像较小,因为其他软件包使用了很多您的解决方案未使用的库。
使用小图片有什么好处?
好处是:更少的内存、更好的性能、安全性和可维护性。
较小的 docker 图像减少了磁盘所需的大小,但是 磁盘 space 很便宜。
更重要的是它还消耗更少的内存,这在每台服务器上都是有限的。如果你减少服务器上的基础镜像数量,这也会导致你需要更少的内存。更少的内存也意味着更少的交换,因此您可以通过将所有基本图像加载到内存中来获得一些性能改进。
另一个特点是,来自 alpine 的基础图像使用较少的依赖库,提高了整体安全性。您可以使用基本的 alpine 图像轻松分离风险,并使用仅使用真正需要的 apk 的顶级图像。这对于整体维护也有好处。
在https://hub.docker.com/r/library/node/tags/上可以看到,alpine版本没有漏洞。所有其他图像版本都有一些问题,这可能会针对您的解决方案的安全性。
为什么默认值仍然是 "buildpack-deps" 以及为什么您应该使用它们?
当您阅读 docker 节点图像的官方文档时:
https://hub.docker.com/_/node/
主要要点是:
- 您可以使用普通图像,因为它是基于 "buildpack-deps" 的,很多图像都常用。
- Alpine 图像非常小,减少了所需的内存量。特别是docker容器没有其他类型的安装。
对我来说,这最终意味着,如果您使用基于 "buildpack-deps" 构建的其他图像,则在大多数情况下您可以使用普通包。在这种情况下,这可能是更好的解决方案,因为除了 "buildpack-deps" 之外,您不需要在磁盘和内存中保存 "alpine" 基本映像。
结论
如果您的 docker 环境中有 "only" alpine 镜像,那么您应该使用 "alpine",或者如果 "node" 容器的安全性真的很重要你.
在大多数情况下,基于 "buildpack-deps" 的 "node" 图像是合适的,因为您还有其他基于 "buildpack-deps" 的 docker 容器。
我假设将来会有越来越多的包基于 "alpine" 可用,然后你应该使用 node-alpine。
一般来说,是的,alpine 图像比预烘焙二进制文件附带的官方节点图像更好。
但这是高度特定于案例的。
- 如果您进行大量自定义,即使使用官方节点映像,您最终仍可能会添加依赖项。
- 如果您没有大量自定义,与官方节点图像相比,向节点 alpine 添加小的依赖项在大小和构建时间方面不会花费您太多。
- 如果你有复杂的依赖关系(有时文档可能很差),在官方节点图像中一切正常,但你需要不遗余力地让事情在 node alpine 中工作,但它仍然会不稳定。 (这发生在我身上一次
libpng16-dev
包,它只适用于官方节点图像,我无法弄清楚为什么即使在尝试了几天之后它也不能与节点高山一起使用)。
所以总而言之,通常选择 node alpine 是个好主意,除非你有一个复杂的设置并且官方 node 图像使你的事情变得更容易。
我使用过的几乎所有节点容器,其中 90% 运行 在 alpine 图像上。
如果您是 运行 nodejs 10 或更高版本,请考虑使用 alpine 检测到的内存泄漏问题:
我正在 运行 建立一个 nodeJS 应用程序集群 - 它应该非常小,因为它们 运行 作为微服务。他们中只有少数人需要额外的东西,比如 bcrypt 或 imagemagick - 这不时给我带来一些麻烦。
现在我正在使用 node:10.13-alpine
作为所有 Dockerfile 的基础映像来构建我的应用程序。对于其中一些,我需要通过 apk
等添加依赖项。所以这些图像变大了。这是使用 alpine 图像的最佳方法吗,它通过添加所需的包(例如 python、gcc...)变得更大?或者我应该使用完整图像?
如果我使用 node:10.13
,基本图像会大很多,但如果我的理解是正确的,我的应用程序将只添加一个小层,因为使用相同的基本图像。所以最后还是用一张大节点图片比较好??
Alpine 图像较小,因为其他软件包使用了很多您的解决方案未使用的库。
使用小图片有什么好处?
好处是:更少的内存、更好的性能、安全性和可维护性。
较小的 docker 图像减少了磁盘所需的大小,但是 磁盘 space 很便宜。
更重要的是它还消耗更少的内存,这在每台服务器上都是有限的。如果你减少服务器上的基础镜像数量,这也会导致你需要更少的内存。更少的内存也意味着更少的交换,因此您可以通过将所有基本图像加载到内存中来获得一些性能改进。
另一个特点是,来自 alpine 的基础图像使用较少的依赖库,提高了整体安全性。您可以使用基本的 alpine 图像轻松分离风险,并使用仅使用真正需要的 apk 的顶级图像。这对于整体维护也有好处。
在https://hub.docker.com/r/library/node/tags/上可以看到,alpine版本没有漏洞。所有其他图像版本都有一些问题,这可能会针对您的解决方案的安全性。
为什么默认值仍然是 "buildpack-deps" 以及为什么您应该使用它们?
当您阅读 docker 节点图像的官方文档时:
https://hub.docker.com/_/node/
主要要点是:
- 您可以使用普通图像,因为它是基于 "buildpack-deps" 的,很多图像都常用。
- Alpine 图像非常小,减少了所需的内存量。特别是docker容器没有其他类型的安装。
对我来说,这最终意味着,如果您使用基于 "buildpack-deps" 构建的其他图像,则在大多数情况下您可以使用普通包。在这种情况下,这可能是更好的解决方案,因为除了 "buildpack-deps" 之外,您不需要在磁盘和内存中保存 "alpine" 基本映像。
结论
如果您的 docker 环境中有 "only" alpine 镜像,那么您应该使用 "alpine",或者如果 "node" 容器的安全性真的很重要你.
在大多数情况下,基于 "buildpack-deps" 的 "node" 图像是合适的,因为您还有其他基于 "buildpack-deps" 的 docker 容器。
我假设将来会有越来越多的包基于 "alpine" 可用,然后你应该使用 node-alpine。
一般来说,是的,alpine 图像比预烘焙二进制文件附带的官方节点图像更好。
但这是高度特定于案例的。
- 如果您进行大量自定义,即使使用官方节点映像,您最终仍可能会添加依赖项。
- 如果您没有大量自定义,与官方节点图像相比,向节点 alpine 添加小的依赖项在大小和构建时间方面不会花费您太多。
- 如果你有复杂的依赖关系(有时文档可能很差),在官方节点图像中一切正常,但你需要不遗余力地让事情在 node alpine 中工作,但它仍然会不稳定。 (这发生在我身上一次
libpng16-dev
包,它只适用于官方节点图像,我无法弄清楚为什么即使在尝试了几天之后它也不能与节点高山一起使用)。
所以总而言之,通常选择 node alpine 是个好主意,除非你有一个复杂的设置并且官方 node 图像使你的事情变得更容易。
我使用过的几乎所有节点容器,其中 90% 运行 在 alpine 图像上。
如果您是 运行 nodejs 10 或更高版本,请考虑使用 alpine 检测到的内存泄漏问题: