部署实践:Docker Compose 与 Kubernetes

介绍 go-ai-scheduler 的部署方案,包括 Docker Compose 全栈启动、Kubernetes 多副本部署与配置管理最佳实践。

部署模式概览

go-ai-scheduler 支持三种部署模式:

模式适用场景复杂度
Docker Compose开发、测试、小规模生产
Kubernetes大规模生产、需要自动扩缩容
二进制直接运行快速验证、调试最低

Docker Compose 部署

全栈启动

docker compose -f deployments/docker-compose/docker-compose.yml up -d

启动的服务包括:

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: scheduler
      MYSQL_DATABASE: scheduler
    ports:
      - "3306:3306"

  redis:
    image: redis:7
    ports:
      - "6379:6379"

  etcd:
    image: etcd:3.5
    ports:
      - "2379:2379"

  scheduler:
    build: .
    command: /app/scheduler
    environment:
      MYSQL_DSN: "root:scheduler@tcp(mysql:3306)/scheduler"
      REDIS_ADDR: "redis:6379"
      ETCD_ENDPOINTS: "etcd:2379"
    depends_on:
      - mysql
      - redis
      - etcd

  worker:
    build: .
    command: /app/worker
    environment:
      SCHEDULER_URL: "http://scheduler:8081"
    depends_on:
      - scheduler

  api:
    build: .
    command: /app/api
    ports:
      - "8082:8082"
    environment:
      MYSQL_DSN: "root:scheduler@tcp(mysql:3306)/scheduler"
      AI_SERVICE_URL: "http://ai-service:8083"
    depends_on:
      - mysql
      - scheduler

  ai-service:
    build: .
    command: /app/ai-service
    environment:
      LLM_ENDPOINT: "https://api.openai.com/v1"
      LLM_API_KEY: "${OPENAI_API_KEY}"
      LLM_MODEL: "gpt-4o"

配置说明

  • MySQL:必需,所有持久化数据存储在此
  • Redis:可选,启用缓存和 Worker 状态加速
  • etcd:可选,启用分布式 Leader 选举
  • AI Service:可选,启用 AI 辅助能力

去掉可选组件后,最小部署只需 MySQL + Scheduler + Worker + API。

Kubernetes 部署

架构

Namespace: go-ai-scheduler
├── Deployment: api (replicas: 2-8, HPA)
├── Deployment: scheduler (replicas: 3, 仅 1 个 Leader 工作)
├── Deployment: worker (replicas: 3-10, HPA)
├── Deployment: ai-service (replicas: 2-6, HPA)
├── Service: api (ClusterIP + NodePort/LoadBalancer)
├── Service: scheduler (ClusterIP)
├── Secret: ai-service-llm (LLM API Key)
├── ConfigMap: scheduler-config
└── Ingress: api (可选)

HPA 配置

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 2
  maxReplicas: 8
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: ai-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: ai-service
  minReplicas: 2
  maxReplicas: 6
  metrics:
    - type: Pods
      pods:
        metric:
          name: ai_requests_per_second
        target:
          type: AverageValue
          averageValue: "10"

LLM 密钥管理

# 创建 Secret
kubectl create secret generic ai-service-llm \
  --from-literal=LLM_API_KEY="sk-xxx" \
  --from-literal=LLM_FALLBACK_API_KEY="sk-yyy"
# Deployment 中引用
spec:
  containers:
    - name: ai-service
      envFrom:
        - secretRef:
            name: ai-service-llm

配置管理

环境变量

变量默认值说明
REPO_BACKEND设为 mysql
MYSQL_DSNMySQL 连接串
REDIS_ADDRRedis 地址(可选)
ETCD_ENDPOINTSetcd 集群地址(可选)
LLM_ENDPOINTOpenAI-compatible API 基地址
LLM_API_KEYAPI Key
LLM_MODELgpt-4o模型名
AI_RATE_LIMIT_RPM0LLM 请求速率限制(请求/分钟)
SCHEDULER_URLhttp://127.0.0.1:8081Worker/API → Scheduler 地址
LOG_LEVELinfo日志级别

配置加载优先级

1. 环境变量(最高优先级)
2. 配置文件(.env 文件)
3. 默认值
func Load() *Config {
    cfg := &Config{}
    // 从环境变量读取
    if dsn := os.Getenv("MYSQL_DSN"); dsn != "" {
        cfg.MySQLDSN = dsn
    }
    // 从 .env 文件读取(如果环境变量未设置)
    godotenv.Load(".env")
    // 应用默认值
    if cfg.LogLevel == "" {
        cfg.LogLevel = "info"
    }
    return cfg
}

数据库迁移

# 自动迁移(启动时执行)
go run ./cmd/migrate

# 或 Docker 中
 docker run go-ai-scheduler /app/migrate

迁移文件位于 migrations/ 目录:

migrations/
├── 000001_init.sql              # 初始表结构
├── 000002_add_retry_fields.sql  # 重试相关字段
├── 000003_add_task_labels.sql   # 任务标签
├── 000004_add_task_dependency.sql # 任务依赖
├── 000005_add_task_image.sql    # 容器镜像字段
├── 000006_fix_error_message_size.sql
├── 000007_add_instance_analysis.sql # AI 分析结果
├── 000008_add_ai_conversation.sql   # AI 会话
├── 000009_add_execution_timestamps.sql
└── 000010_add_worker_load_snapshot.sql

生产环境建议

1. MySQL 高可用

  • 使用主从复制或 MySQL Group Replication
  • Scheduler 连接主库(读写)
  • Worker 心跳和查询可连接从库(只读)

2. Redis 可选但推荐

  • 启用 Redis 后,Scheduler 启动更快(缓存到期任务)
  • Worker 负载查询更快
  • AI 查询结果可缓存

3. Scheduler 副本数

  • 至少 2 个副本,保证 Leader 故障时快速切换
  • 3 个副本是推荐配置
  • 副本越多,Leader 选举竞争越激烈

4. Worker 资源规划

  • Shell 任务密集的 Worker:CPU 要求高
  • Container 任务密集的 Worker:磁盘和网络要求高
  • 按任务类型分组 Worker,配合 Label 路由

5. 监控告警

  • 部署 Prometheus + Grafana
  • 导入项目内置 Dashboard
  • 配置关键指标告警(pending 数、失败率、Worker 离线)

小结

go-ai-scheduler 的部署设计遵循几个原则:

  1. 单二进制:每个服务一个 Go 二进制,容器镜像统一
  2. 渐进式依赖:从最小部署(MySQL only)到全功能部署(+ Redis + etcd + AI)
  3. 配置即代码:环境变量 + ConfigMap + Secret,不依赖配置文件
  4. 云原生:支持 Docker Compose 和 Kubernetes,内置 HPA
  5. 数据库迁移内置:启动时自动执行,无需手动操作

无论是开发环境的一条 docker compose up,还是生产环境的 Kubernetes 集群,go-ai-scheduler 都能快速部署并运行。