將 Node.js 應(yīng)用程序容器化的七種方法
在過去的五年里,Node.js 一直是嚴(yán)肅程序員的最愛。最大吞吐量的 JavaScript 運(yùn)行時(shí)環(huán)境是一個(gè)免費(fèi)的開源程序,旨在提高JavaScript在多個(gè)平臺(tái)上的性能。
由于其事件驅(qū)動(dòng)、非阻塞 I/O 方法,Node.js 體積小且處理請(qǐng)求速度快,使其成為數(shù)據(jù)密集型、實(shí)時(shí)和分布式應(yīng)用程序的絕佳選擇。
開發(fā)人員越來越多地轉(zhuǎn)向 node.js 應(yīng)用程序優(yōu)化服務(wù);因此,簡化跨平臺(tái)應(yīng)用程序的設(shè)計(jì)和發(fā)布過程非常重要。那么,讓我們進(jìn)入文章的上下文。
Node App 容器化和優(yōu)化建議
這里列出了七種容器化 node.js 應(yīng)用程序的方法,所以讓我們簡要地看一下它們。
1.使用特定的基本圖像標(biāo)簽而不是“版本:最新”
創(chuàng)建Docker映像時(shí),應(yīng)始終包含用于定義版本信息、預(yù)期目標(biāo)(例如生產(chǎn)或測試)、穩(wěn)定性或其他用于跨環(huán)境分發(fā)應(yīng)用程序的相關(guān)信息的有用標(biāo)簽。
在開發(fā)環(huán)境之外,您不應(yīng)依賴 Docker 自動(dòng)下載的最新標(biāo)簽。使用最新版本的程序可能會(huì)導(dǎo)致奇怪甚至有害的影響。
假設(shè)您不斷更新到最新版本的圖像。在這種情況下,最終,其中一個(gè)更新肯定會(huì)包含一個(gè)全新的構(gòu)建或未經(jīng)測試的代碼,這將導(dǎo)致您的應(yīng)用程序停止按預(yù)期運(yùn)行。
以針對(duì)該節(jié)點(diǎn)的這個(gè)示例 Dockerfile 為例?:
您不應(yīng)使用 node:latest,而應(yīng)使用 lts-buster Docker 映像??紤]到 lts-buster 是靜態(tài)圖片,這種方法可能更可取。
2.使用多階段構(gòu)建
一個(gè)單一的 Docker 基礎(chǔ)鏡像可以在構(gòu)建的多個(gè)階段使用,包括編譯、打包和 單元測試。但是,執(zhí)行程序的實(shí)際代碼存儲(chǔ)在不同的映像中。
由于完成的圖像沒有任何開發(fā)或調(diào)試工具,因此它會(huì)更安全并且占用更少的空間。此外,如果您使用 Docker 的多階段構(gòu)建過程,您可以確定您的構(gòu)建將既高效又可重復(fù)。
您可以在 Dockerfile 中創(chuàng)建多個(gè)階段來控制構(gòu)建該映像的方式。您可以使用多層方法容器化您的 Node 應(yīng)用程序。
應(yīng)用程序的不同部分,如代碼、資產(chǎn),甚至快照依賴項(xiàng),可能位于構(gòu)成程序的許多層的每一層中。如果我們希望為我們的應(yīng)用程序創(chuàng)建一個(gè)獨(dú)立的圖像怎么辦?
要查看此操作的示例 Dockerfile,?請(qǐng)檢查以下內(nèi)容:
我們首先在 node:lts-buster-slim 語句中添加一個(gè) AS 開發(fā)標(biāo)簽。這使我們可以在其他構(gòu)建階段中引用此構(gòu)建階段。接下來,我們添加一個(gè)標(biāo)記為 dev-envs 的新開發(fā)階段。我們將使用這個(gè)階段來運(yùn)行我們的開發(fā)。
現(xiàn)在,讓我們重建我們的形象并運(yùn)行我們的開發(fā)。為了僅執(zhí)行開發(fā)構(gòu)建階段,我們將使用與之前相同的 docker build 命令,但這次我們將使用 —target 開發(fā)參數(shù)。
3.修復(fù)節(jié)點(diǎn)鏡像中的安全漏洞
為了創(chuàng)建現(xiàn)代服務(wù),程序員經(jīng)常使用已有的第三方軟件。但是,在將第三方軟件集成到您的項(xiàng)目中時(shí)一定要謹(jǐn)慎,因?yàn)樗赡艽嬖诎踩┒础?/p>
使用經(jīng)過驗(yàn)證的圖像源和保持警惕的容器監(jiān)控都是有用的安全措施。Docker Desktop 會(huì)通知您對(duì)新創(chuàng)建的 node:lts-buster-slim Docker 鏡像進(jìn)行安全檢查。
讓我們借助 Docker Desktop 的 Snyk 插件看看我們的 Node.js 應(yīng)用程序。首先在您的 Mac、Windows 或 Linux PC 上設(shè)置 Docker Desktop 4.8.0+。接下來,選擇設(shè)置 > 擴(kuò)展下的允許 Docker 擴(kuò)展復(fù)選框。
之后,您可以通過選擇左側(cè)欄中的“添加擴(kuò)展”選項(xiàng)在擴(kuò)展市場中搜索 Snyk。
放入 Snyk 并登錄網(wǎng)絡(luò):
lts-buster-slim 在“選擇圖像名稱”框中鍵入“Node Docker 官方圖像”。為了開始掃描,您需要登錄到 Docker Hub。如果您沒有帳戶,請(qǐng)不要擔(dān)心;制作一個(gè)簡單、快速且完全免費(fèi)。
使用 Docker Desktop,掃描結(jié)果如下所示:
在此掃描期間,Snyk 發(fā)現(xiàn)了 70 個(gè)不同嚴(yán)重程度的漏洞。確定它們后,您可以開始修復(fù)它們以提高您的聲譽(yù)。
不僅如此。在 Dockerfile 上使用 docker scan 命令將執(zhí)行漏洞掃描:
4. 利用健康檢查
HEALTHCHECK 指令指示 Docker 如何檢查容器的健康狀況。例如,這可用于確定 Web 服務(wù)器是否處于無限循環(huán)中并且無法接受新連接,即使服務(wù)器進(jìn)程仍處于活動(dòng)狀態(tài)。
在生產(chǎn)階段,應(yīng)用程序通常由 Kubernetes 或服務(wù)結(jié)構(gòu)等編排器管理。HEALTHCHECK 允許您通知編排器有關(guān)容器的健康狀況,這可能用于基于配置的管理。
這是一個(gè)很好的例子:?
5.使用.dockerignore
我們建議在與 Dockerfile 相同的文件夾中創(chuàng)建一個(gè) .dockerignore 文件以縮短構(gòu)建時(shí)間。本指南需要您的 .dockerignore 文件中的一行:
由于這一行,包含 Maven 輸出的節(jié)點(diǎn)模塊目錄未包含在 Docker 構(gòu)建上下文中。擁有一個(gè)組織良好的 .dockerignore 文件有很多好處,但目前,這個(gè)簡單的文件就足夠了。
接下來,我將描述構(gòu)建環(huán)境及其如此重要的原因。可以使用 Docker build 命令通過組合 Dockerfile 和“上下文”來創(chuàng)建 Docker 映像。在此設(shè)置中,您所做的一切都適用于您剛才給我的目錄結(jié)構(gòu)或 URL。這些文件中的任何一個(gè)都可以在構(gòu)建過程中使用。
同時(shí),開發(fā)人員在編譯上下文中進(jìn)行操作。Mac、Windows 或 Linux 上的目錄。運(yùn)行該程序所需的一切都可以在此文件夾中找到,包括源代碼、設(shè)置、庫和插件。
如果您提供 .dockerignore 文件,我們可能會(huì)在創(chuàng)建新圖像時(shí)使用它來跳過項(xiàng)目的某些部分:代碼、配置文件、庫、插件等。例如,如果您想將節(jié)點(diǎn)模塊目錄保留在外面在您的構(gòu)建中,您可以通過將以下內(nèi)容添加到您的 .dockerignore 文件來實(shí)現(xiàn)。
后端
前端
6.出于安全目的以非根用戶身份運(yùn)行
在用戶許可的情況下運(yùn)行應(yīng)用程序更安全,因?yàn)檫@有助于減少漏洞。即使使用 Docker 容器。Docker 容器及其內(nèi)容會(huì)自動(dòng)獲得對(duì)主機(jī)系統(tǒng)的根訪問權(quán)限。這就是為什么建議永遠(yuǎn)不要以 root 用戶身份運(yùn)行 Docker 容器。
這可以通過在 Dockerfile 中包含某些 USER 指令來實(shí)現(xiàn)。在執(zhí)行映像以及任何未來的 RUN、CMD 或 ENTRYPOINT 指令時(shí),USER 命令指定所需的用戶名(或 UID)以及可選的用戶組(或 GID):
7. 探索 Node 的優(yōu)雅關(guān)閉選項(xiàng)
在 Docker 中為 Node.js 創(chuàng)建的臨時(shí)存儲(chǔ)空間。它們很容易預(yù)防、銷毀,然后更換或重新利用??梢酝ㄟ^向進(jìn)程提供 SIGTERM 信號(hào)來終止容器。
為了充分利用這個(gè)短暫的機(jī)會(huì)窗口,您的應(yīng)用程序必須能夠立即處理傳入的請(qǐng)求并釋放任何相關(guān)資源。
另一方面,Node.js 對(duì)于成功關(guān)閉應(yīng)用程序至關(guān)重要,因?yàn)樗鼜牟僮飨到y(tǒng)接收并傳遞 SIGINT 和 SIGTERM 等信號(hào)。由于 Node.js,您的應(yīng)用程序可以選擇如何響應(yīng)它接收到的信號(hào)。
如果你不為他們編程或使用一個(gè)模塊,你的應(yīng)用程序?qū)o法正常終止。但是,它將繼續(xù)正常運(yùn)行,直到 Docker 或Kubernetes由于超時(shí)而終止它。
如果您無法修改應(yīng)用程序的代碼,您仍然可以在 Dockerfile 中使用 docker run —init 或 tini init 選項(xiàng)。但是,建議您提供代碼來管理適當(dāng)?shù)男盘?hào)處理以實(shí)現(xiàn)正常關(guān)閉。
結(jié)論
在本教程中,我們涵蓋了與 Docker 鏡像優(yōu)化相關(guān)的廣泛主題,從構(gòu)建可靠的 Dockerfile 到使用 Snyk 檢查漏洞。制作更好的 Node.js 應(yīng)用程序并不難。如果你掌握了一些基本技能,你的狀態(tài)就會(huì)很好。