feat: 添加 K8S 部署功能
- 新增 src/k8s-client.ts: K8S 客户端封装 - 新增 src/deploy.ts: 部署/删除/状态查询逻辑 - 新增 scripts/deploy.ts: 命令行部署工具 - 更新 .env.example: 添加 K8S 配置项 - 安装 @kubernetes/client-node@1.3.0 依赖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
173
scripts/deploy.ts
Normal file
173
scripts/deploy.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* K8S 部署命令行工具
|
||||
* 用于部署 Claude API 代理服务到 ECI
|
||||
*
|
||||
* 用法:
|
||||
* pnpm deploy <name> <image> [options] - 部署代理服务
|
||||
* pnpm deploy delete <name> - 删除代理服务
|
||||
* pnpm deploy status <name> - 查询服务状态
|
||||
*
|
||||
* 选项:
|
||||
* --replicas <n> 副本数 (默认: 1)
|
||||
* --port <port> 容器端口 (默认: 3000)
|
||||
* --eip-bandwidth <n> EIP 带宽 Mbps (默认: 5)
|
||||
*/
|
||||
|
||||
import { config } from 'dotenv';
|
||||
config();
|
||||
|
||||
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)));
|
||||
};
|
||||
|
||||
return {
|
||||
command,
|
||||
name: args[1],
|
||||
image: args[2],
|
||||
options: {
|
||||
replicas: getOptionNumber('--replicas', 1),
|
||||
port: getOptionNumber('--port', 3000),
|
||||
eipBandwidth: getOptionNumber('--eip-bandwidth', 5),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function printUsage() {
|
||||
console.log(`
|
||||
K8S 部署命令行工具 - Claude API 代理服务
|
||||
|
||||
用法:
|
||||
pnpm deploy <name> <image> [options] 部署代理服务
|
||||
pnpm deploy delete <name> 删除代理服务
|
||||
pnpm deploy status <name> 查询服务状态
|
||||
|
||||
选项:
|
||||
--replicas <n> 副本数 (默认: 1)
|
||||
--port <port> 容器端口 (默认: 3000)
|
||||
--eip-bandwidth <n> 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`);
|
||||
|
||||
const result = await deployProxy({
|
||||
name,
|
||||
image,
|
||||
replicas: options.replicas,
|
||||
port: options.port,
|
||||
eipBandwidth: options.eipBandwidth,
|
||||
});
|
||||
|
||||
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();
|
||||
Reference in New Issue
Block a user