nkds

导航

 

MonkeyCode 企业级部署架构指南:从单机到大规模集群的完整方案

引言

"好的工具在个人电脑上好用,优秀的工具在企业环境中更可靠。"

当 AI 编程助手从个人工具走向企业级基础设施时,面临的挑战完全不同:

  • 🔐 安全合规 — 代码不能离开内网,数据必须加密
  • 👥 多用户管理 — SSO 集成、权限控制、使用审计
  • 高可用性 — 7×24 不间断服务,故障自动恢复
  • 📈 弹性扩展 — 从 10 人到 10000+ 人的平滑扩容
  • 🏗️ 混合部署 — 本地 + 云端 + 边缘节点的统一架构

MonkeyCode 作为完全开源(Apache License 2.0)的 AI 编程助手,天然支持从单机开发环境到超大规模企业集群的全谱系部署。本指南将提供完整的架构设计、部署方案和运维最佳实践。

🎯 核心信息


一、部署架构全景

1.1 架构分层总览

┌─────────────────────────────────────────────────────────────┐
│         MonkeyCode 企业级部署架构                              │
│                                                             │
│  ══════════════════════════════════════════════════════    │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │           Layer 1: 客户端接入层 (Edge)              │   │
│  │                                                     │   │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐           │   │
│  │  │ VS Code  │ │ JetBrains │ │  Web IDE  │           │   │
│  │  │ 插件     │ │ 插件     │ │ 浏览器   │           │   │
│  │  └────┬─────┘ └────┬─────┘ └────┬─────┘           │   │
│  │       └────────────┼────────────┘                  │   │
│  │                    ▼                                │   │
│  │         ┌──────────────────────┐                   │   │
│  │         │   API Gateway / LB   │                   │   │
│  │         │   (Nginx/Traefik)    │                   │   │
│  │         └──────────┬───────────┘                   │   │
│  └────────────────────┼───────────────────────────────┘   │
│                         │                                   │
│  ┌────────────────────▼───────────────────────────────┐   │
│  │           Layer 2: 服务层 (Service)                 │   │
│  │                                                     │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌───────────┐  │   │
│  │  │ Auth        │  │ Session     │  │ Config    │  │   │
│  │  │ Service     │  │ Manager     │  │ Service   │  │   │
│  │  │ (SSO/OAuth) │  │ (Redis)     │  │ (Consul)  │  │   │
│  │  └─────────────┘  └─────────────┘  └───────────┘  │   │
│  │                                                     │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌───────────┐  │   │
│  │  │ AI Engine   │  │ Context     │  │ Plugin    │  │   │
│  │  │ (LLM Proxy) │  │ Service     │  │ Runtime   │  │   │
│  │  └─────────────┘  └─────────────┘  └───────────┘  │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │           Layer 3: 数据层 (Data)                     │   │
│  │                                                     │   │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐          │   │
│  │  │PostgreSQL│  │ Redis    │  │ MinIO/S3  │          │   │
│  │  │(主数据)  │  │(缓存)    │  │(对象存储) │          │   │
│  │  └──────────┘  └──────────┘  └──────────┘          │   │
│  │                                                     │   │
│  │  ┌──────────────────────────────────────────┐      │   │
│  │  │         Elasticsearch (日志/搜索)          │      │   │
│  │  └──────────────────────────────────────────┘      │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │           Layer 4: AI 基础设施层                      │   │
│  │                                                     │   │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐          │   │
│  │  │ Local LLM│  │ Cloud API│  │ Custom   │          │   │
│  │  │(Ollama)  │  │(Proxy)   │  │ Model    │          │   │
│  │  └──────────┘  └──────────┘  └──────────┘          │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
╚═══════════════════════════════════════════════════════════╝

1.2 部署模式对比

维度 单机模式 小型团队 中型企业 大规模集群
用户数 1-5 5-50 50-500 500-10000+
服务器 1 台工作站 1-3 台 VM 5-20 节点 50+ 节点 K8s
AI 模型 本地 Ollama 共享 GPU 混合部署 多区域分布
高可用 基础 HA 全链路 HA 多活容灾
SSO LDAP SAML 2.0 OIDC + MFA
审计日志 文件 数据库 ES + SIEM 实时流处理
适用场景 个人/小团队 初创公司 中型企业 超大型组织

二、Docker Compose 快速部署

2.1 最简部署(开发/测试)

# ===== docker-compose.yml =====
# MonkeyCode 单机快速启动配置
# 适用于:开发测试、POC 验证、小型团队 (< 10人)

version: '3.8'

