최고의 Node.js Docker 이미지를 선택하는 방법에 대해 이야기해 볼까요?

青灯夜游
풀어 주다: 2022-12-13 20:00:09
앞으로
2347명이 탐색했습니다.

NodeDocker 이미지를 선택하는 것은 작은 일처럼 보일 수 있지만 이미지의 크기와 잠재적인 취약점은 CI/CD 프로세스와 보안에 상당한 영향을 미칠 수 있습니다. 그렇다면 최고의 Node.js Docker 이미지를 어떻게 선택합니까?

최고의 Node.js Docker 이미지를 선택하는 방법에 대해 이야기해 볼까요?

FROM node:latest또는 단지FROM node를 사용하면 잠재적인 위험을 무시하기 쉽습니다. 전반적인 보안 위험을 모르고 이를 CI/CD 프로세스에 도입하면 의심할 여지없이 위험이 악화됩니다. [추천 관련 튜토리얼: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 Docker镜像

当你构建一个Node.js镜像的时候,实际上有很多选择。其中就包括了Node.js核心团队维护的官方Docker镜像,以及从特定的基础镜像中选择的特殊Node.js镜像版本。还可以选择其他的,比如谷歌在distroless项目上构建的Node.js应用程序,或者是Docker官方团队提供的一个名为scratch的镜像。

在这些Node.js的Docker镜像中,哪一个是最适合你的呢?

让我们一个一个的去分析,了解更多他们的好处和潜在风险。

作者注:在这篇文章中,我将会比较18.2.0这个版本的Node.js镜像,他的发布时间是2022年6月左右。

默认的Node.js镜像

我们先从维护的node镜像开始。它是由进行正式地维护的,包含了一些基础的镜像tag。这些tag对应到不同的底层发行版(Debian、Ubuntu、Alpine)以及不同版本的Node.js运行时本身。还有针对不同CPU架构的特定版本tag,例如amd64arm64x8(新版苹果的M1)。

Debian发行版中最常见的node镜像,例如bullseyebuster,他们都是基于由另一个团队维护的buildpack-deps的。
当你基于这个默认的node镜像构建Node.js Docker镜像时会发生什么?

FROM node
로그인 후 복사

使用docker build --no-cache -f Dockerfile1 -t dockerfile1构建镜像时,就会出现下面这些:

  • 我们没有指定Node.js运行时版本,所以nodenode:last的一个别名,他的版本指向的是18.2.0
  • 这个Node.js Docker镜像大小是952MB

这个最新的Node.js镜像的依赖和安全漏洞足迹是什么呢?我们可以用docker scan dockerfile1来运行一个Synk-powered容器,就会得到下面的结果:

  • 共有409个依赖项 - 这些是使用操作系统包管理器检测到的开源库,比如curl/libcurl4git/git-manimagemagick/imagemagick-6-common
  • 共有289个安全问题在这些依赖中被发现,例如,Buffer Overflowsuse-after-free errorsout-of-bounds write等。
  • Node.js 18.2.0运行时版本容易出现7个安全问题。例如,DNS RebindingHTTP Request SmugglingConfiguration Hijackingnodejs 비디오 튜토리얼
  • , 프로그래밍 교육
]

다음 이 예제는 매우 일반적입니다. 많은 튜토리얼이나 블로그 게시물에서 이 Node.js Dockerfile의 구성을 볼 수 있습니다.그러나 이 Dockerfile의 구성에는 큰 문제가 있으므로 이 방법으로 사용하는 것은 적극 권장되지 않습니다:

FROM node:bullseye复制代码
로그인 후 복사
로그인 후 복사
번역가의 메모: 분석을 건너뛰고 바로 다음으로 이동해야 하는 경우: 결론을 내리려면 기사 끝 부분까지 직접 스크롤하십시오.

선택할 수 있는 Node.js Docker 이미지

Node.js 이미지를 빌드할 때 실제로 선택할 수 있는 옵션이 많습니다. 여기에는 Node.js 핵심 팀에서 관리하는 공식 Docker 이미지뿐만 아니라 특정 기본 이미지에서 선택된 특수 Node.js 이미지 버전도 포함됩니다.distroless프로젝트에서 Google이 구축한 Node.js 애플리케이션이나 공식 Docker 팀에서 제공하는scratch라는 이미지 등 다른 것을 선택할 수도 있습니다. 이 Node.js Docker 이미지 중에서 귀하에게 가장 적합한 이미지는 무엇입니까? 하나씩 분석하여 이점과 잠재적 위험에 대해 자세히 알아보세요. 작성자 노트: 이번 글에서는 2022년 6월쯤 출시될 Node.js 18.2.0 버전의 이미지를 비교해보겠습니다.

기본 Node.js 이미지

