# Nomad Windows 设置脚本 # 用于将 Windows 笔记本加入 Nomad 集群作为 server param( [string]$NomadVersion = "1.10.5", [string]$DataCenter = "dc1", [string]$EncryptKey = "NVOMDvXblgWfhtzFzOUIHnKEOrbXOkPrkIPbRGGf1YQ=" ) # 需要管理员权限 if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Host "❌ 此脚本需要管理员权限运行" -ForegroundColor Red Write-Host "请以管理员身份运行 PowerShell" -ForegroundColor Yellow exit 1 } Write-Host "🚀 开始设置 Windows Nomad Server..." -ForegroundColor Green # 1. 检查 Tailscale Write-Host "📡 检查 Tailscale 连接..." -ForegroundColor Cyan try { $tailscaleIP = (tailscale ip) | Select-Object -First 1 if ([string]::IsNullOrEmpty($tailscaleIP)) { throw "Tailscale IP 为空" } Write-Host "✅ Tailscale IP: $tailscaleIP" -ForegroundColor Green } catch { Write-Host "❌ Tailscale 未安装或未连接" -ForegroundColor Red Write-Host "请先安装 Tailscale 并运行: tailscale up" -ForegroundColor Yellow exit 1 } # 2. 创建目录 Write-Host "📁 创建 Nomad 目录..." -ForegroundColor Cyan $nomadDir = "C:\nomad" $configDir = "$nomadDir\config" $dataDir = "$nomadDir\data" $binDir = "$nomadDir\bin" New-Item -ItemType Directory -Force -Path $configDir | Out-Null New-Item -ItemType Directory -Force -Path $dataDir | Out-Null New-Item -ItemType Directory -Force -Path $binDir | Out-Null # 3. 下载 Nomad(如果需要) $nomadExe = "$binDir\nomad.exe" if (-not (Test-Path $nomadExe)) { Write-Host "📦 下载 Nomad $NomadVersion..." -ForegroundColor Cyan $nomadUrl = "https://releases.hashicorp.com/nomad/$NomadVersion/nomad_${NomadVersion}_windows_amd64.zip" $zipPath = "$env:TEMP\nomad.zip" try { Invoke-WebRequest -Uri $nomadUrl -OutFile $zipPath Expand-Archive -Path $zipPath -DestinationPath $binDir -Force Remove-Item $zipPath Write-Host "✅ Nomad 下载完成" -ForegroundColor Green } catch { Write-Host "❌ 下载 Nomad 失败: $_" -ForegroundColor Red exit 1 } } # 4. 添加到 PATH(如果需要) $currentPath = [Environment]::GetEnvironmentVariable("PATH", "Machine") if ($currentPath -notlike "*$binDir*") { Write-Host "🔧 添加 Nomad 到系统 PATH..." -ForegroundColor Cyan [Environment]::SetEnvironmentVariable("PATH", "$currentPath;$binDir", "Machine") $env:PATH += ";$binDir" } # 5. 生成配置文件 Write-Host "⚙️ 生成 Nomad 配置..." -ForegroundColor Cyan $configContent = @" datacenter = "$DataCenter" data_dir = "$($dataDir -replace '\\', '/')" log_level = "INFO" bind_addr = "$tailscaleIP" addresses { http = "0.0.0.0" rpc = "$tailscaleIP" serf = "$tailscaleIP" } ports { http = 4646 rpc = 4647 serf = 4648 } server { enabled = true bootstrap_expect = 6 retry_join = [ "100.116.158.95", # semaphore "100.117.106.136", # master "100.116.80.94" # ash3c ] encrypt = "$EncryptKey" } client { enabled = false } plugin "podman" { config { volumes { enabled = true } } } consul { address = "$tailscaleIP:8500" } "@ $configFile = "$configDir\nomad.hcl" $configContent | Out-File -FilePath $configFile -Encoding UTF8 Write-Host "✅ 配置文件已生成: $configFile" -ForegroundColor Green # 6. 创建 Windows 服务 Write-Host "🔧 创建 Windows 服务..." -ForegroundColor Cyan # 先停止并删除现有服务(如果存在) try { Stop-Service -Name "Nomad" -ErrorAction SilentlyContinue & sc.exe delete "Nomad" 2>$null } catch {} # 创建新服务 $serviceName = "Nomad" $serviceDisplayName = "HashiCorp Nomad" $serviceDescription = "HashiCorp Nomad Agent" $serviceCommand = "`"$nomadExe`" agent -config=`"$configFile`"" try { & sc.exe create $serviceName binPath= $serviceCommand DisplayName= $serviceDisplayName start= auto & sc.exe description $serviceName $serviceDescription # 配置服务恢复选项 & sc.exe failure $serviceName reset= 30 actions= restart/5000/restart/5000/restart/5000 Write-Host "✅ Windows 服务已创建" -ForegroundColor Green } catch { Write-Host "❌ 创建服务失败: $_" -ForegroundColor Red exit 1 } # 7. 启动服务 Write-Host "🚀 启动 Nomad 服务..." -ForegroundColor Cyan try { Start-Service -Name $serviceName Write-Host "✅ Nomad 服务已启动" -ForegroundColor Green } catch { Write-Host "❌ 启动服务失败: $_" -ForegroundColor Red Write-Host "检查服务状态: Get-Service Nomad" -ForegroundColor Yellow exit 1 } # 8. 验证安装 Write-Host "🔍 验证 Nomad 服务..." -ForegroundColor Cyan Start-Sleep -Seconds 10 try { $serviceStatus = Get-Service -Name $serviceName if ($serviceStatus.Status -eq "Running") { Write-Host "✅ Nomad 服务运行正常" -ForegroundColor Green } else { Write-Host "❌ Nomad 服务状态异常: $($serviceStatus.Status)" -ForegroundColor Red } } catch { Write-Host "❌ 检查服务状态失败: $_" -ForegroundColor Red } # 9. 检查集群连接 Write-Host "🌐 检查集群连接..." -ForegroundColor Cyan Start-Sleep -Seconds 15 try { & $nomadExe server members Write-Host "✅ 成功加入 Nomad 集群!" -ForegroundColor Green } catch { Write-Host "⚠️ 正在连接集群,请稍等..." -ForegroundColor Yellow Write-Host "可以运行以下命令检查状态:" -ForegroundColor Cyan Write-Host " nomad server members" -ForegroundColor White Write-Host " nomad node status" -ForegroundColor White } # 10. 防火墙规则 Write-Host "🔥 配置防火墙规则..." -ForegroundColor Cyan try { New-NetFirewallRule -DisplayName "Nomad HTTP" -Direction Inbound -Protocol TCP -LocalPort 4646 -Action Allow -ErrorAction SilentlyContinue New-NetFirewallRule -DisplayName "Nomad RPC" -Direction Inbound -Protocol TCP -LocalPort 4647 -Action Allow -ErrorAction SilentlyContinue New-NetFirewallRule -DisplayName "Nomad Serf" -Direction Inbound -Protocol TCP -LocalPort 4648 -Action Allow -ErrorAction SilentlyContinue Write-Host "✅ 防火墙规则已配置" -ForegroundColor Green } catch { Write-Host "⚠️ 防火墙规则配置可能失败,请手动检查" -ForegroundColor Yellow } Write-Host "" Write-Host "🎉 Windows Nomad Server 设置完成!" -ForegroundColor Green Write-Host "📊 Web UI: http://$tailscaleIP:4646" -ForegroundColor Cyan Write-Host "🔧 配置文件: $configFile" -ForegroundColor Cyan Write-Host "📝 服务管理:" -ForegroundColor Cyan Write-Host " 启动: Start-Service Nomad" -ForegroundColor White Write-Host " 停止: Stop-Service Nomad" -ForegroundColor White Write-Host " 状态: Get-Service Nomad" -ForegroundColor White Write-Host " 日志: Get-EventLog -LogName Application -Source Nomad" -ForegroundColor White