Administrator
发布于 2026-03-12 / 30 阅读
0
0

KimiClaw/MaxClaw 多租户部署架构解析

各大厂商如何快速给每个用户提供一个独立 OpenClaw 实例


一、厂商概览

当前市场上的 OpenClaw 变体:

厂商产品定位特点
月之暗面KimiClaw面向 C 端用户Kimi 大模型 + OpenClaw 框架
MiniMaxMaxClaw面向企业用户MiniMax 模型 + 企业级功能
其他NullClaw/OpenFang/ZeroClaw/PicoClaw/TinyClaw/Miclaw垂直场景各自特色定位

二、核心技术方案

方案对比

方案隔离级别成本/用户部署速度适用场景
Docker 容器隔离¥50-200/月30秒标准方案,推荐
Kubernetes 多租户¥30-100/月10秒大规模,成本优
共享实例 + 数据隔离¥5-20/月即时成本敏感
Serverless 按需按调用量冷启动低频使用

三、Docker 容器隔离方案(主流)

架构图

┌─────────────────────────────────────────────────────────────────┐
│                         负载均衡层                               │
│                    Nginx / ALB / CloudFlare                     │
└─────────────────────────┬───────────────────────────────────────┘
                          │
┌─────────────────────────▼───────────────────────────────────────┐
│                      API Gateway                                │
│  • 用户认证 (JWT/OAuth)                                         │
│  • 租户路由 (Tenant Router)                                     │
│  • 限流控制 (Rate Limiting)                                     │
│  • 计费统计 (Billing)                                           │
└─────────────────────────┬───────────────────────────────────────┘
                          │
        ┌─────────────────┼─────────────────┐
        ▼                 ▼                 ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│  Tenant A     │ │  Tenant B     │ │  Tenant C     │
│  Docker       │ │  Docker       │ │  Docker       │
│  Container    │ │  Container    │ │  Container    │
│ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │
│ │ OpenClaw  │ │ │ │ OpenClaw  │ │ │ │ OpenClaw  │ │
│ │ Gateway   │ │ │ │ Gateway   │ │ │ │ Gateway   │ │
│ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │
│ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │
│ │ Redis     │ │ │ │ Redis     │ │ │ │ Redis     │ │
│ │ (DB 1)    │ │ │ │ (DB 2)    │ │ │ │ (DB 3)    │ │
│ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
        │                 │                 │
        └─────────────────┼─────────────────┘
                          ▼
┌─────────────────────────────────────────────────────────────────┐
│                     共享数据层                                   │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐             │
│  │ PostgreSQL  │  │ S3/OSS 存储 │  │ 向量数据库   │             │
│  │ 多Schema    │  │ 用户文件    │  │ 共享/独立    │             │
│  └─────────────┘  └─────────────┘  └─────────────┘             │
└─────────────────────────────────────────────────────────────────┘

核心代码实现

# tenant_manager.py
import docker
import redis
import json
from datetime import datetime

