318 lines
8.6 KiB
Bash
Executable File
318 lines
8.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
##############################################################################
|
|
# Agent Manager - Kubernetes 部署脚本 (ARM64 架构)
|
|
# 用途: 自动构建 Docker 镜像并部署到 Kubernetes
|
|
##############################################################################
|
|
|
|
set -e # 遇到错误立即退出
|
|
|
|
# 颜色输出
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# 配置变量
|
|
ACR_NAME="agnettaiji"
|
|
ACR_LOGIN_SERVER="${ACR_NAME}.azurecr.io"
|
|
IMAGE_NAME="agent-manager"
|
|
IMAGE_TAG="latest-arm64"
|
|
FULL_IMAGE_NAME="${ACR_LOGIN_SERVER}/${IMAGE_NAME}:${IMAGE_TAG}"
|
|
NAMESPACE="agent-manager"
|
|
K8S_DIR="./k8s"
|
|
|
|
# Azure 凭据配置(需要替换为实际值)
|
|
AZURE_TENANT_ID="${AZURE_TENANT_ID:-your-tenant-id}"
|
|
AZURE_CLIENT_ID="${AZURE_CLIENT_ID:-your-client-id}"
|
|
AZURE_CLIENT_SECRET="${AZURE_CLIENT_SECRET:-your-client-secret}"
|
|
AZURE_SUBSCRIPTION_ID="${AZURE_SUBSCRIPTION_ID:-your-subscription-id}"
|
|
AZURE_RESOURCE_GROUP="${AZURE_RESOURCE_GROUP:-your-resource-group}"
|
|
|
|
echo -e "${BLUE}========================================${NC}"
|
|
echo -e "${BLUE} Agent Manager K8s 部署 (ARM64)${NC}"
|
|
echo -e "${BLUE}========================================${NC}"
|
|
|
|
# 函数: 打印步骤
|
|
print_step() {
|
|
echo -e "\n${GREEN}==>${NC} ${BLUE}$1${NC}"
|
|
}
|
|
|
|
# 函数: 打印错误
|
|
print_error() {
|
|
echo -e "${RED}❌ 错误: $1${NC}"
|
|
}
|
|
|
|
# 函数: 打印成功
|
|
print_success() {
|
|
echo -e "${GREEN}✅ $1${NC}"
|
|
}
|
|
|
|
# 函数: 打印警告
|
|
print_warning() {
|
|
echo -e "${YELLOW}⚠️ $1${NC}"
|
|
}
|
|
|
|
# 检查必要的命令
|
|
check_prerequisites() {
|
|
print_step "检查必要的工具..."
|
|
|
|
local tools=("docker" "kubectl" "az")
|
|
for tool in "${tools[@]}"; do
|
|
if ! command -v $tool &> /dev/null; then
|
|
print_error "$tool 未安装,请先安装"
|
|
exit 1
|
|
fi
|
|
print_success "$tool 已安装"
|
|
done
|
|
}
|
|
|
|
# 登录 Azure Container Registry
|
|
login_acr() {
|
|
print_step "登录到 Azure Container Registry..."
|
|
|
|
if az acr login --name ${ACR_NAME}; then
|
|
print_success "ACR 登录成功"
|
|
else
|
|
print_error "ACR 登录失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 构建 Docker 镜像
|
|
build_image() {
|
|
print_step "构建 ARM64 Docker 镜像..."
|
|
|
|
echo "镜像名称: ${FULL_IMAGE_NAME}"
|
|
|
|
# 使用 buildx 支持多架构构建
|
|
if ! docker buildx version &> /dev/null; then
|
|
print_warning "docker buildx 未启用,尝试启用..."
|
|
docker buildx create --use
|
|
fi
|
|
|
|
# 构建镜像
|
|
if docker buildx build \
|
|
--platform linux/arm64 \
|
|
-f Dockerfile.arm64 \
|
|
-t ${FULL_IMAGE_NAME} \
|
|
--push \
|
|
.; then
|
|
print_success "镜像构建并推送成功"
|
|
else
|
|
print_error "镜像构建失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 创建 Kubernetes 命名空间
|
|
create_namespace() {
|
|
print_step "创建 Kubernetes 命名空间..."
|
|
|
|
if kubectl get namespace ${NAMESPACE} &> /dev/null; then
|
|
print_warning "命名空间 ${NAMESPACE} 已存在"
|
|
else
|
|
kubectl apply -f ${K8S_DIR}/agent-manager-namespace.yaml
|
|
print_success "命名空间创建成功"
|
|
fi
|
|
}
|
|
|
|
# 创建 ACR Secret
|
|
create_acr_secret() {
|
|
print_step "创建 ACR 拉取凭据..."
|
|
|
|
if kubectl get secret acr-secret -n ${NAMESPACE} &> /dev/null; then
|
|
print_warning "ACR secret 已存在,删除重建"
|
|
kubectl delete secret acr-secret -n ${NAMESPACE}
|
|
fi
|
|
|
|
# 获取 ACR 凭据
|
|
ACR_USERNAME=$(az acr credential show --name ${ACR_NAME} --query username -o tsv)
|
|
ACR_PASSWORD=$(az acr credential show --name ${ACR_NAME} --query passwords[0].value -o tsv)
|
|
|
|
kubectl create secret docker-registry acr-secret \
|
|
--namespace=${NAMESPACE} \
|
|
--docker-server=${ACR_LOGIN_SERVER} \
|
|
--docker-username=${ACR_USERNAME} \
|
|
--docker-password=${ACR_PASSWORD}
|
|
|
|
print_success "ACR Secret 创建成功"
|
|
}
|
|
|
|
# 更新 ConfigMap 和 Secret
|
|
update_config() {
|
|
print_step "更新配置..."
|
|
|
|
# 检查是否需要更新 Azure 凭据
|
|
if [ "$AZURE_TENANT_ID" = "your-tenant-id" ]; then
|
|
print_warning "请在脚本中设置 Azure 凭据环境变量"
|
|
read -p "是否继续部署(不含 Azure DNS 功能)?[y/N] " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# 创建临时 secret 文件
|
|
cat > /tmp/agent-manager-secret.yaml <<EOF
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: agent-manager-secret
|
|
namespace: agent-manager
|
|
type: Opaque
|
|
stringData:
|
|
AZURE_TENANT_ID: "${AZURE_TENANT_ID}"
|
|
AZURE_CLIENT_ID: "${AZURE_CLIENT_ID}"
|
|
AZURE_CLIENT_SECRET: "${AZURE_CLIENT_SECRET}"
|
|
EOF
|
|
|
|
kubectl apply -f ${K8S_DIR}/agent-manager-configmap.yaml
|
|
kubectl apply -f /tmp/agent-manager-secret.yaml
|
|
rm -f /tmp/agent-manager-secret.yaml
|
|
|
|
print_success "配置已更新"
|
|
}
|
|
|
|
# 创建 kubeconfig Secret(如果需要)
|
|
create_kubeconfig_secret() {
|
|
print_step "创建 kubeconfig Secret..."
|
|
|
|
if [ -f ~/.kube/config ]; then
|
|
if kubectl get secret kubeconfig-secret -n ${NAMESPACE} &> /dev/null; then
|
|
print_warning "kubeconfig secret 已存在"
|
|
else
|
|
kubectl create secret generic kubeconfig-secret \
|
|
--from-file=config=/home/${USER}/.kube/config \
|
|
-n ${NAMESPACE}
|
|
print_success "kubeconfig Secret 创建成功"
|
|
fi
|
|
else
|
|
print_warning "未找到 kubeconfig 文件,跳过"
|
|
fi
|
|
}
|
|
|
|
# 部署 RBAC
|
|
deploy_rbac() {
|
|
print_step "部署 RBAC 权限..."
|
|
kubectl apply -f ${K8S_DIR}/agent-manager-rbac.yaml
|
|
print_success "RBAC 部署成功"
|
|
}
|
|
|
|
# 部署应用
|
|
deploy_app() {
|
|
print_step "部署 Agent Manager 应用..."
|
|
|
|
# 更新 Deployment 中的镜像
|
|
kubectl apply -f ${K8S_DIR}/agent-manager-deployment.yaml
|
|
kubectl apply -f ${K8S_DIR}/agent-manager-service.yaml
|
|
|
|
print_success "应用部署成功"
|
|
}
|
|
|
|
# 等待部署完成
|
|
wait_for_deployment() {
|
|
print_step "等待部署完成..."
|
|
|
|
kubectl rollout status deployment/agent-manager -n ${NAMESPACE} --timeout=300s
|
|
print_success "部署已就绪"
|
|
}
|
|
|
|
# 显示部署信息
|
|
show_deployment_info() {
|
|
print_step "部署信息:"
|
|
|
|
echo -e "\n${BLUE}Pods:${NC}"
|
|
kubectl get pods -n ${NAMESPACE} -o wide
|
|
|
|
echo -e "\n${BLUE}Services:${NC}"
|
|
kubectl get svc -n ${NAMESPACE}
|
|
|
|
echo -e "\n${BLUE}获取外网访问地址:${NC}"
|
|
EXTERNAL_IP=$(kubectl get svc agent-manager -n ${NAMESPACE} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
|
|
|
|
if [ -z "$EXTERNAL_IP" ]; then
|
|
print_warning "LoadBalancer IP 正在分配中..."
|
|
echo "运行以下命令查看 IP: kubectl get svc agent-manager -n ${NAMESPACE}"
|
|
else
|
|
print_success "外网访问地址: http://${EXTERNAL_IP}"
|
|
echo -e "\n测试访问:"
|
|
echo " curl http://${EXTERNAL_IP}/"
|
|
fi
|
|
}
|
|
|
|
# 查看日志
|
|
show_logs() {
|
|
print_step "最近的日志:"
|
|
kubectl logs -n ${NAMESPACE} -l app=agent-manager --tail=50
|
|
}
|
|
|
|
# 主函数
|
|
main() {
|
|
local skip_build=false
|
|
local skip_deploy=false
|
|
|
|
# 解析参数
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--skip-build)
|
|
skip_build=true
|
|
shift
|
|
;;
|
|
--skip-deploy)
|
|
skip_deploy=true
|
|
shift
|
|
;;
|
|
--help)
|
|
echo "用法: $0 [选项]"
|
|
echo "选项:"
|
|
echo " --skip-build 跳过镜像构建"
|
|
echo " --skip-deploy 跳过应用部署"
|
|
echo " --help 显示帮助"
|
|
exit 0
|
|
;;
|
|
*)
|
|
print_error "未知参数: $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# 执行部署
|
|
check_prerequisites
|
|
|
|
if [ "$skip_build" = false ]; then
|
|
login_acr
|
|
build_image
|
|
else
|
|
print_warning "跳过镜像构建"
|
|
fi
|
|
|
|
if [ "$skip_deploy" = false ]; then
|
|
create_namespace
|
|
create_acr_secret
|
|
update_config
|
|
create_kubeconfig_secret
|
|
deploy_rbac
|
|
deploy_app
|
|
wait_for_deployment
|
|
show_deployment_info
|
|
|
|
echo -e "\n${GREEN}========================================${NC}"
|
|
echo -e "${GREEN} 部署完成!${NC}"
|
|
echo -e "${GREEN}========================================${NC}"
|
|
|
|
read -p "是否查看日志?[y/N] " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
show_logs
|
|
fi
|
|
else
|
|
print_warning "跳过应用部署"
|
|
fi
|
|
}
|
|
|
|
# 运行主函数
|
|
main "$@"
|