forked from xiaohei/taiji-AI-PAD
318 lines
8.1 KiB
Bash
Executable File
318 lines
8.1 KiB
Bash
Executable File
#!/bin/bash
|
||
# MCP Server 部署脚本 - Azure AKS
|
||
# 用法: ./deploy-mcp-server.sh [build|deploy|all|status|logs|rollback]
|
||
|
||
set -e
|
||
|
||
# ===== 配置变量 =====
|
||
ACR_NAME="taiji"
|
||
ACR_LOGIN_SERVER="${ACR_NAME}.azurecr.io"
|
||
IMAGE_NAME="mcp-server"
|
||
IMAGE_TAG="${IMAGE_TAG:-latest}"
|
||
NAMESPACE="taiji-ai"
|
||
K8S_DIR="$(dirname "$0")"
|
||
MCP_SERVER_DIR="$(dirname "$0")/../services/mcp-server"
|
||
|
||
# ===== 颜色输出 =====
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||
|
||
# ===== 检查先决条件 =====
|
||
check_prerequisites() {
|
||
log_info "检查先决条件..."
|
||
|
||
# 检查 kubectl
|
||
if ! command -v kubectl &> /dev/null; then
|
||
log_error "kubectl 未安装"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查 az CLI
|
||
if ! command -v az &> /dev/null; then
|
||
log_error "Azure CLI 未安装"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查 docker
|
||
if ! command -v docker &> /dev/null; then
|
||
log_error "Docker 未安装"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查 kubectl 连接
|
||
if ! kubectl cluster-info &> /dev/null; then
|
||
log_error "无法连接到 Kubernetes 集群,请先运行: az aks get-credentials --resource-group <RG> --name <AKS_NAME>"
|
||
exit 1
|
||
fi
|
||
|
||
log_success "先决条件检查通过"
|
||
}
|
||
|
||
# ===== 登录 ACR =====
|
||
login_acr() {
|
||
log_info "登录 Azure Container Registry..."
|
||
az acr login --name ${ACR_NAME}
|
||
log_success "ACR 登录成功"
|
||
}
|
||
|
||
# ===== 构建镜像 =====
|
||
build_image() {
|
||
log_info "构建 Docker 镜像..."
|
||
|
||
cd "${MCP_SERVER_DIR}"
|
||
|
||
# 使用 ACR 构建(推荐)
|
||
log_info "使用 ACR Tasks 构建镜像..."
|
||
az acr build \
|
||
--registry ${ACR_NAME} \
|
||
--image ${IMAGE_NAME}:${IMAGE_TAG} \
|
||
--file Dockerfile \
|
||
.
|
||
|
||
# 也打上 latest 标签
|
||
if [ "${IMAGE_TAG}" != "latest" ]; then
|
||
az acr import \
|
||
--name ${ACR_NAME} \
|
||
--source ${ACR_LOGIN_SERVER}/${IMAGE_NAME}:${IMAGE_TAG} \
|
||
--image ${IMAGE_NAME}:latest \
|
||
--force
|
||
fi
|
||
|
||
log_success "镜像构建完成: ${ACR_LOGIN_SERVER}/${IMAGE_NAME}:${IMAGE_TAG}"
|
||
}
|
||
|
||
# ===== 本地构建镜像(备选) =====
|
||
build_image_local() {
|
||
log_info "本地构建并推送 Docker 镜像..."
|
||
|
||
cd "${MCP_SERVER_DIR}"
|
||
|
||
# 本地构建
|
||
docker build -t ${ACR_LOGIN_SERVER}/${IMAGE_NAME}:${IMAGE_TAG} .
|
||
|
||
# 推送到 ACR
|
||
docker push ${ACR_LOGIN_SERVER}/${IMAGE_NAME}:${IMAGE_TAG}
|
||
|
||
# 也打上 latest 标签
|
||
if [ "${IMAGE_TAG}" != "latest" ]; then
|
||
docker tag ${ACR_LOGIN_SERVER}/${IMAGE_NAME}:${IMAGE_TAG} ${ACR_LOGIN_SERVER}/${IMAGE_NAME}:latest
|
||
docker push ${ACR_LOGIN_SERVER}/${IMAGE_NAME}:latest
|
||
fi
|
||
|
||
log_success "镜像推送完成: ${ACR_LOGIN_SERVER}/${IMAGE_NAME}:${IMAGE_TAG}"
|
||
}
|
||
|
||
# ===== 创建命名空间 =====
|
||
create_namespace() {
|
||
log_info "创建命名空间 ${NAMESPACE}..."
|
||
kubectl apply -f "${K8S_DIR}/namespace.yaml" || true
|
||
log_success "命名空间已创建"
|
||
}
|
||
|
||
# ===== 应用配置 =====
|
||
apply_configs() {
|
||
log_info "应用 ConfigMap 和 Secrets..."
|
||
|
||
# 应用 ConfigMap
|
||
kubectl apply -f "${K8S_DIR}/configmap.yaml"
|
||
|
||
# 应用 Secrets
|
||
kubectl apply -f "${K8S_DIR}/secrets.yaml"
|
||
|
||
log_success "配置已应用"
|
||
}
|
||
|
||
# ===== 部署服务 =====
|
||
deploy_service() {
|
||
log_info "部署 MCP Server..."
|
||
|
||
# 应用部署配置
|
||
kubectl apply -f "${K8S_DIR}/mcp-server.yaml"
|
||
|
||
# 等待部署完成
|
||
log_info "等待部署完成..."
|
||
kubectl rollout status deployment/mcp-server -n ${NAMESPACE} --timeout=300s
|
||
|
||
log_success "MCP Server 部署完成"
|
||
}
|
||
|
||
# ===== 查看状态 =====
|
||
show_status() {
|
||
log_info "MCP Server 部署状态:"
|
||
echo ""
|
||
|
||
echo "=== Deployment ==="
|
||
kubectl get deployment mcp-server -n ${NAMESPACE} -o wide
|
||
echo ""
|
||
|
||
echo "=== Pods ==="
|
||
kubectl get pods -n ${NAMESPACE} -l app=mcp-server -o wide
|
||
echo ""
|
||
|
||
echo "=== Service ==="
|
||
kubectl get svc mcp-server -n ${NAMESPACE}
|
||
echo ""
|
||
|
||
echo "=== HPA ==="
|
||
kubectl get hpa mcp-server-hpa -n ${NAMESPACE} 2>/dev/null || echo "HPA 未配置"
|
||
echo ""
|
||
|
||
echo "=== Recent Events ==="
|
||
kubectl get events -n ${NAMESPACE} --field-selector involvedObject.name=mcp-server --sort-by='.lastTimestamp' | tail -10
|
||
}
|
||
|
||
# ===== 查看日志 =====
|
||
show_logs() {
|
||
log_info "MCP Server 日志 (最近 100 行):"
|
||
kubectl logs -n ${NAMESPACE} -l app=mcp-server --tail=100 -f
|
||
}
|
||
|
||
# ===== 回滚部署 =====
|
||
rollback() {
|
||
log_warn "回滚 MCP Server 部署..."
|
||
kubectl rollout undo deployment/mcp-server -n ${NAMESPACE}
|
||
kubectl rollout status deployment/mcp-server -n ${NAMESPACE} --timeout=300s
|
||
log_success "回滚完成"
|
||
}
|
||
|
||
# ===== 验证连接 =====
|
||
verify_connections() {
|
||
log_info "验证服务连接..."
|
||
|
||
# 获取一个 Pod 名称
|
||
POD_NAME=$(kubectl get pods -n ${NAMESPACE} -l app=mcp-server -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
|
||
|
||
if [ -z "$POD_NAME" ]; then
|
||
log_error "没有运行中的 Pod"
|
||
return 1
|
||
fi
|
||
|
||
log_info "使用 Pod: ${POD_NAME}"
|
||
|
||
# 检查健康状态
|
||
log_info "检查健康状态..."
|
||
kubectl exec -n ${NAMESPACE} ${POD_NAME} -- curl -s http://localhost:8000/health || log_warn "健康检查失败"
|
||
|
||
log_success "连接验证完成"
|
||
}
|
||
|
||
# ===== 打印配置信息 =====
|
||
print_config() {
|
||
echo ""
|
||
log_info "===== 当前配置 ====="
|
||
echo "ACR: ${ACR_LOGIN_SERVER}"
|
||
echo "镜像: ${IMAGE_NAME}:${IMAGE_TAG}"
|
||
echo "命名空间: ${NAMESPACE}"
|
||
echo ""
|
||
log_info "===== 关键配置(来自 ConfigMap/Secrets) ====="
|
||
echo "PostgreSQL: postgres 数据库 (生产环境)"
|
||
echo "Redis: Azure Cache for Redis (SSL, 端口 10000)"
|
||
echo "Agent Manager: http://agent-manager.agent-manager.svc.cluster.local:80"
|
||
echo "LiteLLM: https://litellm.graystone-fb459c5d.southeastasia.azurecontainerapps.io"
|
||
echo ""
|
||
}
|
||
|
||
# ===== 完整部署 =====
|
||
full_deploy() {
|
||
check_prerequisites
|
||
print_config
|
||
login_acr
|
||
build_image
|
||
create_namespace
|
||
apply_configs
|
||
deploy_service
|
||
show_status
|
||
log_success "===== MCP Server 完整部署完成 ====="
|
||
}
|
||
|
||
# ===== 仅部署(不构建) =====
|
||
deploy_only() {
|
||
check_prerequisites
|
||
print_config
|
||
create_namespace
|
||
apply_configs
|
||
deploy_service
|
||
show_status
|
||
log_success "===== MCP Server 部署完成 ====="
|
||
}
|
||
|
||
# ===== 帮助信息 =====
|
||
show_help() {
|
||
echo "MCP Server AKS 部署脚本"
|
||
echo ""
|
||
echo "用法: $0 [命令]"
|
||
echo ""
|
||
echo "命令:"
|
||
echo " build 只构建镜像并推送到 ACR"
|
||
echo " deploy 只部署服务(不构建镜像)"
|
||
echo " all 完整部署(构建 + 部署)"
|
||
echo " status 查看部署状态"
|
||
echo " logs 查看服务日志"
|
||
echo " rollback 回滚到上一版本"
|
||
echo " verify 验证服务连接"
|
||
echo " config 显示配置信息"
|
||
echo " help 显示此帮助信息"
|
||
echo ""
|
||
echo "环境变量:"
|
||
echo " IMAGE_TAG 镜像标签 (默认: latest)"
|
||
echo ""
|
||
echo "示例:"
|
||
echo " $0 all # 完整部署"
|
||
echo " IMAGE_TAG=v1.0.0 $0 all # 使用指定版本部署"
|
||
echo " $0 deploy # 只部署不构建"
|
||
echo " $0 status # 查看状态"
|
||
}
|
||
|
||
# ===== 主程序 =====
|
||
case "${1:-help}" in
|
||
build)
|
||
check_prerequisites
|
||
login_acr
|
||
build_image
|
||
;;
|
||
build-local)
|
||
check_prerequisites
|
||
login_acr
|
||
build_image_local
|
||
;;
|
||
deploy)
|
||
deploy_only
|
||
;;
|
||
all)
|
||
full_deploy
|
||
;;
|
||
status)
|
||
show_status
|
||
;;
|
||
logs)
|
||
show_logs
|
||
;;
|
||
rollback)
|
||
rollback
|
||
;;
|
||
verify)
|
||
verify_connections
|
||
;;
|
||
config)
|
||
print_config
|
||
;;
|
||
help|--help|-h)
|
||
show_help
|
||
;;
|
||
*)
|
||
log_error "未知命令: $1"
|
||
show_help
|
||
exit 1
|
||
;;
|
||
esac
|
||
|
||
|