services:
  # ===== 核心服务 =====
  monkeycode-server:
    image: monkeycode/monkeyCode-server:latest
    container_name: monkeycode-server
    restart: unless-stopped
    ports:
      - "3000:3000"      # Web UI & API
      - "3001:3001"      # WebSocket (实时通信)
    environment:
      # 基础配置
      - NODE_ENV=production
      - MC_PORT=3000
      - MC_WS_PORT=3001
      
      # 数据库连接
      - MC_DB_HOST=postgres
      - MC_DB_PORT=5432
      - MC_DB_NAME=monkeyCode
      - MC_DB_USER=monkeyCode
      - MC_DB_PASSWORD=${MC_DB_PASSWORD:-changeme_in_production}
      
      # Redis 缓存
      - MC_REDIS_HOST=redis
      - MC_REDIS_PORT=6379
      
      # AI 配置 (本地模型)
      - MC_AI_PROVIDER=ollama
      - MC_AI_OLLAMA_URL=http://ollama:11434
      - MC_AI_OLLAMA_MODEL=qwen2.5-coder:7b
      
      # 安全配置
      - MC_JWT_SECRET=${MC_JWT_SECRET:-generate_random_secret}
      - MC_ENCRYPTION_KEY=${MC_ENCRYPTION_KEY:-generate_32_byte_key}
      
      # 日志级别
      - LOG_LEVEL=info
    volumes:
      - mc_data:/app/data
      - mc_logs:/app/logs
      - ./config:/app/config:ro
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - monkeycode-net

  # ===== PostgreSQL 数据库 =====
  postgres:
    image: postgres:16-alpine
    container_name: monkeycode-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: monkeyCode
      POSTGRES_USER: monkeyCode
      POSTGRES_PASSWORD: ${MC_DB_PASSWORD:-changeme_in_production}
    volumes:
      - pg_data:/var/lib/postgresql/data
      - ./init-db:/docker-entrypoint-initdb.d:ro
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U monkeyCode"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - monkeycode-net

  # ===== Redis 缓存 =====
  redis:
    image: redis:7-alpine
    container_name: monkeycode-redis
    restart: unless-stopped
    command: redis-server --requirepass ${MC_REDIS_PASSWORD:-redis_password} --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3
    networks:
      - monkeycode-net

  # ===== Ollama 本地 LLM (可选) =====
  ollama:
    image: ollama/ollama:latest
    container_name: monkeycode-ollama
    restart: unless-stopped
    volumes:
      - ollama_data:/root/.ollama
    ports:
      - "11434:11434"
    # 如果有 GPU,取消下面的注释
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: 1
    #           capabilities: [gpu]
    networks:
      - monkeycode-net

  # ===== Nginx 反向代理 (可选) =====
  nginx:
    image: nginx:alpine
    container_name: monkeycode-nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - monkeycode-server
    networks:
      - monkeycode-net

volumes:
  pg_data:
  redis_data:
  ollama_data:
  mc_data:
  mc_logs:

networks:
  monkeycode-net:
    driver: bridge

2.2 Nginx 配置

# ===== nginx.conf =====
# MonkeyCode 反向代理配置

upstream monkeycode_backend {
    server monkeycode-server:3000;
    keepalive 32;
}

upstream monkeycode_ws {
    server monkeycode-server:3001;
}

server {
    listen 80;
    server_name monkeycode.yourcompany.com;
    
    # 强制 HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name monkeycode.yourcompany.com;

    # SSL 证书配置
    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    # 安全头
    add_header X-Frame-Options DENY always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # API 请求
    location /api/ {
        proxy_pass http://monkeycode_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # 大文件上传支持
        client_max_body_size 50m;
        proxy_read_timeout 120s;
        
        # 限流
        limit_req zone=api burst=20 nodelay;
    }

    # WebSocket
    location /ws {
        proxy_pass http://monkeycode_ws;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 86400s;
    }

    # 静态资源 (前端)
    location / {
        proxy_pass http://monkeycode_backend;
        proxy_cache_valid 200 1h;
        expires 1h;
    }

    # 限流定义
    limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
}

三、Kubernetes 生产级部署

3.1 Helm Chart 核心配置

# ===== values.yaml (生产环境推荐配置) =====
# MonkeyCode Kubernetes Helm Chart

# ===== 全局配置 =====
global:
  imageRegistry: registry.yourcompany.com
  imagePullSecrets:
    - name: regcred
  
  # 环境标签
  environment: production
  team: platform

# ===== 应用配置 =====
replicaCount: 3  # 至少 3 个副本保证高可用

image:
  repository: monkeycode/monkeyCode-server
  tag: "v2.1.0"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80
  annotations:
    # 使用云厂商负载均衡器
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"

ingress:
  enabled: true
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
  hosts:
    - host: monkeycode.yourcompany.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: monkeycode-tls
      hosts:
        - monkeycode.yourcompany.com

# ===== 资源配置 =====
resources:
  requests:
    cpu: "500m"
    memory: "512Mi"
  limits:
    cpu: "2000m"
    memory: "2Gi"

