首页 / 文章

为 Node.js 工作负载选择 EC2、ECS 还是 EKS

对比了EC2、带Fargate的ECS以及EKS在运行Node.js应用方面的差异,帮助您根据团队的规模和技能水平选择合适的AWS计算服务。

发布者:REACTAPP.TOP阅读约 9 分钟2009 词

来源: EC2 vs ECS vs EKS for Node.js: Which AWS Service Should You Actually Choose?

当需要将 Node.js 后端迁移到 Amazon Web Services 时,几乎必须立即做出选择。AWS 控制台提供了至少三种不同的计算产品:Amazon EC2、Amazon ECS 和 Amazon EKS。

如果你向他人咨询,会得到相互矛盾的建议。有些开发人员认为在 EC2 上使用普通虚拟机是最简单且最佳的选择;另一些人则坚持认为,如果想要真正现代化的架构,没有什么能比通过 EKS 运行 Kubernetes 更好。与此同时,许多生产平台团队已悄悄将其所有微服务统一采用 ECS 作为标准方案。

选择错误的工具往往会导致两种令人沮丧的结果:要么不得不手动修补操作系统并管理服务器,要么为了维持一个简单的 Express API 运行而深陷于 Kubernetes 配置文件之中——这样的 API 每秒可能只能处理几十次请求。

此对比摒弃了各种宣传噱头,直接探讨 EC2、ECS 和 EKS 在 Node.js 应用方面的表现:它们各自对团队运营有哪些要求,以及如何根据自身情况选出最合适的选项。

三种服务的简要说明

在比较各种优缺点之前,先明确每种服务的具体内容会更有帮助。

+-------------------------------------------------------------------------+
|                               Amazon EKS                                |
|   Fully managed Kubernetes. High control, high complexity, multi-cloud. |
+-------------------------------------------------------------------------+
                                    ▲
                                    │ Built for complex orchestration
+-------------------------------------------------------------------------+
|                               Amazon ECS                                |
|   AWS-native container orchestration. Fast, simple, deeply integrated.  |
+-------------------------------------------------------------------------+
                                    ▲
                                    │ Built for containers
+-------------------------------------------------------------------------+
|                               Amazon EC2                                |
|   Raw virtual machines in the cloud. Full OS access, manual maintenance.|
+-------------------------------------------------------------------------+

1. Amazon EC2(弹性计算云)

EC2会为你提供一台虚拟机,称为“实例”。你可以选择操作系统——Ubuntu和Amazon Linux是常见的选择——通过SSH登录,安装Node.js以及PM2这样的进程管理器,然后自行启动应用程序。

从内核到上层的一切都在你的直接控制之下。

2. Amazon ECS(弹性容器服务)

ECS是AWS用于管理Docker容器的系统。你无需直接管理操作系统,只需将Node.js应用程序打包成Docker镜像,然后指示ECS保持一定数量的该容器运行且状态良好——比如四个副本。

如果将 ECS 与它的无服务器计算层 AWS Fargate 结合使用,就完全无需管理容器底层的服务器了。AWS 会根据需求自动为每个容器分配 CPU 和内存。

3. Amazon EKS(弹性 Kubernetes 服务)

EKS 在 AWS 基础设施之上提供托管式的 Kubernetes 集群。Kubernetes 本身是由谷歌发起的开源容器编排标准。

使用 EKS 时,AWS 负责 Kubernetes 的控制平面——即主节点,而你仍需负责定义容器组、部署、服务、入口规则以及网络策略。

为何 Node.js 的特性在此处很重要

在选定某项服务之前,值得回顾一下 Node.js 的实际运行机制:

  • JavaScript 执行为单线程模式:Node.js 进程仅使用一个 CPU 核心来运行 JavaScript 代码。在拥有 8 核心的 EC2 实例上运行一个进程时,除非明确启动多个进程集群或将任务分配到多个实例上,否则其余 7 个核心将处于闲置状态。
  • 启动速度快且占用资源少:容器化的 Node.js 应用通常可在两秒内启动运行,这使其非常适合基于容器和自动扩缩容架构构建的环境。
  • 工作负载多为 I/O 密集型:大多数 Node.js 服务的大部分时间都用于等待数据库响应、外部 API 调用或磁盘操作,而非执行高强度的 CPU 计算。

