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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
| function Remove-DockerOrphanResources { [CmdletBinding()] param( [switch]$IncludeVolumes, [switch]$DryRun )
$report = [System.Text.StringBuilder]::new() [void]$report.AppendLine("=== Docker 资源清理报告 ===") [void]$report.AppendLine("执行时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')`n")
$stopped = docker ps -aq --filter 'status=exited' 2>$null if ($stopped) { $count = ($stopped | Measure-Object).Count [void]$report.AppendLine("[容器] 发现 $count 个已停止的容器") if (-not $DryRun) { docker rm $stopped 2>$null | Out-Null [void]$report.AppendLine(" -> 已清理") } }
$dangling = docker images -q --filter 'dangling=true' 2>$null if ($dangling) { $count = ($dangling | Measure-Object).Count [void]$report.AppendLine("[镜像] 发现 $count 个悬空镜像") if (-not $DryRun) { docker rmi $dangling 2>$null | Out-Null [void]$report.AppendLine(" -> 已清理") } }
$networks = docker network ls --filter 'type=custom' -q 2>$null if ($networks) { $count = ($networks | Measure-Object).Count [void]$report.AppendLine("[网络] 发现 $count 个自定义网络") if (-not $DryRun) { docker network prune -f 2>$null | Out-Null [void]$report.AppendLine(" -> 已清理") } }
if ($IncludeVolumes) { $volumes = docker volume ls -q --filter 'dangling=true' 2>$null if ($volumes) { $count = ($volumes | Measure-Object).Count [void]$report.AppendLine("[卷] 发现 $count 个悬空卷") if (-not $DryRun) { docker volume prune -f 2>$null | Out-Null [void]$report.AppendLine(" -> 已清理") } } }
if (-not $DryRun) { [void]$report.AppendLine("`n正在回收磁盘空间...") $reclaim = docker system df --format '{{.Reclaimable}}' 2>$null docker system prune -f 2>$null | Out-Null [void]$report.AppendLine("可回收空间: $($reclaim -join ', ')") } else { [void]$report.AppendLine("`n[模拟模式] 未执行实际清理操作") }
$report.ToString() }
function Get-DockerResourceMonitor { [CmdletBinding()] param( [int]$IntervalSeconds = 5, [int]$Count = 12 )
for ($i = 0; $i -lt $Count; $i++) { $timestamp = Get-Date -Format 'HH:mm:ss'
$stats = docker stats --no-stream --format ` '{{.Name}}|{{.CPUPerc}}|{{.MemUsage}}|{{.MemPerc}}|{{.NetIO}}|{{.PIDs}}' 2>$null
if ($i -eq 0) { Write-Host ("{0,-8} {1,-20} {2,-10} {3,-15} {4,-8} {5,-20} {6,-6}" -f ` '时间', '容器', 'CPU', '内存使用', '内存%', '网络IO', 'PID') ` -ForegroundColor Cyan Write-Host ('-' * 90) }
$stats | ForEach-Object { $parts = $_ -split '\|' if ($parts.Count -eq 6) { Write-Host ("{0,-8} {1,-20} {2,-10} {3,-15} {4,-8} {5,-20} {6,-6}" -f ` $timestamp, $parts[0], $parts[1], $parts[2], $parts[3], $parts[4], $parts[5]) } }
if ($i -lt $Count - 1) { Start-Sleep -Seconds $IntervalSeconds } } }
function Test-DockerImageSecurity { [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Image,
[string]$Severity = 'HIGH,CRITICAL', [switch]$SkipDbUpdate )
Write-Host "正在扫描镜像: $Image" -ForegroundColor Cyan Write-Host "严重级别过滤: $Severity`n"
$trivy = Get-Command trivy -ErrorAction SilentlyContinue if (-not $trivy) { Write-Warning "未找到 trivy 扫描器,使用 docker scout 替代" $scanResult = docker scout cves $Image 2>&1 } else { $trivyArgs = @('image', '--severity', $Severity, '--format', 'table', $Image) if ($SkipDbUpdate) { $trivyArgs += '--skip-db-update' } $scanResult = trivy $trivyArgs 2>&1 }
$scanResult | ForEach-Object { Write-Host $_ }
$criticalCount = ($scanResult | Select-String -Pattern 'CRITICAL' -SimpleMatch).Count $highCount = ($scanResult | Select-String -Pattern 'HIGH' -SimpleMatch).Count
[PSCustomObject]@{ Image = $Image Critical = $criticalCount High = $highCount ScanTime = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' Status = if ($criticalCount -gt 0) { 'NEEDS ATTENTION' } else { 'ACCEPTABLE' } } }
|