# HPA 自动伸缩
autoscaling:
  enabled: true
  minReplicas: 3
  maxReplicas: 20
  targetCPUUtilizationPercentage: 70
  targetMemoryUtilizationPercentage: 80

# ===== 数据库配置 =====
postgresql:
  enabled: true
  auth:
    username: monkeyCode
    database: monkeyCode
    existingSecret: monkeycode-db-secret
  primary:
    resources:
      requests:
        cpu: "250m"
        memory: "256Mi"
      limits:
        cpu: "1000m"
        memory: "1Gi"
    persistence:
      size: 100Gi
      storageClass: gp3  # AWS EBS gp3

redis:
  enabled: true
  auth:
    existingSecret: monkeycode-redis-secret
  master:
    resources:
      requests:
        cpu: "100m"
        memory: "128Mi"
  replica:
    replicaCount: 2  # Redis 高可用副本
  persistence:
    size: 10Gi

# ===== AI 模型配置 =====
ai:
  provider: hybrid  # hybrid = 本地优先 + 云端兜底
  
  local:
    enabled: true
    model: qwen2.5-coder:14b
    gpu:
      enabled: true
      vendor: nvidia
      type: t4  # 或 a10g/l4
      count: 1
    
  cloud:
    enabled: true
    fallbackOnly: true  # 仅作为本地不可用时的备选
    provider: azure-openai
    endpoint: ${AZURE_OPENAI_ENDPOINT}
    model: gpt-4o-mini
    
  # 智能路由规则
  routing:
    rules:
      - condition: "context.size < 4096 AND user.tier == 'free'"
        target: cloud
      - condition: "context.contains('confidential')"
        target: local
      - default: local

# ===== 安全配置 =====
security:
  # JWT 认证
  jwt:
    secretName: monkeycode-jwt-secret
    expiresIn: 24h
    refreshExpiresIn: 7d
    
  # 加密密钥
  encryption:
    secretName: monkeycode-encryption-key
    algorithm: AES-256-GCM
    
  # 网络策略
  networkPolicy:
    enabled: true
    ingress:
      - from:
          - namespaceSelector:
              matchLabels:
                name: ingress-nginx
        ports:
          - port: 8080
    egress:
      - to:
          - namespaceSelector:
              matchLabels:
                name: database
        ports:
          - port: 5432
      - to:
          - namespaceSelector:
              matchLabels:
                name: cache
        ports:
          - port: 6379

# ===== SSO 集成 =====
auth:
  sso:
    provider: oidc
    issuer: https://sso.yourcompany.com
    clientId: ${OIDC_CLIENT_ID}
    clientSecretName: monkeycode-sso-client-secret
    scopes:
      - openid
      - profile
      - email
      - groups
    
  rbac:
    enabled: true
    adminGroup: cn=mc-admins,ou=groups,dc=yourcompany,dc=com
    userGroup: cn=mc-users,ou=groups,dc=yourcompany,dc=com

# ===== 监控与日志 =====
monitoring:
  prometheus:
    enabled: true
    scrapeInterval: 15s
    
  grafana:
    enabled: true
    dashboards:
      enabled: true
      
  jaeger:
    enabled: true  # 分布式追踪

logging:
  driver: json-file
  level: info
  elasticsearch:
    enabled: true
    host: elasticsearch.logging.svc.cluster.local
    port: 9200
    index: monkeycode-%{YYYY.MM.dd}

# ===== 备份配置 =====
backup:
  enabled: true
  schedule: "0 2 * * *"  # 每天凌晨 2 点
  retention: 30d
  destination: s3://your-backet-monkeyCode-backups/
  encryption: AES256

3.2 Kubernetes 部署清单

# ===== deploy.sh =====
#!/bin/bash
set -euo pipefail

echo "🚀 开始部署 MonkeyCode 到 Kubernetes..."

# 1. 创建命名空间
kubectl create namespace monkeycode --dry-run=client -o yaml | kubectl apply -f -

# 2. 创建密钥 (生产环境请使用外部密钥管理系统)
kubectl create secret generic monkeycode-db-secret \
  --namespace=monkeycode \
  --from-literal=password="$(openssl rand -base64 32)" \
  --dry-run=client -o yaml | kubectl apply -f -

kubectl create secret generic monkeycode-redis-secret \
  --namespace=monkeycode \
  --from-literal=password="$(openssl rand -base64 16)" \
  --dry-run=client -o yaml | kubectl apply -f -

kubectl create secret generic monkeycode-jwt-secret \
  --namespace=monkeycode \
  --from-literal=secret="$(openssl rand -base64 64)" \
  --dry-run=client -o yaml | kubectl apply -f -

