Maison > Article > interface Web > Parlons de la façon de choisir la meilleure image Docker Node.js ?
Choisir une image NodeDocker peut sembler une petite chose, mais la taille et les vulnérabilités potentielles de l'image peuvent avoir un impact significatif sur votre processus CI/CD et votre sécurité. Alors, comment choisir la meilleure image Docker Node.js ?
Lorsque nous utilisons FROM node:latest
ou simplement FROM node
, il est facile d'ignorer ses risques potentiels. Si vous ne connaissez pas le risque de sécurité global et que vous l'introduisez dans le processus CI/CD, cela exacerbera sans aucun doute le risque. [Tutoriels associés recommandés : FROM node:latest
或只是FROM node
时,很容易忽略他潜在的风险。如果你不知道总体的安全风险并且把他引入到了CI/CD的流程中,那无疑是加剧了这个风险。【相关教程推荐:nodejs视频教程、编程教学】
下面这个例子非常典型,你可以从很多教程或者博客文章中看到这个Node.js Dockerfile的配置。但是这个Dockerfile的配置存在很大的问题,非常不推荐这样使用:
FROM node WORKDIR /usr/src/app COPY . /usr/src/app RUN npm install CMD "npm" "start"
译者注:如果需要跳过分析直接看结论,请直接滑到文末。
当你构建一个Node.js镜像的时候,实际上有很多选择。其中就包括了Node.js核心团队维护的官方Docker镜像,以及从特定的基础镜像中选择的特殊Node.js镜像版本。还可以选择其他的,比如谷歌在distroless
项目上构建的Node.js应用程序,或者是Docker官方团队提供的一个名为scratch
的镜像。
在这些Node.js的Docker镜像中,哪一个是最适合你的呢?
让我们一个一个的去分析,了解更多他们的好处和潜在风险。
作者注:在这篇文章中,我将会比较18.2.0这个版本的Node.js镜像,他的发布时间是2022年6月左右。
我们先从维护的node镜像开始。它是由进行正式地维护的,包含了一些基础的镜像tag。这些tag对应到不同的底层发行版(Debian、Ubuntu、Alpine)以及不同版本的Node.js运行时本身。还有针对不同CPU架构的特定版本tag,例如amd64
和arm64x8
(新版苹果的M1)。
Debian发行版中最常见的node
镜像,例如bullseye
或buster
,他们都是基于由另一个团队维护的buildpack-deps
的。
当你基于这个默认的node
镜像构建Node.js Docker镜像时会发生什么?
FROM node
使用docker build --no-cache -f Dockerfile1 -t dockerfile1
构建镜像时,就会出现下面这些:
node
是node:last
的一个别名,他的版本指向的是18.2.0
这个最新的Node.js镜像的依赖和安全漏洞足迹是什么呢?我们可以用docker scan dockerfile1
来运行一个Synk-powered
容器,就会得到下面的结果:
curl/libcurl4
、git/git-man
、imagemagick/imagemagick-6-common
。Buffer Overflows
、use-after-free errors
、out-of-bounds write
等。DNS Rebinding
、HTTP Request Smuggling
、Configuration Hijacking
Tutoriel vidéo Nodejs🎜🎜🎜Ce qui suit Un exemple est très typique, vous pouvez voir la configuration de ce Dockerfile Node.js à partir de nombreux tutoriels ou articles de blog. Cependant, il y a de gros problèmes avec la configuration de ce Dockerfile, et il est fortement déconseillé de l'utiliser de cette façon :
FROM node:bullseye复制代码🎜🎜Note du traducteur : si vous devez ignorer l'analyse et accéder directement à la conclusion, veuillez faire défiler directement jusqu’à la fin de l’article. 🎜
distroless
, ou une image appelée scratch
fournie par l'équipe officielle Docker. 🎜🎜Parmi ces images Docker Node.js, laquelle vous convient le mieux ? 🎜🎜Analysons-les un par un pour en savoir plus sur leurs avantages et leurs risques potentiels. 🎜🎜🎜Note de l'auteur : Dans cet article, je comparerai l'image Node.js de la version 18.2.0, qui sortira vers juin 2022. 🎜🎜🎜🎜amd64
et arm64x8
(nouvelle version du M1 d'Apple). 🎜🎜Les images node
les plus courantes dans les distributions Debian, telles que bullseye
ou buster
, sont basées sur maintenu par une autre équipe >buildpack -deps
. node
par défaut ? 🎜FROM node:bullseye-slim🎜Lorsque vous utilisez
docker build --no-cache -f Dockerfile1 -t dockerfile1
pour créer l'image, ce qui suit apparaîtra : 🎜node
est un alias de node:last
, et sa version pointe vers 18.2.0
🎜docker scan dockerfile1
pour exécuter un conteneur Synk-powered
, et nous obtiendrons les résultats suivants : 🎜curl/libcurl4
, git/git-man
, imagemagick/imagemagick-6-common
>. 🎜Débordements de tampon
, des erreurs d'utilisation après libération
, hors limites. écrire
etc. 🎜Reliaison DNS
, Smuggling de requêtes HTTP
, Détournement de configuration
🎜🎜🎜🎜Note du traducteur : 🎜你真的需要在Node.js镜像中给你的应用提供wget
、git
、curl
吗?在Node.js Docker镜像中,有成百上千个依赖和工具,而这些依赖又对应着成百上千个漏洞。Node.js运行时的特性对应着7个不同的安全漏洞,给潜在攻击留下了很大的空间。总的来说,情况并不是很乐观。
如果你在Node.js Docker Hub仓库上浏览可用tags,你将会发现有两个Node.js镜像tags - node:buster
和node:bullseye
。
这两个Docker镜像tags都基于Debian发行版。buster
镜像tag对应着Debian10,将会在2022年8月到2024年进入到他的End of Life日期,所以buster
不是一个很好的选择。bullseye
镜像tag对应着Debian11,被当做Debian的当前稳定版本,预计EOL日期为2026年6月。
译者注:
- End of Life。特指产品寿命的结束,通常缩写为EOL。
因此,十分建议你将所有新的和现有的Node.js Docker镜像从node:buster
迁移到node:bullseye
或者其他合适的可替代版本。
我们先构建一个新的Node.js Docker镜像基于:
FROM node:bullseye复制代码
如果你构建了这个Node.js Docker镜像tag并且与之前使用node:latest
的结果进行比较,将会得到完全相同的大小、依赖数量和发现的漏洞。原因是node
、node:latest
、node:bullseye
全部指向了同一个正在构建的Node.js镜像tag。
官方的Node.js团队还维护了一个显式地针对功能性Node.js环境所需工具的镜像tag并且不会存在其他的东西。
这个Node.js镜像tags是通过slim
镜像tag变量来引用的,比如node:bullseye-slim
,或者带有Node.js指定版本,像node:14.19.2 -slim
。
我们再来基于Debian的当前稳定版本的bullseye
构建一个Node.jsslim
镜像:
FROM node:bullseye-slim
就容器镜像大小和安全状况而言,node:bullseye-slim
已经是一个比较好的起点了。
到目前为止,我们的Node.js Docker镜像基于当前版本的Node.js,即Node.js18。但是根据Node.js的发布时间表,这个版本直到2022年10月才进入正式的Active LTS
状态。
译者注:LTS - Long-term support,即长期支持版本。
如果我们总是依赖于我们正在构建的Node.js Docker镜像中的LTS版本的话会怎么样?我们先更新这个Docker镜像tag并构建一个新的Node.js镜像:
FROM node:lts-bullseye-slim
瘦身后的Node.js LTS版本(16.15.0)在镜像上带来了相似数量的依赖、安全漏洞和一个略小的体积(188MB)。
因此,尽管你可能需要在LTS和当前Node.js运行时版本中选择,但他们都不会对Node.js镜像的软件占用空间有大的影响。
Node.js Docker团队维护了一个node:alpine
镜像tag以及他的变体,以便将Alpine Linux发行版的特定版本与Node.js运行时的特定版本进行匹配。
Alpine Linux项目经常因为其非常小的镜像体积而被引用,小体积意味着更新的软件占用空间和更少的漏洞,确实十分不错。
下面的命令会让Dockerfile去生成一个node环境,这个将会增加未压缩的镜像体积:
FROM node:alpine
这个将会产生一个178MB大小的docker镜像,和slim
Node.js镜像大小差不多,但是在alpine
镜像tag中,只检测到了16个系统依赖漏洞和2个安全安全漏洞。这就意味着alpine
镜像tag对于小体积和漏洞数量来说是一个比较好的选择。
alpine
对Node.js镜像可能提供了一个较小的镜像体积和更少的漏洞数量。但是,我们必须意识到Alpine项目使用musl
作为C标准库的实现。而Debian的Node.js镜像tag依赖于glibc
实现,比如bullseye
和slim
。这些差异可以解释性能问题、功能性的bug或者是潜在的应用程序崩溃,这些都是由于底层C库的差异造成的。
选择一个alpine
的Node.js镜像tag意味着你实际上是在选择一个非官方的Node.js运行时。Node.js Docker团队并不会正式支持基于alpine
的容器镜像构建。因此,他声明基于Alpine的镜像tag是实验性的,并且可能和官方的构建不一致。
如果你正在选一个一个基于Alpine的Node.js Docker镜像,需要记住一点,Docker安全工具(例如Trivy或Snyk)目前无法检测到Alpine镜像中与运行时相关的漏洞的。虽然这种情况未来可能会改变,但是目前还不能找到Node.js18.2.0alpine
基础镜像tag的安全漏洞,而18.2.0运行时本身实际上是容易受到攻击的。这与安全工具本身有关,而不是与Alpine基础镜像有关,但是也应该考虑到这一点。
distroless
(无损)Docker镜像我们的基准测试的最后一个比较项目是谷歌的Distroless容器镜像。
distroless
容器镜像?这种镜像甚至比slim
的Node.js镜像更加小,因为distroless
镜像只针对这个应用和应用运行时的依赖性而已。因此,一个distroless
的docker镜像没有容器包管理器、shell、或者其他通用工具的依赖性,这使得它们的体积更小,漏洞也更少。
幸运的是,Distroless项目为Node.js维护了一个特殊运行时的distroless
docker镜像,通过其完整的命名空间识别为grc.io/distroless/nodejs-debian11
,并且可以在谷歌的容器注册表中找到(这个是gcr.io
的部分)。
因为Distroless容器镜像没有软件,我们可以使用一个docker的多阶段工作流来为我们的容器安装依赖项,并且把它们复制到Distroless镜像:
FROM node:16-bullseye-slim AS build WORKDIR /usr/src/app COPY . /usr/src/app RUN npm install FROM gcr.io/distroless/nodejs:16 COPY --from=build /usr/src/app /usr/src/app WORKDIR /usr/src/app CMD ["server.js"]
构建这个distroless
docker镜像将产生112MB的文件,而在slim
和alpine
镜像tag来说,这已经减小了很多文件的体积了。
如果你正在考虑使用distroless
docker镜像,有一些重要的事项需要注意:
glibc
实现,并且不太可能在生产环境出现一些奇怪的问题。nodejs:16
的标记(该标记经常更新),或者在一个特定时间点根据镜像的SHA256哈希值进行安装。
我们可以参考下面的表格来总结不同Node.js Docker镜像tags之间的比较:
Balise d'image | Version d'exécution de Node.js | Dépendances du système d'exploitation | Vulnérabilités de sécurité du système d'exploitation | Vulnérabilités élevées et critiques | Vulnérabilités moyennes | Vulnérabilités faibles | Vulnérabilité d'exécution de Node.js capacités | Taille de l'image | Fil disponible |
---|---|---|---|---|---|---|---|---|---|
node | 18.2.0 | 409 | 289 | 54 | 18 | 217 | 7 | 952MB | Oui |
node:bullseye | 18.2.0 | 409 | 289 | 54 | 18 | 217 | 7 | 952MB | Oui |
node:bullseye-slim | 18.2.0 | 97 | 56 | 4 | 8 | 44 | 7 | 246MB | Oui |
node:lts-bullseye-slim | 16.15.0 | 97 | 55 | 4 | 7 | 44 | 6 | 188 Mo | Oui |
node:alpine | 18.2.0 | 16 | 2 | 2 | 0 | 0 | 0 | 178MB | Oui |
gcr.io/distroless/nodejs:16 | 16.17.0 | 9 | 11 | 0 | 0 | 11 | 0 | 112MB | Non |
我们来Balises de base de données Node.js的数据和见解,然后确定哪个是最理想的。
如Le tag Node.js est utilisé pour créer des balises. La bataille est terminée. , 所有3主要操作系统都使用不同的C库实现。Linux glibc,Alpine依赖musl,而macOS有自己的BSD libc实现。
有时候,镜像大小也很重要。更准确地说,我们的目标不是拥有最小的体积,而是拥有最小的整体软件占用。在这种情况下,slim
镜像tags et alpine
没有太大的区别,而且它们对于一个容器镜Il s'agit d'une taille de 200 Mo. slim
镜像的软件占用相对于alpine
来说还是相当高的(slim
97 pouces VS alpine
16 pouces ),因此,漏洞数量对于alipne
来说也更高(slime
56个 VS slpine
2个)。slim
镜像tags和alpine
没有太大的区别,而且它们对于一个容器镜像来说平均大概是200MB。当然,slim
镜像的软件占用相对于alpine
来说还是相当高的(slim
97个 VS alpine
16个),因此,漏洞数量对于alipne
来说也更高(slime
56个 VS slpine
2个)。
漏洞是一个重要的问题,并且一直是很多文章的中心——关于你为什么应该减少容器镜像的大小。
忽略node
和node:bullseye
这种由于较大的软件占用而跟着增加安全漏洞的镜像,我们可以更关注稍微小一点的镜像类型。在slim
、alpine
、distroless
之间对比,高危和关键安全漏洞的绝对数量并不高,范围在0到4之间,这是一个可控的风险,并不会影响到你的应用程序。
最理想的Node.js Docker镜像应该是一个基于现代Debian OS的操作系统的精简版本,它有一个稳定且活跃的Node.js长期支持版本。
归根结底就是选择node:lts-bullseye-slim
Node.js镜像tag。我赞成使用确定性图像标记,因此我要做的细微更改是使用实际的底层版本号,而不是lts
别名。
最理想的Node.js Docker镜像tag是**node:16.17.0-bullseye-slim**
。
如果你在一个成熟的开发团队工作,该团队可以支持自定义基础镜像,那么我的第二个最佳建议是选择谷歌的distroless
镜像tag,因为它保持了glibc
安全关于你为什么应该减少容器镜像的大小。忽略node
et node:bullseye code>型。在<code>slim
、alpine
、sans distribution
,并不会影响到你的应用程序。
node:lts-bullseye-slim
Node.js.改是使用实际的底层版本号,而不是lts
别名。🎜🎜🎜最理想的Node.js Docker tag是🎜**node:16.17.0-bullseye-slim**
🎜。🎜🎜🎜如果你在一个成熟的开发团队工作,该团队可以支持自定义基础镜像,那么我的第二个最佳建议是选择Il s'agit d'une balise distroless
, et d'une balise glibc code>Node.js多node相关知识,请访问:🎜nodejs 教程🎜!🎜
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!