class TenantManager:
    def __init__(self):
        self.docker_client = docker.from_env()
        self.redis_client = redis.Redis(host='localhost', port=6379)
        
    def create_tenant(self, user_id: str, plan: str = "basic"):
        """为用户创建独立 OpenClaw 实例"""
        
        # 1. 分配资源配额
        resource_limits = {
            "basic": {"cpu": 1, "memory": "1g"},
            "pro": {"cpu": 2, "memory": "2g"},
            "enterprise": {"cpu": 4, "memory": "4g"}
        }
        
        limits = resource_limits.get(plan, resource_limits["basic"])
        
        # 2. 创建 Docker 容器
        container = self.docker_client.containers.run(
            image="openclaw/openclaw:latest",
            name=f"openclaw-{user_id}",
            detach=True,
            environment={
                "TENANT_ID": user_id,
                "API_KEY": self._generate_api_key(user_id),
                "REDIS_DB": self._allocate_redis_db(user_id),
                "MODEL_PROVIDER": "kimi",  # 或 miniMax
            },
            volumes={
                f"/data/{user_id}": {"bind": "/root/.openclaw/workspace", "mode": "rw"}
            },
            nano_cpus=int(limits["cpu"]) * 1000000000,
            mem_limit=limits["memory"],
            network="openclaw-network",
            labels={
                "tenant": user_id,
                "plan": plan,
                "created_at": datetime.now().isoformat()
            }
        )
        
        # 3. 初始化租户数据库 Schema
        self._init_tenant_schema(user_id)
        
        # 4. 配置网关路由
        self._configure_gateway(user_id, container.id)
        
        return {
            "container_id": container.id,
            "endpoint": f"https://{user_id}.kamiclaw.com",
            "api_key": self._generate_api_key(user_id)
        }
    
    def _allocate_redis_db(self, user_id: str) -> int:
        """分配独立的 Redis 数据库"""
        # Redis 支持 0-15 共 16 个数据库
        # 或使用 key 前缀隔离
        db_id = hash(user_id) % 16
        return db_id
    
    def _init_tenant_schema(self, user_id: str):
        """初始化租户数据库 Schema"""
        # PostgreSQL 多 Schema 隔离
        sql = f"""
        CREATE SCHEMA IF NOT EXISTS tenant_{user_id};
        GRANT ALL ON SCHEMA tenant_{user_id} TO openclaw_user;
        """
        # 执行 SQL...
        
    def _configure_gateway(self, user_id: str, container_id: str):
        """配置 API 网关路由"""
        config = {
            "tenant_id": user_id,
            "container_id": container_id,
            "endpoint": f"/api/v1/tenant/{user_id}",
            "backend": f"http://{container_id[:12]}:18789"
        }
        # 更新 Nginx/Kong 配置...
        
    def delete_tenant(self, user_id: str):
        """删除租户实例"""
        # 停止并删除容器
        try:
            container = self.docker_client.containers.get(f"openclaw-{user_id}")
            container.stop()
            container.remove()
        except:
            pass
        
        # 清理数据
        # ...

Docker Compose 模板

# docker-compose.tenant.yml
version: '3.8'

x-openclaw-base: &openclaw-base
  image: openclaw/openclaw:2026.2.17
  restart: unless-stopped
  networks:
    - openclaw-network
  environment: &env-base
    - LOG_LEVEL=info
    - ENABLE_SANDBOX=true

services:
  # 租户 A
  openclaw-tenant-a:
    <<: *openclaw-base
    container_name: openclaw-user-12345
    environment:
      <<: *env-base
      - TENANT_ID=user-12345
      - API_KEY=${TENANT_A_API_KEY}
      - MODEL_PROVIDER=kimi
      - REDIS_URL=redis://redis:6379/1
    volumes:
      - ./data/user-12345:/root/.openclaw/workspace
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1G
    labels:
      - "tenant=user-12345"
      - "plan=basic"

  # 租户 B
  openclaw-tenant-b:
    <<: *openclaw-base
    container_name: openclaw-user-67890
    environment:
      <<: *env-base
      - TENANT_ID=user-67890
      - API_KEY=${TENANT_B_API_KEY}
      - MODEL_PROVIDER=minimax
      - REDIS_URL=redis://redis:6379/2
    volumes:
      - ./data/user-67890:/root/.openclaw/workspace
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
    labels:
      - "tenant=user-67890"
      - "plan=pro"

  # 共享 Redis
  redis:
    image: redis:7-alpine
    networks:
      - openclaw-network
    command: redis-server --databases 16

  # 共享 PostgreSQL
  postgres:
    image: pgvector/pgvector:pg16
    networks:
      - openclaw-network
    environment:
      - POSTGRES_DB=openclaw
      - POSTGRES_USER=openclaw
      - POSTGRES_PASSWORD=${DB_PASSWORD}

networks:
  openclaw-network:
    driver: bridge

四、Kubernetes 多租户方案(大规模)

架构图