这些特性直接影响着在这三项服务中扩展的难易程度。

1. Amazon EC2:最大程度的控制,繁重的维护工作

使用EC2的感觉很像在自己的Linux机器上开发,因为它本质上就是一台Linux机器。

Bash

# Typical manual setup on an EC2 instance:
sudo apt update && sudo apt install -y nodejs npm
git clone https://github.com/your-org/api.git
cd api && npm ci --omit=dev
npm install -g pm2
pm2 start app.js -i max
Traffic ──> Application Load Balancer (ALB)
                 │
        ┌────────┴────────┐
        ▼                 ▼
   [EC2 Instance]    [EC2 Instance]
   ├─ Node Process   ├─ Node Process
   ├─ Node Process   ├─ Node Process
   └─ PM2 Manager    └─ PM2 Manager

优点:

  • 价格可预测:您只需按照所选择的实例规格支付固定的每小时费用。
  • 完全的系统访问权限:您可以查看系统日志,通过sysctl调整内核参数,或安装应用程序所需的任何本地库。

缺点:

在EC2上运行生产级工作负载需要大量的手动维护工作。您需要负责:

  • 应用操作系统安全补丁。
  • 在所有实例上逐步部署 Node.js 运行时升级。
  • 维护自动扩展组并构建机器镜像(AMIs)。
  • 重启崩溃的进程,并排查长时间运行的服务中的内存泄漏问题。
  • 实际开发者见解: 对于几乎不会发生变化的单一单体应用,EC2 效果不错。但一旦需要运行三到四个微服务,将它们分散在不同的 EC2 实例上要么会浪费资源,要么会导致服务器配置变得混乱。

    2. Amazon ECS:大多数团队的理想选择

    如果你的 Node.js 应用已经位于 Docker 容器中,那么在 AWS 上 ECS 通常是最高效的解决方案。

    编写可用于生产环境的 Node.js Dockerfile 并不复杂:

    # Multi-stage Dockerfile for Node.js
    FROM node:20-alpine AS builder
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci
    
    FROM node:20-alpine
    WORKDIR /app
    ENV NODE_ENV=production
    COPY package*.json ./
    RUN npm ci --omit=dev
    COPY . .
    USER node
    EXPOSE 3000
    CMD ["node", "server.js"]
    

    将图像推送到 Amazon ECR(弹性容器注册表)后,你需要创建一个 ECS 任务定义,其中需指定:

    • 容器的 CPU 配置(例如 0.5 vCPU)和内存配置(例如 1 GB)。
    • 从 AWS Secrets Manager 或 Parameter Store 中获取的环境变量。
    • 健康检查端点。
    Traffic ──> ALB
                 │
                 ├── Path /api/users ──> [ECS Task: Users] (0.5 vCPU)
                 └── Path /api/orders ─> [ECS Task: Orders] (0.5 vCPU)
                                         [ECS Task: Orders] (0.5 vCPU)
    

    为何 ECS 与 Fargate 非常适合 Node.js:

    ECS 与 Fargate的结合完全省去了服务器层——无需管理任何底层的 EC2 实例。

    当流量激增时,ECS 可以在几秒钟内启动五个新任务。由于 Node.js 进程的占用资源较少,你可以以较小的粒度来配置计算资源(如 0.25 vCPU 和 512 MB RAM),这样就能将空闲资源及成本维持在接近零的水平。

    权衡因素:

    • AWS锁定效应:ECS的配置是针对AWS设计的。为ECS编写的任务定义JSON文件若不进行修改,则无法直接用于Google Cloud或Azure。
    • 工具生态系统较为薄弱:ECS虽能与CloudWatch和IAM良好集成,但其第三方插件生态系统远不及围绕Kubernetes发展起来的那套完善。

    3. Amazon EKS:企业级规模与可移植性

    EKS是AWS提供的托管版Kubernetes服务。Kubernetes的功能不仅限于运行容器,它还提供了网络管理、服务发现、滚动部署以及密钥管理的统一平台。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: node-api
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: node-api
      template:
        metadata:
          labels:
            app: node-api
        spec:
          containers:
          - name: node-api
            image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/node-api:v1.2.0
            resources:
              limits:
                cpu: "500m"
                memory: "512Mi"
              requests:
                cpu: "250m"
                memory: "256Mi"
            ports:
            - containerPort: 3000
    

    优势:

    • 真正的可移植性:相同的 YAML 配置文件即可在 EKS、Google 的 GKE、Azure 的 AKS,或是您自己数据中心的服务器上运行。
    • 丰富的生态系统:Helm、ArgoCD、Prometheus 和 Istio 等工具可通过标准配置实现集成。
    • 精确的自动扩缩容控制:您可以使用 KEDA(Kubernetes 事件驱动型自动扩缩容)根据自定义指标——如 SQS 队列中的消息数量或 Redis 缓冲区的大小——来调整容器的规模。

    权衡因素:

    Kubernetes 也会带来较大的运营负担:

    • 控制平面成本:EKS 仅为了维持控制平面的运行,每个集群每月就需要大约 73 美元的费用,这还不包括用于工作节点和运行容器的支出。
  • 学习曲线陡峭:您的团队需要掌握 Ingress 控制器、CoreDNS、集群自动扩缩容功能、CNI 插件以及 RBAC 规则的相关知识。
  • 常见错误: 有些团队仅仅因为 Kubernetes 是行业默认选择就选用 EKS。对于规模较小的工程团队——开发者人数少于 15 人——维护 Kubernetes 集群可能会占用资深工程师每周 20% 到 30% 的时间,而这些时间本可以用于产品开发本身。

    直接对比

    功能特性 Amazon EC2 Amazon ECS (Fargate) Amazon EKS
    抽象层次 虚拟机 容器 容器加 Pod
    部署复杂度 低 低至中等
    高 持续维护 高(补丁更新、操作系统、安全防护) 非常低 高(集群维护) 基础空闲成本 较低(t4g或t3实例每月约3至15美元) 仅需为实际运行的任务付费 控制平面约73美元/月,另加计算成本 扩展速度 分钟级(需启动完整虚拟机) 秒级(拉取镜像并启动任务) 秒级(调度容器组) 跨云迁移能力 低 低(依赖AWS) 高(标准Kubernetes架构) 理想团队规模 单独开发者或小型传统系统 2至50名工程师 专门的平台团队或DevOps小组

    实用的决策方法

    不必为每个功能纠结,只需遵循这条简单的原则:

    何时选择 EC2:

    • 您的 Node.js 应用属于旧版,依赖本地后台守护进程、特定操作系统的软件,或必须存储在本地磁盘上的文件。
    • 您正在使用每月5美元的实例快速搭建原型,此时价格是唯一需要考虑的因素。

    何时选择带 Fargate 的 ECS:

    • 您希望运行现代化的容器化 Node.js 服务,而无需亲自管理底层操作系统。
    • 您的团队由后端工程师组成,没有专门的基础设施或 DevOps 专家。
    • 您完全致力于 AWS 生态系统(DynamoDB、SQS、RDS、IAM),并希望获得开箱即用的安全集成功能。
    • 这种架构适用于大约80%在 AWS 上构建应用的公司,因此是合理的默认选择。

    何时选择 EKS:

    • 您需要运行数十甚至数百个采用多种语言开发的微服务,如 Node.js、Go、Python 和 Java。
    • 您的组织要求采用多云或混合云架构,且需要在各处使用统一的工具。
    • 您已经拥有能够安全监控、保护及升级 Kubernetes 集群的平台或 SRE 团队。

    总结

    优秀的云架构并非在于选择最炫酷的技术,而在于挑选那些能以最低维护成本解决问题方案。

    具体到 Node.js:

    • EC2 虽能让您完全掌控服务器,但需要您承担常规的服务器维护工作。
    • EKS 虽能提供强大的功能以及跨生态系统迁移的能力,但会带来较高的复杂度及集群管理开销。
  • Fargate版ECS可帮您免除服务器管理负担,能在几秒内扩展容器规模,让开发人员能够专注于编写优质的Node.js代码。
  • 明智的做法是从小规模开始:将您的应用封装在精简的Docker容器中,先在ECS上运行,只有当组织规模确实超出其承载能力时再转向Kubernetes。由于容器本身不会改变,因此一旦时机成熟,它已经为部署到EKS做好了准备。