kubectl create secret generic monkeycode-encryption-key \
  --namespace=monkeycode \
  --from-literal=key="$(openssl rand -hex 32)" \
  --dry-run=client -o yaml | kubectl apply -f -

# 3. 安装 Helm Chart
helm upgrade --install monkeycode \
  ./helm-chart/monkeyCode \
  --namespace monkeycode \
  --values values-production.yaml \
  --wait --timeout=600s

# 4. 验证部署
echo ""
echo "✅ 部署完成!验证状态..."
kubectl get pods -n monkeycode -l app=monkeyCode
kubectl get svc -n monkeycode
kubectl get ingress -n monkeycode

echo ""
echo "🎉 MonkeyCode 已成功部署!"
echo "访问地址: https://monkeycode.yourcompany.com"

四、AI 模型部署方案

4.1 本地 LLM 部署(Ollama/vLLM)

# ===== k8s/llm-deployment.yaml =====
# 本地大语言模型部署 (GPU 节点)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: monkeycode-llm-local
  namespace: monkeycode
spec:
  replicas: 1
  selector:
    matchLabels:
      app: monkeycode-llm
  template:
    metadata:
      labels:
        app: monkeycode-llm
    spec:
      # GPU 节点调度
      nodeSelector:
        gpu: "true"
        gpu-vendor: nvidia
      tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: "NoSchedule"
      
      containers:
        - name: ollama
          image: ollama/ollama:latest
          ports:
            - containerPort: 11434
          resources:
            limits:
              nvidia.com/gpu: "1"
              memory: "32Gi"
            requests:
              memory: "24Gi"
          volumeMounts:
            - name: model-cache
              mountPath: /.ollama
          livenessProbe:
            httpGet:
              path: /
              port: 11434
            initialDelaySeconds: 60
            periodSeconds: 30
          readinessProbe:
            httpGet:
              path: /api/tags
              port: 11434
            initialDelaySeconds: 30
            periodSeconds: 10
            
        - name: model-loader
          image: busybox:latest
          command: ['sh', '-c', '
            echo "Waiting for Ollama to start..." &&
            sleep 30 &&
            curl -f http://localhost:11434/api/pull -d "{\"name\": \"qwen2.5-coder:14b\"}" &&
            echo "Model pulled successfully!"
          ']
          
      volumes:
        - name: model-cache
          persistentVolumeClaim:
            claimName: llm-model-cache

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: llm-model-cache
  namespace: monkeycode
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: gp3
  resources:
    requests:
      storage: 50Gi  # 14B 模型约需 10GB,留足空间

---
apiVersion: v1
kind: Service
metadata:
  name: monkeycode-llm-service
  namespace: monkeycode
spec:
  selector:
    app: monkeycode-llm
  ports:
    - port: 11434
      targetPort: 11434
  type: ClusterIP

4.2 云端 API 代理配置

// ===== config/ai-proxy.ts =====
/**
 * MonkeyCode AI 代理配置
 * 
 * 统一管理多个 AI 后端的路由、负载均衡、
 * 降级策略和成本控制。
 */

export interface AIProviderConfig {
  id: string;
  name: string;
  type: 'openai' | 'azure' | 'anthropic' | 'local' | 'custom';
  
  // 连接信息
  endpoint: string;
  apiKey?: string;  // 通过环境变量注入
  apiVersion?: string;
  
  // 模型配置
  models: Array<{
    id: string;
    name: string;
    contextWindow: number;
    maxOutputTokens: number;
    costPer1kInput?: number;
    costPer1kOutput?: number;
  }>;
  
  // 限制
  rateLimit: {
    rpm: number;   // 每分钟请求数
    tpm: number;   // 每分钟 token 数
    concurrent: number;  // 并发数
  };
  
  // 特性标记
  features: {
    streaming: boolean;
    functionCalling: boolean;
    vision: boolean;
    systemPrompt: boolean;
  };
  
  // 优先级 (数字越小越优先)
  priority: number;
  
  // 启用状态
  enabled: boolean;
}

// ===== 生产环境 AI 配置示例 =====
export const aiProviders: AIProviderConfig[] = [
  // === Tier 1: 本地模型 (最高优先级,零成本) ===
  {
    id: 'local-qwen',
    name: 'Qwen2.5-Coder 14B (Local)',
    type: 'local',
    endpoint: 'http://monkeycode-llm-service:11434',
    models: [{
      id: 'qwen2.5-coder:14b',
      name: 'Qwen2.5-Coder 14B',
      contextWindow: 32768,
      maxOutputTokens: 8192,
      costPer1kInput: 0,
      costPer1kOutput: 0,
    }],
    rateLimit: { rpm: 60, tpm: 500000, concurrent: 10 },
    features: {
      streaming: true,
      functionCalling: false,
      vision: false,
      systemPrompt: true,
    },
    priority: 1,
    enabled: true,
  },
  
  // === Tier 2: Azure OpenAI (付费,高质量) ===
  {
    id: 'azure-gpt4o-mini',
    name: 'Azure GPT-4o Mini',
    type: 'azure',
    endpoint: process.env.AZURE_OPENAI_ENDPOINT!,
    apiVersion: '2024-02-15-preview',
    models: [{
      id: 'gpt-4o-mini',
      name: 'GPT-4o Mini',
      contextWindow: 128000,
      maxOutputTokens: 16384,
      costPer1kInput: 0.00015,
      costPer1kOutput: 0.0006,
    }],
    rateLimit: { rpm: 500, tpm: 150000, concurrent: 50 },
    features: {
      streaming: true,
      functionCalling: true,
      vision: true,
      systemPrompt: true,
    },
    priority: 2,
    enabled: true,
  },
  
  // === Tier 3: Anthropic Claude (备选) ===
  {
    id: 'anthropic-claude',
    name: 'Claude 3.5 Sonnet',
    type: 'anthropic',
    endpoint: 'https://api.anthropic.com',
    models: [{
      id: 'claude-3-5-sonnet-20241022',
      name: 'Claude 3.5 Sonnet',
      contextWindow: 200000,
      maxOutputTokens: 8192,
      costPer1kInput: 0.003,
      costPer1kOutput: 0.015,
    }],
    rateLimit: { rpm: 1000, tpm: 500000, concurrent: 100 },
    features: {
      streaming: true,
      functionCalling: true,
      vision: true,
      systemPrompt: true,
    },
    priority: 3,
    enabled: true,
  },
];

// ===== 智能路由逻辑 =====
export interface RoutingContext {
  userId: string;
  userTier: 'free' | 'pro' | 'enterprise';
  requestSize: number;  // token 数
  isConfidential: boolean;
  requiredFeatures: string[];
  preferredProvider?: string;
}

export function selectBestProvider(
  context: RoutingContext,
): AIProviderConfig | null {
  // 过滤可用的 Provider
  const available = aiProviders.filter(p => p.enabled);
  
  // 1. 用户指定了偏好 Provider
  if (context.preferredProvider) {
    const preferred = available.find(p => p.id === context.preferredProvider);
    if (preferred) return preferred;
  }
  
  // 2. 机密内容 → 必须走本地
  if (context.isConfidential) {
    const local = available.find(p => p.type === 'local');
    if (local) return local;
    // 如果没有本地模型,拒绝请求
    return null;
  }
  
  // 3. 免费用户 → 优先本地,降级到低成本云端
  if (context.userTier === 'free') {
    return available
      .filter(p => p.type === 'local' || p.models[0].costPer1kInput! < 0.001)
      .sort((a, b) => a.priority - b.priority)[0] || null;
  }
  
  // 4. 企业用户 → 按优先级选择
  if (context.userTier === 'enterprise') {
    return available.sort((a, b) => a.priority - b.priority)[0];
  }
  
  // 5. 默认: 按优先级 + 可用性
  return available.sort((a, b) => a.priority - b.priority)[0];
}

五、安全加固方案

5.1 网络安全

# ===== k8s/network-policy.yaml =====
# MonkeyCode 网络隔离策略

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: monkeycode-network-policy
  namespace: monkeycode
spec:
  podSelector:
    matchLabels:
      app: monkeycode
  policyTypes:
    - Ingress
    - Egress
  
  ingress:
    # 只允许 Ingress Controller 访问
    - from:
        - namespaceSelector:
            matchLabels:
              name: ingress-nginx
      ports:
        - protocol: TCP
          port: 8080
        
    # 允许同命名空间的 Pod 间通信
    - from:
        - podSelector: {}
      
  egress:
    # 允许访问数据库
    - to:
        - podSelector:
            matchLabels:
              app: postgresql
      ports:
        - protocol: TCP
          port: 5432
          
    # 允许访问 Redis
    - to:
        - podSelector:
            matchLabels:
              app: redis-master
      ports:
        - protocol: TCP
          port: 6379
          
    # 允许访问本地 LLM
    - to:
        - podSelector:
            matchLabels:
              app: monkeycode-llm
      ports:
        - protocol: TCP
          port: 11434
          
    # 允许 DNS 解析
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
          
    # 允许访问外部 HTTPS (用于云端 AI API)
    - to:
        - namespaceSelector: {}
      ports:
        - protocol: TCP
          port: 443

5.2 密钥管理

# ===== scripts/setup-secrets.sh =====
#!/bin/bash
# MonkeyCode 密钥管理脚本
# 推荐使用 HashiCorp Vault 或云厂商 KMS

set -euo pipefail

NAMESPACE="monkeycode"

echo "🔐 设置 MonkeyCode 生产密钥..."

# 方法 1: Kubernetes Secrets (基础)
# 仅适用于非敏感环境或开发/测试

# JWT 密钥 (至少 64 字符随机字符串)
JWT_SECRET=$(openssl rand -base64 64)
kubectl create secret generic monkeycode-jwt-secret \
  --namespace="$NAMESPACE" \
  --from-literal=secret="$JWT_SECRET" \
  --dry-run=client -o yaml | kubectl apply -f -

# AES-256-GCM 加密密钥 (32 字节 hex)
ENCRYPTION_KEY=$(openssl rand -hex 32)
kubectl create secret generic monkeycode-encryption-key \
  --namespace="$NAMESPACE" \
  --from-literal=key="$ENCRYPTION_KEY" \
  --dry-run=client -o yaml | kubectl apply -f -

# 数据库密码
DB_PASSWORD=$(openssl rand -base64 32)
kubectl create secret generic monkeycode-db-secret \
  --namespace="$NAMESPACE" \
  --from-literal=password="$DB_PASSWORD" \
  --dry-run=client -o yaml | kubectl apply -f -

# Redis 密码
REDIS_PASSWORD=$(openssl rand -base64 16)
kubectl create secret generic monkeycode-redis-secret \
  --namespace="$NAMESPACE" \
  --from-literal=password="$REDIS_PASSWORD" \
  --dry-run=client -o yaml | kubectl apply -f -

# SSO OAuth 客户端密钥
kubectl create secret generic monkeycode-sso-client-secret \
  --namespace="$NAMESPACE" \
  --from-literal=clientId="${OIDC_CLIENT_ID}" \
  --from-literal=clientSecret="${OIDC_CLIENT_SECRET}" \
  --dry-run=client -o yaml | kubectl apply -f -

# Azure OpenAI API Key
kubectl create secret generic monkeycode-azure-openai \
  --namespace="$NAMESPACE" \
  --from-literal=endpoint="${AZURE_OPENAI_ENDPOINT}" \
  --from-literal=apiKey="${AZURE_OPENAI_API_KEY}" \
  --dry-run=client -o yaml | kubectl apply -f -

echo "✅ 所有密钥已创建!"

# 输出重要信息 (仅此一次!)
echo ""
echo "⚠️  请立即保存以下信息到安全的密码管理器:"
echo "  JWT Secret: ${JWT_SECRET:0:16}..."
echo "  Encryption Key: ${ENCRYPTION_KEY:0:16}..."
echo "  DB Password: ${DB_PASSWORD:0:16}..."

六、监控与运维

6.1 Prometheus 监控指标

# ===== monitoring/prometheus-rules.yaml =====
# MonkeyCode 告警规则

groups:
  - name: monkeycode-alerts
    rules:
      # === 服务可用性 ===
      - alert: MonkeyCodeDown
        expr: up{job="monkeyCode"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "MonkeyCode 服务不可用"
          description: "MonkeyCode 服务已宕机超过 1 分钟"
          
      - alert: MonkeyCodeHighErrorRate
        expr: |
          sum(rate(http_requests_total{job="monkeyCode", status=~"5.."}[5m]))
          / sum(rate(http_requests_total{job="monkeyCode"}[5m])) > 0.05
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "MonkeyCode 错误率过高"
          description: "错误率超过 5%,当前值: {{ $value | humanizePercentage }}"
          
      # === 性能告警 ===
      - alert: MonkeyCodeHighLatency
        expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{job="monkeyCode"}[5m])) > 5
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "MonkeyCode 响应延迟过高"
          description: "P95 延迟超过 5 秒,当前值: {{ $value }}s"
          
      - alert: MonkeyCodeHighMemoryUsage
        expr: container_memory_usage_bytes{container="monkeyCode"} / container_spec_memory_limit_bytes{container="monkeyCode"} > 0.85
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "MonkeyCode 内存使用率过高"
          description: "内存使用超过 85%,当前值: {{ $value | humanizePercentage }}"
          
      # === AI 相关告警 ===
      - alert: AILocalModelDown
        expr: up{job="monkeyCode-llm"} == 0
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "本地 AI 模型服务不可用"
          description: "Ollama/本地 LLM 服务已宕机,将自动切换到云端 API"
          
      - alert: AICloudAPIHighCost
        expr: increase(monkeyCode_ai_tokens_cloud_total[1h]) > 10000000
        for: 0m
        labels:
          severity: info
        annotations:
          summary: "云端 AI Token 消耗量较大"
          description: "过去 1 小时消耗了 {{ $value }} tokens 的云端 API 调用"
          
      # === 安全告警 ===
      - alert: HighAuthFailureRate
        expr: |
          sum(rate(monkeyCode_auth_failures_total[5m]))
          / sum(rate(monkeyCode_auth_attempts_total[5m])) > 0.1
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "认证失败率过高"
          description: "认证失败率超过 10%,可能存在暴力破解攻击"
          
      - alert: SuspiciousPromptInjection
        expr: increase(monkeyCode_security_injection_detected_total[10m]) > 5
        for: 0m
        labels:
          severity: warning
        annotations:
          summary: "检测到多次 Prompt 注入尝试"
          description: "过去 10 分钟检测到 {{ $value }} 次 Prompt 注入尝试"

