MonkeyCode 容器编排内幕:从Docker Compose到Kubernetes的演进之路

MonkeyCode 的核心竞争力之一是为每个用户提供独立的云端开发环境。这意味着容器编排是整个系统的基石。从早期的Docker Compose到现在的Kubernetes,MonkeyCode经历了三次架构演进。

第一代:单机Docker Compose

MonkeyCode 最初是为小规模使用设计的。一台服务器,Docker Compose编排所有服务:

# docker-compose.yml(v1版本)\nversion: "3.8"\nservices:\n  gateway:\n    build: ./gateway\n    ports: ["8080:8080"]\n  workspace-manager:\n    build: ./workspace\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n  postgres:\n    image: postgres:15\n  redis:\n    image: redis:7-alpine

这个架构的问题很快暴露:

  • 单点故障 — 服务器挂了,所有用户的环境都丢失
  • 资源瓶颈 — 一台服务器最多支撑约50个并发容器
  • 无法弹性伸缩 — 用户高峰期资源不够,低谷期资源浪费

当用户量突破100人时,单机架构已经力不从心。

第二代:Docker Swarm集群

第二代的改进是引入Docker Swarm做容器集群:

// 容器调度逻辑\nclass SwarmScheduler implements ContainerScheduler {\n  async createWorkspace(userId: string): Promise<Workspace> {\n    // 1. 找到资源最充裕的节点\n    const node = await this.findBestNode();\n    \n    // 2. 创建容器\n    const container = await this.swarm.createService({\n      name: `workspace-${userId}`,\n      image: 'monkeycode/workspace:latest',\n      resources: {\n        cpu_limit: 2,\n        memory_limit: 4 * 1024 * 1024 * 1024, // 4GB\n      },\n      placement: {\n        constraints: [`node.id == ${node.id}`]\n      }\n    });\n    \n    return container;\n  }\n}

Docker Swarm解决了单机的问题,但引入了新的复杂性:

  • 跨节点存储同步复杂
  • 网络配置管理困难
  • 监控和日志收集需要额外方案
  • Swarm社区活跃度下降,长期维护风险

第三代:Kubernetes原生

当用户量突破1000人,MonkeyCode迁移到了Kubernetes。这次迁移不只是换了一个编排工具,而是重新设计了整个调度架构。

核心设计:Workspace Custom Resource

MonkeyCode 定义了自己的Kubernetes CRD(Custom Resource Definition):

// Workspace CRD\napiVersion: api.monkeyCode.ai/v1\nkind: Workspace\nmetadata:\n  name: workspace-user123\nspec:\n  userId: user123\n  resources:\n    cpu: "2"\n    memory: "4Gi"\n    storage: "10Gi"\n  image: monkeycode/workspace:v1.8\n  networking:\n    allowOutbound: true\n    outboundPorts: [80, 443]\n  lifecycle:\n    idleTimeout: 30m     # 30分钟无操作暂停\n    maxLifetime: 7d      # 最长运行7天\n    snapshotOnPause: true # 暂停前自动快照

调度器设计

自定义调度器考虑以下因素:

  1. 资源可用性 — 节点剩余CPU/内存是否满足需求
  2. 用户亲和性 — 优先把用户调度到之前的节点(缓存数据可能还在本地)
  3. 成本优化 — 优先使用Spot/抢占式实例,降低成本
  4. 故障域分布 — 同一用户的容器分布在不同可用区

存储方案

每个Workspace使用PersistentVolumeClaim存储用户数据:

// 存储层级\n- PVC (10GB per workspace)\n  └── 用户代码文件\n  └── npm/node_modules缓存\n  └── 项目配置\n\n- 对象存储 (S3/MinIO)\n  └── 文件快照\n  └── 项目备份\n  └── 静态资源

自动伸缩

Kubernetes的HPA(Horizontal Pod Autoscaler)配合自定义指标:

  • 并发Workspace数量 — 超过阈值自动添加节点
  • 等待队列长度 — 用户等待创建Workspace的时间过长时扩容
  • 成本预算 — 在成本预算内最大化可用资源

三代架构对比

维度 Docker Compose Docker Swarm Kubernetes
最大并发 ~50 ~200 无限(水平扩展)
高可用 ⚠️
自动伸缩 ⚠️
存储管理 本地 分布式 CSI插件
运维复杂度
适用规模 <100用户 100-1000 1000+

给中小团队的实用建议

如果你的项目也在做容器编排:

  1. 不要一开始就用K8s — 100个用户以内,Docker Compose够用
  2. 先解决有和无的问题 — 能跑起来比架构优雅更重要
  3. 预留迁移空间 — 用接口隔离编排逻辑,未来换方案成本低
  4. 监控先行 — 在迁移之前先建立监控,迁移过程中用数据说话
  5. 灰度迁移 — 先迁移10%的用户,验证无误后再全量迁移

总结

容器编排没有银弹。MonkeyCode从Docker Compose到Kubernetes的演进,是随着用户量增长的自然选择。最重要的是:每一代架构都解决了当时最紧迫的问题,而不是过度设计。

编排配置开源:github.com/chaitin/MonkeyCode/tree/main/deploy

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