适用于 PowerShell 7.0 及以上版本,需安装 kubectl
Kubernetes 已成为容器编排的事实标准,无论是自建集群还是使用托管服务(AKS、EKS、GKE),日常运维都离不开与 Kubernetes API 交互。虽然 kubectl 是官方命令行工具,但 PowerShell 的管道、对象处理和脚本能力可以为 Kubernetes 运维带来更高的效率——特别是在批量操作、日志聚合和自动化巡检等场景中。
本文将讲解如何使用 PowerShell 封装 kubectl 命令,实现高效的 Kubernetes 运维管理。
kubectl 环境准备 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 kubectl version --client 2 >$null if ($LASTEXITCODE -ne 0 ) { Write-Host "kubectl 未安装" -ForegroundColor Red Install-Script -Name install-kubectl -Scope CurrentUser -Force } kubectl cluster-info kubectl get nodes -o wide $kubeConfig = "$env:USERPROFILE \.kube\config" kubectl get namespaces | Select-Object -Skip 1 | ForEach-Object { ($_ -split '\s+' )[0 ] }
执行结果示例:
1 2 3 4 5 6 7 Client Version: v1.30 .0 Kubernetes control plane is running at https://k8s-api.example.com:6443 NAME STATUS ROLES AGE VERSION INTERNAL-IPnode -01 Ready control-plane 90 d v1.30 .0 10.0.0.1 node -02 Ready worker 90 d v1.30 .0 10.0.0.2 node -03 Ready worker 90 d v1.30 .0 10.0.0.3
解析 kubectl 输出为 PowerShell 对象 kubectl 的文本输出可以通过管道解析为结构化对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 function Get-K8sPod { param ( [string ]$Namespace = "default" , [string ]$LabelSelector , [string ]$FieldSelector ) $args = @ ('get' , 'pods' , '-n' , $Namespace , '-o' , 'custom-columns=NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName,RESTARTS:.status.containerStatuses[0].restartCount,AGE:.metadata.creationTimestamp,IP:.status.podIP' ) if ($LabelSelector ) { $args += @ ('-l' , $LabelSelector ) } if ($FieldSelector ) { $args += @ ('--field-selector' , $FieldSelector ) } $output = kubectl @args 2 >$null if ($output .Count -le 1 ) { return @ () } $output | Select-Object -Skip 1 | ForEach-Object { $parts = $_ -split '\s+' [PSCustomObject ]@ { Name = $parts [0 ] Status = $parts [1 ] Node = $parts [2 ] Restarts = [int ]$parts [3 ] Age = $parts [4 ] IP = $parts [5 ] } } } Get-K8sPod -Namespace "production" | Format-Table -AutoSize Get-K8sPod -Namespace "production" -LabelSelector "app=web" | Format-Table -AutoSize Get-K8sPod | Where-Object { $_ .Status -ne 'Running' }
执行结果示例:
1 2 3 4 5 6 7 8 9 10 11 Name Status Node Restarts Age IP ---- ------ ---- -------- --- -- web-app-7 d4f8b-x2k9l Running node -02 0 5 d 10.244 .1.15 web-app-7 d4f8b-m8n3p Running node -03 0 5 d 10.244 .2.22 api-server-5 c9a2d-q7j4 Running node -02 3 12 d 10.244 .1.10 redis-master -0 Running node -01 0 30 d 10.244 .0.5 Name Status Node Restarts Age IP ---- ------ ---- -------- --- -- web-app-7 d4f8b-x2k9l Running node -02 0 5 d 10.244 .1.15 web-app-7 d4f8b-m8n3p Running node -03 0 5 d 10.244 .2.22
集群健康巡检 使用 PowerShell 构建自动化的 Kubernetes 集群健康检查:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 function Get-K8sClusterHealth { param ( [string []]$Namespaces = @ ('default' , 'production' , 'monitoring' ) ) Write-Host "========== Kubernetes 集群健康报告 ==========" -ForegroundColor Cyan Write-Host "检查时间:$ (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')`n" Write-Host "--- 节点状态 ---" -ForegroundColor Yellow $nodes = kubectl get nodes -o json | ConvertFrom-Json foreach ($node in $nodes .items) { $conditions = $node .status.conditions | Where-Object { $_ .type -eq 'Ready' } $status = $conditions .status $cpuAlloc = $node .status.allocatable.cpu $memAlloc = $node .status.allocatable.memory $color = if ($status -eq 'True' ) { 'Green' } else { 'Red' } Write-Host " $ ($node .metadata.name): " -NoNewline Write-Host $status -ForegroundColor $color -NoNewline Write-Host " (CPU: $cpuAlloc , Memory: $memAlloc )" } Write-Host "`n--- Pod 状态汇总 ---" -ForegroundColor Yellow foreach ($ns in $Namespaces ) { $pods = kubectl get pods -n $ns -o json 2 >$null | ConvertFrom-Json if (-not $pods .items) { continue } $running = ($pods .items | Where-Object { $_ .status.phase -eq 'Running' }).Count $failed = ($pods .items | Where-Object { $_ .status.phase -eq 'Failed' }).Count $pending = ($pods .items | Where-Object { $_ .status.phase -eq 'Pending' }).Count $total = $pods .items.Count $highRestart = $pods .items | Where-Object { ($_ .status.containerStatuses | Measure-Object -Property restartCount -Maximum ).Maximum -gt 5 } Write-Host " 命名空间 $ns : $total 个 Pod" -NoNewline Write-Host " (Running: $running , Failed: $failed , Pending: $pending )" -ForegroundColor $ (if ($failed -gt 0 ) { 'Red' } elseif ($pending -gt 0 ) { 'Yellow' } else { 'Green' }) if ($highRestart ) { Write-Host " 高重启 Pod:" -ForegroundColor Red $highRestart | ForEach-Object { $restarts = ($_ .status.containerStatuses | Measure-Object -Property restartCount -Maximum ).Maximum Write-Host " $ ($_ .metadata.name) - 重启 $restarts 次" -ForegroundColor Red } } } Write-Host "`n--- 资源使用 Top ---" -ForegroundColor Yellow $topNodes = kubectl top nodes 2 >$null if ($topNodes ) { $topNodes | Select-Object -Skip 1 | ForEach-Object { $parts = $_ -split '\s+' $cpuPct = $parts [2 ] -replace '%' ,'' $memPct = $parts [4 ] -replace '%' ,'' $color = if ([int ]$cpuPct -gt 80 -or [int ]$memPct -gt 80 ) { 'Red' } elseif ([int ]$cpuPct -gt 60 -or [int ]$memPct -gt 60 ) { 'Yellow' } else { 'Green' } Write-Host " $ ($_ )" -ForegroundColor $color } } else { Write-Host " Metrics Server 未安装,无法获取资源使用率" -ForegroundColor DarkGray } Write-Host "`n--- 最近事件(Warning) ---" -ForegroundColor Yellow $events = kubectl get events -A --field-selector type =Warning --sort-by ='.lastTimestamp' 2 >$null if ($events ) { $events | Select-Object -First 5 | ForEach-Object { Write-Host " $_ " } } else { Write-Host " 无警告事件" -ForegroundColor Green } } Get-K8sClusterHealth
执行结果示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 == == == == == Kubernetes 集群健康报告 == == == == == 检查时间:202 5-0 5-30 08 :30 :00 - -- 节点状态 - -- node-01: True (CPU: 4 , Memory: 16 Gi) node-02: True (CPU: 8 , Memory: 32 Gi) node-03: True (CPU: 8 , Memory: 32 Gi) - -- Pod 状态汇总 - -- 命名空间 default : 5 个 Pod (Running: 5 , Failed: 0 , Pending: 0 ) 命名空间 production : 12 个 Pod (Running: 11 , Failed: 1 , Pending: 0 ) 高重启 Pod: api-server-5 c9a2d-q7j4 - 重启 15 次 命名空间 monitoring : 3 个 Pod (Running: 3 , Failed: 0 , Pending: 0 ) - -- 资源使用 Top - -- node-01 1200 m/4 8 Gi/16Gi (30 %/ 50 %) node-02 4500 m/8 28 Gi/32Gi (56 %/ 87 %) node-03 2100 m/8 18 Gi/32Gi (26 %/ 56 %) - -- 最近事件(Warning) - -- 15 m Warning PodLoadBalancer api-server-5 c9a2d Failed to pull image
批量操作与日志收集 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 function Restart-K8sDeployment { param ( [Parameter (Mandatory )] [string ]$Namespace , [string ]$LabelSelector ) $deployments = kubectl get deployments -n $Namespace -l $LabelSelector -o json | ConvertFrom-Json foreach ($deploy in $deployments .items) { $name = $deploy .metadata.name Write-Host "重启 Deployment:$name " -ForegroundColor Cyan kubectl rollout restart deployment/$name -n $Namespace kubectl rollout status deployment/$name -n $Namespace --timeout =300 s } } function Get-K8sPodLogs { param ( [string ]$Namespace = "default" , [string ]$LabelSelector , [int ]$Tail = 100 ) $pods = kubectl get pods -n $Namespace -l $LabelSelector -o json | ConvertFrom-Json $allLogs = @ () foreach ($pod in $pods .items) { $podName = $pod .metadata.name $logs = kubectl logs $podName -n $Namespace --tail $Tail 2 >$null foreach ($line in $logs -split "`n" ) { if ($line -match 'ERROR|WARN|Exception' ) { $allLogs += [PSCustomObject ]@ { Pod = $podName Level = if ($line -match 'ERROR|FATAL' ) { 'Error' } else { 'Warning' } Message = $line .Trim() } } } } $allLogs | Sort-Object Level, Pod | Format-Table -AutoSize -Wrap } Get-K8sPodLogs -Namespace "production" -LabelSelector "app=web" -Tail 500
执行结果示例:
1 2 3 4 5 6 7 8 重启 Deployment:web-app deployment "web-app" successfully rolled out Pod Level Message ---- ----- ------- web-app-7d4f8b-x2k9l Error ERROR [DB] Connection pool exhausted web-app-7d4f8b-m8n3p Warning WARN Cache miss rate exceeded 50% api-server-5c9a2d-q7j4 Error ERROR Failed to process request: timeout
注意事项
JSON 输出解析 :kubectl 的 -o json 输出通过 ConvertFrom-Json 解析为 PowerShell 对象,比文本解析更可靠
API Server 连接 :确保 kubeconfig 正确配置,可以访问目标集群的 API Server
命名空间隔离 :多命名空间环境下操作时,始终使用 -n 参数指定命名空间,避免误操作
资源配额 :大规模集群中避免频繁 kubectl get all 类型的查询,可能给 API Server 造成压力
日志量控制 :生产 Pod 日志量可能很大,使用 --tail 和 --since 参数限制查询范围
kubectl 插件 :kubectx、kubens、kubectl-tree 等插件可以提升操作效率,建议安装