유지관리 노드 이미지부터 시작해 보겠습니다. 에서 공식적으로 관리하며 몇 가지 기본 이미지 태그를 포함합니다. 이러한 태그는 다양한 기본 배포판(Debian, Ubuntu, Alpine) 및 Node.js 런타임 자체의 다양한 버전에 해당합니다.amd64arm64x8(Apple M1의 새 버전)과 같은 다양한 CPU 아키텍처에 대한 특정 버전 태그도 있습니다.bullseye또는buster와 같은 Debian 배포판에서 가장 일반적인노드이미지는 다른 팀 >buildpack에서 관리하는를 기반으로 합니다. -뎁스.
이 기본노드이미지를 기반으로 Node.js Docker 이미지를 빌드하면 어떻게 되나요?
FROM node:bullseye-slim
로그인 후 복사
로그인 후 복사
docker build --no-cache -f Dockerfile1 -t dockerfile1을 사용하여 이미지를 빌드하면 다음이 나타납니다.
  • Node.js를 지정하지 않았습니다. 런타임 버전이므로nodenode:last의 별칭이고 해당 버전은18.2.0
  • 이 Node.js를 가리킵니다. Docker 이미지 크기는 952MB입니다이 최신 Node.js 이미지의 종속성과 보안 취약점 발자국은 무엇입니까?docker scan dockerfile1을 사용하여동기화 기반컨테이너를 실행할 수 있으며 다음과 같은 결과를 얻을 수 있습니다.
    • 총 409개의 종속성이 있습니다.curl/libcurl4,git/git-man,imagemagick/imagemagick-6-common과 같이 운영 체제의 패키지 관리자가 감지한 오픈 소스 라이브러리를 사용합니다.>.
    • 이러한 종속성에서버퍼 오버플로,use-after-free 오류,범위 초과 등 총 289개의 보안 문제가 발견되었습니다. 쓰기등.
    • Node.js 18.2.0 런타임 버전에는 7가지 보안 문제가 발생하기 쉽습니다. 예를 들어DNS 리바인딩,HTTP 요청 스머글링,구성 하이재킹번역자 메모:
      • Buffer Overflows - 缓冲区溢出
      • Use After Free - 一种内存破坏漏洞,通常存在于浏览器中
      • out-of-bounds write - 越界写入
      • DNS Rebinding - DNS重绑定攻击
      • HTTP Request Smugglin - HTTP请求夹带攻击技术
      • Configuration Hijacking - 配置劫持

      你真的需要在Node.js镜像中给你的应用提供wgetgitcurl吗?在Node.js Docker镜像中,有成百上千个依赖和工具,而这些依赖又对应着成百上千个漏洞。Node.js运行时的特性对应着7个不同的安全漏洞,给潜在攻击留下了很大的空间。总的来说,情况并不是很乐观。

      Node.js Docker Hub选项node:buster vs node:bullseye

      如果你在Node.js Docker Hub仓库上浏览可用tags,你将会发现有两个Node.js镜像tags -node:busternode: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的结果进行比较,将会得到完全相同的大小、依赖数量和发现的漏洞。原因是nodenode:latestnode:bullseye全部指向了同一个正在构建的Node.js镜像tag。

      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
      로그인 후 복사
      로그인 후 복사
      • 镜像的大小已经急剧下降,从接近1GB的容器镜像降到246MB的镜像大小
      • 扫描他的内容也显示了整体软件足迹的大幅下降,只有97个依赖项和56个漏洞。

      就容器镜像大小和安全状况而言,node:bullseye-slim已经是一个比较好的起点了。

      一个LTS的Node.js Docker镜像

      到目前为止,我们的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:alpine对于Node.js镜像来说是一个更好的选择吗?

      Node.js Docker团队维护了一个node:alpine镜像tag以及他的变体,以便将Alpine Linux发行版的特定版本与Node.js运行时的特定版本进行匹配。

      Alpine Linux项目经常因为其非常小的镜像体积而被引用,小体积意味着更新的软件占用空间和更少的漏洞,确实十分不错。
      下面的命令会让Dockerfile去生成一个node环境,这个将会增加未压缩的镜像体积:

      FROM node:alpine
      로그인 후 복사

      这个将会产生一个178MB大小的docker镜像,和slimNode.js镜像大小差不多,但是在alpine镜像tag中,只检测到了16个系统依赖漏洞和2个安全安全漏洞。这就意味着alpine镜像tag对于小体积和漏洞数量来说是一个比较好的选择。

      alpine对Node.js镜像可能提供了一个较小的镜像体积和更少的漏洞数量。但是,我们必须意识到Alpine项目使用musl作为C标准库的实现。而Debian的Node.js镜像tag依赖于glibc实现,比如bullseyeslim。这些差异可以解释性能问题、功能性的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基础镜像有关,但是也应该考虑到这一点。

      Node.js的distroless(无损)Docker镜像

      我们的基准测试的最后一个比较项目是谷歌的Distroless容器镜像。

      什么是distroless容器镜像?

      这种镜像甚至比slim的Node.js镜像更加小,因为distroless镜像只针对这个应用和应用运行时的依赖性而已。因此,一个distroless的docker镜像没有容器包管理器、shell、或者其他通用工具的依赖性,这使得它们的体积更小,漏洞也更少。

      幸运的是,Distroless项目为Node.js维护了一个特殊运行时的distrolessdocker镜像,通过其完整的命名空间识别为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"]
      로그인 후 복사

      构建这个distrolessdocker镜像将产生112MB的文件,而在slimalpine镜像tag来说,这已经减小了很多文件的体积了。
      如果你正在考虑使用distrolessdocker镜像,有一些重要的事项需要注意:

      • 好的一点是,它们是基于当前稳定的Debian发行版本,这意味着它们是最新的,很久才会到EOL的日期。
      • 因为它们是基于Debian的,所以它们依赖glibc实现,并且不太可能在生产环境出现一些奇怪的问题。
      • 你很快就会发现Distroless团队没有维护细粒度的Node.js运行时版本。这意味着你需要依赖于通用的nodejs:16的标记(该标记经常更新),或者在一个特定时间点根据镜像的SHA256哈希值进行安装。

      Node.js Docker镜像tags的比较

      我们可以参考下面的表格来总结不同Node.js Docker镜像tags之间的比较:

      이미지 태그 Node.js 런타임 버전 OS 종속성 OS 보안 취약점 높고 심각한 취약점 중간 취약점 낮은 취약점 Node.js 런타임 취약점 이미지 크기 실 사용 가능
      node 18.2.0 409 289 54 18 217 7 952MB
      node:bullseye 18.2.0 409 289 54 18 217 7 952MB
      node:bullseye-slim 18.2.0 97 56 4 8 44 7 246MB
      node:lts-bullseye-slim 16.15.0 97 55 4 7 44 6 188MB
      노드:alpine 18.2.0 16 2 2 0 0 0 178MB
      gcr.io/distroless/nodejs:16 16.17.0 9 11 0 0 11 0 112MB 아니요

      我们来통 Node.js의 이미지 태그的数据发环境平价)

      如果你选择使 이용 적. Node.js의 이미지 태그取决于开发的一致性为开发和生产完全源了境进行优化), 那么这可能已经是一场失败的battle了.大多数情况下, 所有3个主要操作系统都使用不同的C库实现。Linux依赖glibc,Alpine依赖musl, 而macOS는 자체 BSD libc实现。

      DOCKER镜image大小

      有时候,镜image大小也很要。更准确地说,我们的目标不是拥有最작은 체형, 而是拥有最작은 것整体软件種整体软件種没有太大的区别,而且它们对于一个容器镜image来说平均大概是200MB。当然,slim镜image적软件·용상对于alpine来说还是相当高的(slim97만 VSalpine16만) ),因此,漏洞数weight对于alipne来说也更高(slime56个 VSslpine2个)。

      안전漏洞

      slim镜像tags和alpine没有太大的区别,而且它们对于一个容器镜像来说平均大概是200MB。当然,slim镜像的软件占用相对于alpine来说还是相当高的(slim97个 VSalpine16个),因此,漏洞数量对于alipne来说也更高(slime56个 VSslpine2个)。

      安全漏洞

      漏洞是一个重要的问题,并且一直是很多文章的中心——关于你为什么应该减少容器镜像的大小。

      忽略nodenode:bullseye这种由于较大的软件占用而跟着增加安全漏洞的镜像,我们可以更关注稍微小一点的镜像类型。在slimalpinedistroless之间对比,高危和关键安全漏洞的绝对数量并不高,范围在0到4之间,这是一个可控的风险,并不会影响到你的应用程序。

      本质内容?

      最理想的Node.js Docker镜像应该是一个基于现代Debian OS的操作系统的精简版本,它有一个稳定且活跃的Node.js长期支持版本。

      归根结底就是选择node:lts-bullseye-slimNode.js镜像tag。我赞成使用确定性图像标记,因此我要做的细微更改是使用实际的底层版本号,而不是lts别名。

      最理想的Node.js Docker镜像tag是**node:16.17.0-bullseye-slim**

      如果你在一个成熟的开发团队工作,该团队可以支持自定义基础镜像,那么我的第二个最佳建议是选择谷歌的distroless镜像tag,因为它保持了glibc漏洞是一个重要的问题,并且一直是很多文章的中心——关于你为什么应该减少容器镜应该减少容器镜의 상상의대소。忽略노드노드:과녁code>这种由于较大的软件而跟着增加漏洞的镜型,我们可以更关注稍微小一点的镜image类型。여기슬림alpinedistroless间对比, 高危 and 关键security 漏洞的绝对数weight并不高,范围在0到4之间, 这是一个可控的风险, 并不会影响到你的应用程序。

      本质内容?

      最理想的Node.js Docker镜应该是一个基于现代Debian OS의 운영 체제에 맞는 精简版本, 它有一个稳定且活跃的Node.js长期支持版本。归根结底就是选择node:lts-bullseye-slimNode.js镜imagetag层版本号,而不是lts别name。最理想的Node.js Docker镜imagetag是**node:16.17.0-bullseye-slim**。如果你재一个成熟的开发团队工작품, 该团队可以支持自己义基础镜 Image, 那么我的第二个最佳建议是选择谷歌的distroless镜imagetag,因为它保持了glibc code>对官方Node.js运行时版本的兼容性. nodejs 教程!

      위 내용은 최고의 Node.js Docker 이미지를 선택하는 방법에 대해 이야기해 볼까요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:juejin.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!