@echo off REM Kubernetes 自动部署脚本 (Windows 版本) REM 用于从私有 Harbor 仓库拉取 NGINX 镜像并部署到 K8s 集群 setlocal EnableDelayedExpansion REM 设置颜色代码(Windows 10/11 支持 ANSI 转义序列) set "RED=[91m" set "GREEN=[92m" set "YELLOW=[93m" set "BLUE=[94m" set "NC=[0m" REM 打印带颜色的信息 :print_info echo %BLUE%[INFO]%NC% %~1 goto :eof :print_success echo %GREEN%[SUCCESS]%NC% %~1 goto :eof :print_warning echo %YELLOW%[WARNING]%NC% %~1 goto :eof :print_error echo %RED%[ERROR]%NC% %~1 goto :eof REM 检查必要的环境变量 :check_env_vars call :print_info "检查环境变量..." set "missing_vars=" if "%HARBOR_REGISTRY%"=="" set "missing_vars=%missing_vars% HARBOR_REGISTRY" if "%HARBOR_USERNAME%"=="" set "missing_vars=%missing_vars% HARBOR_USERNAME" if "%HARBOR_PASSWORD%"=="" set "missing_vars=%missing_vars% HARBOR_PASSWORD" if "%NGINX_IMAGE_TAG%"=="" set "missing_vars=%missing_vars% NGINX_IMAGE_TAG" if not "%missing_vars%"=="" ( call :print_error "缺少必要的环境变量: %missing_vars%" echo. echo 请设置以下环境变量: echo set HARBOR_REGISTRY=^<你的Harbor仓库地址^> echo set HARBOR_USERNAME=^ echo set HARBOR_PASSWORD=^ echo set NGINX_IMAGE_TAG=^<镜像标签,如: %%GITHUB_SHA%% 或 latest^> echo. echo 或者创建 .env 文件包含这些变量 exit /b 1 ) call :print_success "环境变量检查通过" goto :eof REM 检查 kubectl 连接 :check_kubectl call :print_info "检查 kubectl 连接..." kubectl version --client >nul 2>&1 if errorlevel 1 ( call :print_error "kubectl 未安装或不在 PATH 中" echo 请从 https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/ 安装 kubectl exit /b 1 ) kubectl cluster-info >nul 2>&1 if errorlevel 1 ( call :print_error "无法连接到 Kubernetes 集群" echo 请确保: echo 1. kubectl 已正确配置 echo 2. 能够访问 Kubernetes 集群 echo 3. 当前用户有适当的权限 exit /b 1 ) call :print_success "kubectl 连接正常" kubectl cluster-info --short goto :eof REM 创建命名空间(如果不存在) :create_namespace set "namespace=%~1" if "%namespace%"=="" set "namespace=default" call :print_info "检查命名空间: %namespace%" kubectl get namespace %namespace% >nul 2>&1 if errorlevel 1 ( call :print_info "创建命名空间: %namespace%" kubectl create namespace %namespace% if errorlevel 1 ( call :print_error "创建命名空间失败" exit /b 1 ) call :print_success "命名空间 '%namespace%' 创建成功" ) else ( call :print_success "命名空间 '%namespace%' 已存在" ) goto :eof REM 创建或更新 Harbor 仓库访问凭据 :create_harbor_secret set "namespace=%~1" if "%namespace%"=="" set "namespace=default" call :print_info "创建/更新 Harbor 仓库访问凭据..." REM 删除已存在的 secret(如果存在) kubectl delete secret harbor-registry-secret -n %namespace% --ignore-not-found=true >nul 2>&1 REM 创建新的 secret kubectl create secret docker-registry harbor-registry-secret --docker-server=%HARBOR_REGISTRY% --docker-username=%HARBOR_USERNAME% --docker-password=%HARBOR_PASSWORD% --namespace=%namespace% if errorlevel 1 ( call :print_error "创建 Harbor 仓库访问凭据失败" exit /b 1 ) call :print_success "Harbor 仓库访问凭据创建成功" goto :eof REM 更新部署文件中的镜像标签 :update_deployment_image set "deployment_file=%~1" set "image_tag=%~2" call :print_info "更新部署文件中的镜像标签: %image_tag%" set "full_image=%HARBOR_REGISTRY%/test/nginx:%image_tag%" REM 备份原文件 copy "%deployment_file%" "%deployment_file%.bak" >nul REM 使用 PowerShell 替换镜像标签 powershell -Command "(Get-Content '%deployment_file%') -replace '%HARBOR_REGISTRY%/test/nginx:[^\s]*', '%full_image%' | Set-Content '%deployment_file%'" if errorlevel 1 ( call :print_error "更新镜像标签失败" exit /b 1 ) call :print_success "镜像标签更新为: %full_image%" goto :eof REM 应用 Kubernetes 配置 :apply_k8s_config set "deployment_file=%~1" call :print_info "应用 Kubernetes 配置..." if not exist "%deployment_file%" ( call :print_error "部署文件不存在: %deployment_file%" exit /b 1 ) kubectl apply -f "%deployment_file%" if errorlevel 1 ( call :print_error "应用 Kubernetes 配置失败" exit /b 1 ) call :print_success "Kubernetes 配置应用成功" goto :eof REM 等待部署就绪 :wait_for_deployment set "deployment_name=nginx-deployment" set "namespace=%~1" set "timeout=%~2" if "%namespace%"=="" set "namespace=default" if "%timeout%"=="" set "timeout=300" call :print_info "等待部署就绪..." kubectl wait --for=condition=available deployment/%deployment_name% --namespace=%namespace% --timeout=%timeout%s if errorlevel 1 ( call :print_error "部署超时,请检查部署状态" kubectl describe deployment %deployment_name% -n %namespace% exit /b 1 ) call :print_success "部署已就绪" goto :eof REM 显示部署状态 :show_deployment_status set "namespace=%~1" if "%namespace%"=="" set "namespace=default" call :print_info "部署状态:" echo. echo === Pods === kubectl get pods -l app=nginx -n %namespace% -o wide echo. echo === Services === kubectl get services -l app=nginx -n %namespace% echo. echo === Deployments === kubectl get deployments -l app=nginx -n %namespace% echo. echo === HPA === kubectl get hpa -l app=nginx -n %namespace% 2>nul || echo HPA 未启用 echo. echo === Events === kubectl get events --sort-by=.metadata.creationTimestamp -n %namespace% | findstr /C:"nginx" goto :eof REM 获取访问信息 :get_access_info set "namespace=%~1" if "%namespace%"=="" set "namespace=default" call :print_info "获取访问信息..." for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.spec.type}"') do set "service_type=%%i" if "%service_type%"=="NodePort" ( for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.spec.ports[0].nodePort}"') do set "node_port=%%i" for /f "tokens=*" %%i in ('kubectl get nodes -o jsonpath^="{.items[0].status.addresses[?(@.type==\"InternalIP\")].address}"') do set "node_ip=%%i" call :print_success "NodePort 访问地址: http://!node_ip!:!node_port!" ) else if "%service_type%"=="LoadBalancer" ( call :print_info "等待 LoadBalancer 外部 IP..." for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.status.loadBalancer.ingress[0].ip}" 2^>nul') do set "external_ip=%%i" if not "!external_ip!"=="" ( call :print_success "LoadBalancer 访问地址: http://!external_ip!" ) else ( call :print_warning "LoadBalancer 外部 IP 仍在分配中" ) ) else if "%service_type%"=="ClusterIP" ( for /f "tokens=*" %%i in ('kubectl get service nginx-service -n %namespace% -o jsonpath^="{.spec.clusterIP}"') do set "cluster_ip=%%i" call :print_success "ClusterIP 访问地址: http://!cluster_ip!" call :print_info "注意: ClusterIP 只能在集群内部访问" ) goto :eof REM 清理函数 :cleanup call :print_info "执行清理操作..." if exist ".\nginx-deployment.yaml.bak" ( move ".\nginx-deployment.yaml.bak" ".\nginx-deployment.yaml" >nul ) goto :eof REM 主函数 :main call :print_info "开始 NGINX Kubernetes 自动部署..." REM 设置默认值 if "%NAMESPACE%"=="" set "NAMESPACE=default" if "%DEPLOYMENT_FILE%"=="" set "DEPLOYMENT_FILE=.\nginx-deployment.yaml" if "%NGINX_IMAGE_TAG%"=="" set "NGINX_IMAGE_TAG=latest" REM 检查是否有 .env 文件 if exist ".env" ( call :print_info "加载 .env 文件..." for /f "usebackq tokens=1,2 delims==" %%a in (".env") do ( set "%%a=%%b" ) ) REM 执行部署步骤 call :check_env_vars if errorlevel 1 exit /b 1 call :check_kubectl if errorlevel 1 exit /b 1 call :create_namespace "%NAMESPACE%" if errorlevel 1 exit /b 1 call :create_harbor_secret "%NAMESPACE%" if errorlevel 1 exit /b 1 call :update_deployment_image "%DEPLOYMENT_FILE%" "%NGINX_IMAGE_TAG%" if errorlevel 1 exit /b 1 call :apply_k8s_config "%DEPLOYMENT_FILE%" if errorlevel 1 exit /b 1 call :wait_for_deployment "%NAMESPACE%" if errorlevel 1 exit /b 1 call :show_deployment_status "%NAMESPACE%" call :get_access_info "%NAMESPACE%" call :print_success "🎉 NGINX 部署完成!" goto :eof REM 如果直接运行此脚本,执行主函数 call :main call :cleanup