
一个高效、合理的部署方案不仅支持快速升级、滚动更新、负载均衡和应用隔离,还配套了一套成熟稳定的监控体系。
Kubernetes 将 Node 应用视为一个可独立运行的服务单元,逐渐成为团队的主流选择。
在此之前,我们需要先把 Node 应用跑在一个 Docker 容器中,这也是本章的核心主题。
1. 一个简单的 Node 应用
聚沙成塔,积小成大。以一个 hello world 版本的 Node Server 为起点。
在生产环境启动 Node Server 时,单纯执行 node index.js 往往无法满足诸多先决条件。
因此,在 package.json 中引入一层封装,通过 npm start 启动服务,方便在 Docker 镜像中如此配置启动命令。
2. NODE_ENV=Production
在生产环境下若无构建步骤,则无需安装 devDependencies。将 NODE_ENV 设置为 Production 时可跳过 devDependencies 的安装。
另一方面,部分第三方库会根据 NODE_ENV 做出不同的行为,因此生产环境需要正确配置该环境变量。
3. 一个 Node 服务的镜像
一个典型的面向服务端的 Node 服务启动流程大致如下:
- NPM install
- NPM Run config,从配置服务(Consul/Vault)拉取配置信息,例如数据库和缓存的账号密码;此时镜像需要具备相应的服务权限
- NPM Run Migration,执行数据库迁移脚本,更新表结构;镜像需要数据库访问权限
- NPM Start,启动 Node 服务
把运行步骤翻译为 Dockerfile 的多阶段构建,这对于大多数 Node 应用已经足够,后续可以在此基础上进一步优化。
4. node-gyp 与原生 Addon
某些 Node 依赖包含原生插件(Native Addon),它们通过 node-gyp 编译,需要 Python、Make 和 g++。
在带有编译过程的镜像构建中,源代码和构建工具会增加镜像体积。通过多阶段构建,可以在不影响最终镜像的情况下完成编译,显著减少体积。
类似的做法也适用于 Go 语言及前端相关的构建流程。