6.2 Grafana Dashboard 配置

{
  "dashboard": {
    "title": "MonkeyCode Enterprise Dashboard",
    "panels": [
      {
        "title": "请求量 (RPS)",
        "type": "graph",
        "targets": [
          {
            "expr": "sum(rate(http_requests_total{job=\"monkeyCode\"}[5m])) by (endpoint)",
            "legendFormat": "{{endpoint}}"
          }
        ]
      },
      {
        "title": "响应延迟 (P95)",
        "type": "gauge",
        "targets": [
          {
            "expr": "histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{job=\"monkeyCode\"}[5m])) by (le))",
            "legendFormat": "P95 Latency"
          }
        ],
        "fieldConfig": {
          "thresholds": {"mode": "absolute", "steps":[{"value":0,"color":"green"},{"value":2,"color":"yellow"},{"value":5,"color":"red"}]},
          "unit": "s"
        }
      },
      {
        "title": "AI 请求来源分布",
        "type": "piechart",
        "targets": [
          {
            "expr": "sum(rate(monkeyCode_ai_requests_total{job=\"monkeyCode\"}[1h])) by (provider)",
            "legendFormat": "{{provider}}"
          }
        ]
      },
      {
        "title": "活跃用户数",
        "type": "stat",
        "targets": [
          {
            "expr": "count(monkeyCode_user_active{job=\"monkeyCode\"})",
            "legendFormat": "Active Users"
          }
        ]
      },
      {
        "title": "Token 消耗趋势",
        "type": "graph",
        "targets": [
          {
            "expr": "sum(increase(monkeyCode_ai_tokens_total{job=\"monkeyCode\"}[1h])) by (provider)",
            "legendFormat": "{{provider}}"
          }
        ],
        "fieldConfig": {"unit": "short"}
      }
    ]
  }
}

