Die Auswahl einesNodeDocker-Image mag wie eine kleine Sache erscheinen, aber die Größe und potenziellen Schwachstellen des Images können erhebliche Auswirkungen auf Ihren CI/CD-Prozess und Ihre Sicherheit haben. Wie wählen wir also das beste Node.js Docker-Image aus?
Wenn wirFROM node:latest
oder einfachFROM node
verwenden, können die potenziellen Risiken leicht ignoriert werden. Wenn Sie das allgemeine Sicherheitsrisiko nicht kennen und es nicht in den CI/CD-Prozess einbeziehen, wird es das Risiko zweifellos verschärfen. [Empfohlene verwandte Tutorials: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
nodejs-Video-TutorialDas Folgende 1. Das Beispiel ist sehr typisch. Sie können die Konfiguration dieser Node.js-Dockerdatei aus vielen Tutorials oder Blogbeiträgen sehen.Es gibt jedoch große Probleme mit der Konfiguration dieser Docker-Datei, und es wird dringend davon abgeraten, sie auf diese Weise zu verwenden:
Anmerkung des Übersetzers: Wenn Sie die Analyse überspringen und direkt zu gehen müssen Zum Fazit scrollen Sie bitte direkt zum Ende des Artikels.FROM node:bullseye复制代码Nach dem Login kopierenNach dem Login kopieren
distroless
-Projekts erstellte Node.js-Anwendung oder ein Image namensscratch
, das vom offiziellen Docker-Team bereitgestellt wird. Welches dieser Node.js-Docker-Images ist für Sie am besten geeignet? Lassen Sie uns sie einzeln analysieren, um mehr über ihre Vorteile und potenziellen Risiken zu erfahren. Anmerkung des Autors: In diesem Artikel werde ich das Node.js-Image der Version 18.2.0 vergleichen, die etwa im Juni 2022 veröffentlicht wird.
amd64
undarm64x8
(neue Version von Apples M1). Die häufigstennode
-Images in Debian-Distributionen, wie z. B.bullseye
oderbuster
, basieren auf, die von einem anderen Team verwaltet werden >Buildpack -deps
.node
-Image erstellen?
FROM node:bullseye-slim
docker build --no-cache -f Dockerfile1 -t dockerfile1
verwenden, um das Image zu erstellen, wird Folgendes angezeigt:
node
ein Alias vonnode:last
und seine Version zeigt auf18.2.0
docker scan dockerfile1
verwenden, um einenSynk-powered
-Container auszuführen, und wir erhalten die folgenden Ergebnisse:
curl/libcurl4
,git/git-man
,imagemagick/imagemagick-6-common
>.Pufferüberläufe
,use-after-free-Fehler
,out-of-bounds schreiben
usw.DNS Rebinding
,HTTP Request Smuggling
,Configuration Hijacking
Anmerkung des Übersetzers:
你真的需要在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之间的比较:
node:lts-bullseye-slim
lts
distroless
glibc code>对官方Node.js运行时版本的兼容性.这个工作流会需要一些维护,所以我只是建议而已. 更多node相关知识,请访问: nodejs 教程 !
Das obige ist der detaillierte Inhalt vonLassen Sie uns darüber sprechen, wie Sie das beste Node.js-Docker-Image auswählen.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!