┌─────────────────────────────────────────────────────────────────┐
│                     Kubernetes Cluster                          │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                    Ingress Controller                    │   │
│  │         tenant-a.kamiclaw.com → Service A               │   │
│  │         tenant-b.kamiclaw.com → Service B               │   │
│  └─────────────────────────────────────────────────────────┘   │
│                              │                                  │
│  ┌───────────────────────────┼───────────────────────────┐     │
│  │                     Namespace: tenant-a               │     │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │     │
│  │  │  OpenClaw   │  │   Redis     │  │  Postgres   │   │     │
│  │  │   Pod       │  │   Pod       │  │   Pod       │   │     │
│  │  └─────────────┘  └─────────────┘  └─────────────┘   │     │
│  │  ResourceQuota: cpu=1, memory=1Gi                     │     │
│  └───────────────────────────────────────────────────────┘     │
│                              │                                  │
│  ┌───────────────────────────┼───────────────────────────┐     │
│  │                     Namespace: tenant-b               │     │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐   │     │
│  │  │  OpenClaw   │  │   Redis     │  │  Postgres   │   │     │
│  │  │   Pod       │  │   Pod       │  │   Pod       │   │     │
│  │  └─────────────┘  └─────────────┘  └─────────────┘   │     │
│  │  ResourceQuota: cpu=2, memory=2Gi                     │     │
│  └───────────────────────────────────────────────────────┘     │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                  Shared Components                      │   │
│  │  • Model API Gateway (调用 Kimi/MiniMax API)            │   │
│  │  • Skill Registry (共享 Skill 库)                       │   │
│  │  • Monitoring (Prometheus + Grafana)                    │   │
│  └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

Kubernetes 部署模板

# tenant-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: tenant-user-12345
  labels:
    tenant: user-12345
    plan: basic

---
# tenant-resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-quota
  namespace: tenant-user-12345
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
    persistentvolumeclaims: "5"

---
# tenant-openclaw-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: openclaw
  namespace: tenant-user-12345
spec:
  replicas: 1
  selector:
    matchLabels:
      app: openclaw
  template:
    metadata:
      labels:
        app: openclaw
        tenant: user-12345
    spec:
      containers:
      - name: openclaw
        image: openclaw/openclaw:2026.2.17
        ports:
        - containerPort: 18789
        env:
        - name: TENANT_ID
          value: "user-12345"
        - name: API_KEY
          valueFrom:
            secretKeyRef:
              name: tenant-secrets
              key: api-key
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
          limits:
            cpu: "1"
            memory: "1Gi"
        volumeMounts:
        - name: workspace
          mountPath: /root/.openclaw/workspace
      volumes:
      - name: workspace
        persistentVolumeClaim:
          claimName: tenant-pvc

---
# tenant-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: openclaw
  namespace: tenant-user-12345
spec:
  selector:
    app: openclaw
  ports:
  - port: 18789
    targetPort: 18789

---
# tenant-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: openclaw-ingress
  namespace: tenant-user-12345
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: user-12345.kamiclaw.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: openclaw
            port:
              number: 18789

自动化部署脚本

# k8s_tenant_provisioner.py
from kubernetes import client, config
import yaml
import hashlib

class K8sTenantProvisioner:
    def __init__(self):
        config.load_kube_config()
        self.api = client.CustomObjectsApi()
        self.core_v1 = client.CoreV1Api()
        self.apps_v1 = client.AppsV1Api()
        
    def provision_tenant(self, user_id: str, plan: str = "basic"):
        """一键创建租户环境"""
        
        namespace = f"tenant-{user_id}"
        
        # 1. 创建 Namespace
        self._create_namespace(namespace, user_id, plan)
        
        # 2. 创建 ResourceQuota
        self._create_resource_quota(namespace, plan)
        
        # 3. 创建 Secrets
        self._create_secrets(namespace, user_id)
        
        # 4. 创建 PVC
        self._create_pvc(namespace, user_id)
        
        # 5. 创建 Deployment
        self._create_deployment(namespace, user_id, plan)
        
        # 6. 创建 Service
        self._create_service(namespace)
        
        # 7. 创建 Ingress
        self._create_ingress(namespace, user_id)
        
        return {
            "namespace": namespace,
            "endpoint": f"https://{user_id}.kamiclaw.com"
        }
    
    def _create_namespace(self, name, user_id, plan):
        namespace = client.V1Namespace(
            metadata=client.V1ObjectMeta(
                name=name,
                labels={
                    "tenant": user_id,
                    "plan": plan
                }
            )
        )
        self.core_v1.create_namespace(namespace)
    
    def _create_resource_quota(self, namespace, plan):
        quotas = {
            "basic": {"cpu": "1", "memory": "1Gi"},
            "pro": {"cpu": "2", "memory": "2Gi"},
            "enterprise": {"cpu": "4", "memory": "4Gi"}
        }
        quota = quotas.get(plan, quotas["basic"])
        
        # ... 创建 ResourceQuota

五、共享实例 + 数据隔离方案(低成本)

适用场景

  • 成本敏感型产品
  • 用户量大但活跃度低
  • 快速 MVP 验证