七、灾难恢复与备份

7.1 备份策略

# ===== scripts/backup.sh =====
#!/bin/bash
# MonkeyCode 自动化备份脚本

set -euo pipefail

BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
S3_BUCKET="s3://your-company-backups/monkeyCode/"
RETENTION_DAYS=30

echo "📦 开始备份 MonkeyCode... ($BACKUP_DATE)"

# 1. PostgreSQL 数据库备份
echo "  → 备份数据库..."
kubectl exec -n monkeycode deployment/monkeyCode-postgresql -- \
  pg_dump -U monkeyCode -d monkeyCode --format=custom \
  | gzip > "/tmp/mc_db_${BACKUP_DATE}.sql.gz"

aws s3 cp "/tmp/mc_db_${BACKUP_DATE}.sql.gz" "${S3_BUCKET}db/" \
  --storage-class STANDARD_IA \
  --server-side-encryption AES256

rm -f "/tmp/mc_db_${BACKUP_DATE}.sql.gz"

# 2. Redis 快照备份
echo "  → 备份 Redis..."
kubectl exec -n monkeycode deployment/monkeyCode-redis-master -- \
  redis-cli BGSAVE
sleep 5

kubectl cp "monkeycode/deployment/monkeyCode-redis-master:/data/dump.rdb" \
  "/tmp/mc_redis_${BACKUP_DATE}.rdb"

