#!/usr/bin/env node /** * K8S 部署命令行工具 * 用于部署 Claude API 代理服务到 ECI * * 用法: * pnpm deploy [options] - 部署代理服务 * pnpm deploy delete - 删除代理服务 * pnpm deploy status - 查询服务状态 * * 选项: * --replicas 副本数 (默认: 1) * --port 容器端口 (默认: 3000) * --eip-bandwidth EIP 带宽 Mbps (默认: 5) */ import { config } from 'dotenv'; // 使用 override: true 确保覆盖系统环境变量 config({ override: true }); import { deployProxy, deleteProxy, getProxyStatus } from '../src/deploy'; // 解析命令行参数 function parseArgs() { const args = process.argv.slice(2); if (args.length === 0) { printUsage(); process.exit(1); } const command = args[0]; // 解析选项 const getOption = (name: string, defaultValue: string): string => { const idx = args.indexOf(name); if (idx !== -1 && idx + 1 < args.length) { return args[idx + 1]; } return defaultValue; }; const getOptionNumber = (name: string, defaultValue: number): number => { return Number(getOption(name, String(defaultValue))); }; // 判断是否是子命令模式 const isSubCommand = command === 'delete' || command === 'status'; return { command, name: isSubCommand ? args[1] : command, image: isSubCommand ? undefined : args[1], options: { replicas: getOptionNumber('--replicas', 1), port: getOptionNumber('--port', 3000), eipBandwidth: getOptionNumber('--eip-bandwidth', 5), }, }; } function printUsage() { console.log(` K8S 部署命令行工具 - Claude API 代理服务 用法: pnpm deploy [options] 部署代理服务 pnpm deploy delete 删除代理服务 pnpm deploy status 查询服务状态 选项: --replicas 副本数 (默认: 1) --port 容器端口 (默认: 3000) --eip-bandwidth EIP 带宽 Mbps (默认: 5) 示例: # 部署单个代理实例 pnpm deploy claude-proxy-1 registry.cn-beijing.aliyuncs.com/d8dcloud/claude-api-proxy:v0.0.1 # 部署 3 个副本 pnpm deploy claude-proxy-1 registry.cn-beijing.aliyuncs.com/d8dcloud/claude-api-proxy:v0.0.1 --replicas 3 # 删除服务 pnpm deploy delete claude-proxy-1 # 查询状态 pnpm deploy status claude-proxy-1 `); } async function main() { const { command, name, image, options } = parseArgs(); // 检查环境变量 if (!process.env.K8S_API_URL || !process.env.K8S_API_TOKEN) { console.error('❌ 错误: 请配置 K8S_API_URL 和 K8S_API_TOKEN 环境变量'); console.error(' 可以在 .env 文件中配置或通过环境变量传入'); process.exit(1); } try { switch (command) { case 'delete': { if (!name) { console.error('❌ 错误: 请指定服务名称'); process.exit(1); } console.log(`🗑️ 正在删除服务 ${name}...`); const result = await deleteProxy(name); if (result.success) { console.log(`✅ ${result.message}`); } else { console.error(`❌ ${result.message}`); process.exit(1); } break; } case 'status': { if (!name) { console.error('❌ 错误: 请指定服务名称'); process.exit(1); } console.log(`📊 查询服务状态 ${name}...`); const status = await getProxyStatus(name); if (status.exists) { console.log(`✅ 服务状态: ${status.status}`); if (status.hosts && status.hosts.length > 0) { console.log(`🌐 访问地址: ${status.hosts.join(', ')}`); } } else { console.log(`⚠️ 服务 ${name} 不存在`); } break; } default: { // deploy 命令 if (!name || !image) { console.error('❌ 错误: 请指定服务名称和镜像'); process.exit(1); } console.log(`🚀 正在部署 ${name}...`); console.log(` 镜像: ${image}`); console.log(` 副本: ${options.replicas}`); console.log(` 端口: ${options.port}`); console.log(` EIP 带宽: ${options.eipBandwidth} Mbps`); // 构建环境变量 - 从当前 .env 读取关键配置注入容器 const containerEnv: Record = { ANTHROPIC_BASE_URL: process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com', }; const result = await deployProxy({ name, image, replicas: options.replicas, port: options.port, eipBandwidth: options.eipBandwidth, env: containerEnv, }); if (result.success) { console.log(`\n✅ ${result.message}`); if (result.hosts && result.hosts.length > 0) { console.log(`\n🌐 访问地址:`); result.hosts.forEach(host => console.log(` ${host}`)); } } else { console.error(`\n❌ ${result.message}`); process.exit(1); } break; } } } catch (error) { console.error('❌ 执行失败:', error instanceof Error ? error.message : error); process.exit(1); } } main();