架构设计

┌─────────────────────────────────────────────────────────────────┐
│                      单一 OpenClaw 实例                          │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                    Tenant Router                         │   │
│  │   根据 Tenant-ID 路由到不同的数据空间                      │   │
│  └─────────────────────────────────────────────────────────┘   │
│                              │                                  │
│  ┌───────────────────────────┼───────────────────────────┐     │
│  │                     数据隔离层                          │     │
│  │                                                          │     │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐      │     │
│  │  │Tenant A │ │Tenant B │ │Tenant C │ │Tenant D │      │     │
│  │  │Data     │ │Data     │ │Data     │ │Data     │      │     │
│  │  │Prefix:  │ │Prefix:  │ │Prefix:  │ │Prefix:  │      │     │
│  │  │ta_      │ │tb_      │ │tc_      │ │td_      │      │     │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────┘      │     │
│  │                                                          │     │
│  │  Redis: Key 前缀隔离                                     │     │
│  │  PostgreSQL: 多 Schema 或 行级隔离                       │     │
│  │  文件存储: 目录隔离                                       │     │
│  └──────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

配置示例

# ~/.openclaw/openclaw.json
{
  "multiTenant": {
    "enabled": true,
    "isolation": "prefix"
  },
  "dataIsolation": {
    "redis": {
      "mode": "prefix",
      "keyPrefix": "${TENANT_ID}_"
    },
    "postgres": {
      "mode": "schema",
      "schemaPrefix": "tenant_"
    },
    "storage": {
      "mode": "directory",
      "basePath": "/data/${TENANT_ID}"
    }
  }
}

六、成本分析

各方案成本对比(按1000用户计算)

方案单用户成本/月1000用户总成本隔离级别扩展性
Docker 容器¥50-200¥50,000-200,000★★★★★★★★★
K8s 多租户¥30-100¥30,000-100,000★★★★★★★★★★
共享实例¥5-20¥5,000-20,000★★★★★
Serverless按调用量按需计费★★★★★★★★★

推荐方案

用户规模推荐方案预估成本
< 100 用户Docker 容器¥5,000-20,000/月
100-1000 用户K8s 多租户¥30,000-100,000/月
1000+ 用户K8s + 共享组件¥100,000+/月

七、安全隔离要点

必须实现的安全措施

# 安全配置清单
security:
  # 1. 网络隔离
  network:
    - 每个租户独立网络命名空间
    - 禁止租户间直接通信
    - 仅允许通过 API Gateway 访问
    
  # 2. 数据隔离
  data:
    - Redis: 独立数据库或 Key 前缀
    - PostgreSQL: 独立 Schema 或行级安全
    - 文件存储: 独立目录 + 权限控制
    
  # 3. 资源限制
  resources:
    - CPU/Memory 限制(防止资源耗尽)
    - 磁盘配额限制
    - API 调用频率限制
    
  # 4. 凭证管理
  credentials:
    - 每个租户独立 API Key
    - 不共享模型 API Key(或使用代理层)
    - 定期轮换凭证
    
  # 5. 审计日志
  audit:
    - 记录所有租户操作
    - 跨租户访问检测
    - 异常行为告警

八、厂商实现推测

KimiClaw 可能的实现

用户注册 → 分配 Docker 容器 → Kimi API 配置 → 独立域名
     │
     ├── 30秒内完成
     ├── 使用 Kimi 模型 API
     ├── 阿里云/腾讯云托管
     └── 按月订阅收费

MaxClaw 可能的实现

企业注册 → K8s Namespace → MiniMax API → 企业级功能
     │
     ├── 支持 SSO 集成
     ├── 私有化部署选项
     ├── 企业级 SLA
     └── 按坐席/调用量收费

九、快速启动建议

如果你想自己做类似产品

最小 MVP(1周内上线)

  1. 使用 Docker 容器隔离方案
  2. 阿里云/腾讯云轻量服务器
  3. 单机部署 50-100 个租户
  4. 使用现有 OpenClaw 镜像
  5. 简单的租户路由 Nginx 配置

商业版本(1个月内上线)

  1. Kubernetes 多租户方案
  2. 云厂商托管 K8s(ACK/TKE)
  3. 自动化租户开通系统
  4. 计费系统对接
  5. 监控告警体系

十、参考资源


评论