aws s3 cp "/tmp/mc_redis_${BACKUP_DATE}.rdb" "${S3_BUCKET}redis/" \
  --storage-class STANDARD_IA

rm -f "/tmp/mc_redis_${BACKUP_DATE}.rdb"

# 3. 配置文件备份
echo "  → 备份配置..."
kubectl get secrets -n monkeycode -o yaml > "/tmp/mc_secrets_${BACKUP_DATE}.yaml"
kubectl get configmap -n monkeycode -o yaml > "/tmp/mc_configmaps_${BACKUP_DATE}.yaml"

tar czf "/tmp/mc_config_${BACKUP_DATE}.tar.gz" \
  "/tmp/mc_secrets_${BACKUP_DATE}.yaml" \
  "/tmp/mc_configmaps_${BACKUP_DATE}.yaml"

aws s3 cp "/tmp/mc_config_${BACKUP_DATE}.tar.gz" "${S3_BUCKET}config/" \
  --storage-class GLACIER_IR

rm -f "/tmp/mc_config_${BACKUP_DATE}.tar.gz"

# 4. 清理过期备份
echo "  → 清理过期备份 (${RETENTION_DAYS} 天前)..."
aws s3 ls "${S3_BUCKET}db/" | \
  awk '{print $4}' | while read file; do
    file_date=$(echo "$file" | grep -oE '[0-9]{8}_[0-9]{6}')
    if [[ -n "$file_date" ]]; then
      file_epoch=$(date -d "${file_date:0:8} ${file_date:9:2}:${file_date:11:2}:${file_date:13:2}" +%s 2>/dev/null || echo 0)
      cutoff_epoch=$(date -d "-${RETENTION_DAYS} days" +%s)
      if [[ "$file_epoch" -lt "$cutoff_epoch" ]]; then
        aws s3 rm "${S3_BUCKET}db/${file}"
      fi
    fi
  done

echo "✅ 备份完成!"
echo "  数据库: ${S3_BUCKET}db/mc_db_${BACKUP_DATE}.sql.gz"
echo "  Redis:  ${S3_BUCKET}redis/mc_redis_${BACKUP_DATE}.rdb"
echo "  配置:   ${S3_BUCKET}config/mc_config_${BACKUP_DATE}.tar.gz"

7.2 故障恢复流程

flowchart TD A[检测到故障] --> B{故障类型?} B -->|单节点故障| C[K8s 自动重启 Pod] C --> D{恢复成功?} D -->|是| E[✅ 正常] D -->|否| F[检查事件日志] B -->|数据库故障| G[从 S3 恢复备份] G --> H[验证数据完整性] H --> I[切换流量] B -->|整个区域故障| J[激活异地灾备] J --> K[DNS 切换] K --> L[验证全链路] B -->|安全事件| M[隔离受影响节点] M --> N[取证分析] N --> O[打补丁/更新] O --> P[逐步恢复服务] F --> Q{根因分析完成?} Q -->|是| R[实施修复] Q -->|否| S[升级至专家团队] R --> E S --> T[紧急响应流程]

八、容量规划

8.1 规模估算表

用户规模 并发用户 API QPS 所需节点 GPU 需求 月成本估算
10 人 5 ~10 2 (无 K8s) 0-1 T4 ~$200
50 人 25 ~50 3-5 K8s 1-2 T4 ~$800
200 人 80 ~200 5-10 K8s 2-4 A10G ~$3,000
1000 人 300 ~800 10-20 K8s 4-8 A10G/L4 ~$12,000
5000 人 1200 ~3000 20-50 K8s 8-16 L4/A100 ~$50,000

8.2 成本优化建议

┌─────────────────────────────────────────────────────────────┐
│         MonkeyCode 企业部署成本优化策略                       │
│                                                             │
│  💰 成本优化 Top 5                                         │
│                                                             │
│  1. 本地模型优先                                            │
│     → 70%+ 请求走本地 LLM (零边际成本)                    │
│     → 推荐: Qwen2.5-Coder / DeepSeek-Coder               │
│                                                             │
│  2. 智能缓存                                                │
│     → 相似代码片段命中缓存 (减少 40%+ AI 调用)             │
│     → Redis + 向量缓存结合                                 │
│                                                             │
│  3. Spot/Preemptible 实例                                  │
│     → GPU 节点使用 Spot 实例 (节省 60-70%)                │
│     → 配合 Checkpoint 机制实现无缝替换                    │
│                                                             │
│  4. 自动伸缩                                                │
│     → 基于 QPS/CPU/Memory 的 HPA                          │
│     → 夜间/周末自动缩容                                    │
│                                                             │
│  5. 多区域部署                                              │
│     → 选择成本最优的区域部署                               │
│     → 注意数据驻留合规要求                                 │
│                                                             │
╚═══════════════════════════════════════════════════════════╝

结语

"企业级部署不是简单的'放大版'——它需要全新的架构思维。"

MonkeyCode 的开源本质赋予了企业在部署层面的最大灵活性。无论是完全离线的内网环境、混合云架构,还是全球多区域的大规模部署,MonkeyCode 都能通过其模块化的架构适配各种场景。

记住几个关键原则:

  1. 安全第一 — 代码资产是企业最宝贵的财富
  2. 渐进式演进 — 从小规模开始,逐步扩展
  3. 可观测性为王 — 你无法改进你无法度量的东西
  4. 自动化一切 — 手动操作是故障的最大来源

如果你在企业部署过程中遇到问题,或者需要定制化的架构咨询,欢迎联系我们的企业支持团队。

💡 企业资源

MonkeyCode 企业版 — 为企业的每一行代码保驾护航。 🐵🏢✨

posted on 2026-06-30 13:11  MonkeyCode  阅读(15)  评论(0)    收藏  举报