Если директория C:\ProgramData\docker\windowsfilter неприлично разрослась, а команда
docker system prune -a -f
не помогает освобить место, то нужно почистить orphan (сиротские) слои, не принадлежащие никаким образам.
Function Find-OrphanDockerLayers () { param ( [switch]$RenameOrphanLayers, [switch]$CalcSize ) If ($RenameOrphanLayers) { Write-Warning "$($env:COMPUTERNAME) -RenameOrphanLayers option enabled, will rename all orphan layers" } # Get known layers on Docker images [array]$ImageDetails += docker images -q | ForEach { docker inspect $_ | ConvertFrom-Json } ForEach ($Image in $ImageDetails) { $ImageLayer = $Image.GraphDriver.Data.dir [array]$ImageLayers += $ImageLayer $LayerChain = Get-Content "$ImageLayer\layerchain.json" If ($LayerChainFileContent -ne "null") { [array]$ImageParentLayers += $LayerChain | ConvertFrom-Json } } # Get known layes on Docker containers [array]$ContainerDetails = docker ps -a -q | ForEach { docker inspect $_ | ConvertFrom-Json} ForEach ($Container in $ContainerDetails) { [array]$ContainerLayers += $Container.GraphDriver.Data.dir } # Get layers on disk $LayersOnDisk = (Get-ChildItem -Path C:\ProgramData\Docker\windowsfilter -Directory).FullName $ImageLayers += $ImageParentLayers $UniqueImageLayers = $ImageLayers | Select-Object -Unique [array]$KnownLayers = $UniqueImageLayers $KnownLayers += $ContainerLayers # Find orphan layers $OrphanLayersTotal = 0 ForEach ($Layer in $LayersOnDisk) { If ($KnownLayers -notcontains $Layer) { [array]$OrphanLayer += $Layer If ($CalcSize) { $LayerSize = (Get-ChildItem -Path $Layer -Recurse -ErrorAction:SilentlyContinue | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum $OrphanLayersTotal += $LayerSize Write-Warning "$($env:COMPUTERNAME) - Found orphan layer: $($Layer -Replace '\r\n','') with size: $(($LayerSize -Replace '\r\n','') / 1MB) MB" } else { Write-Warning "$($env:COMPUTERNAME) - Found orphan layer: $($Layer -Replace '\r\n','').." } If (($RenameOrphanLayers) -and ($Layer -notlike "*-removing")) { GrantFullAccessToAdmins $Layer $LayerNewPath = $Layer + "-removing" Rename-Item -Path $Layer -NewName $LayerNewPath } } } Write-Host "$($env:COMPUTERNAME) - Layers on disk: $($LayersOnDisk.count)" Write-Host "$($env:COMPUTERNAME) - Image layers: $($UniqueImageLayers.count)" Write-Host "$($env:COMPUTERNAME) - Container layers: $($ContainerLayers.count)" If ($CalcSize) { $OrphanLayersTotalMB = $OrphanLayersTotal / 1MB Write-Warning "$($env:COMPUTERNAME) - Found $($OrphanLayer.count) orphan layers with total size $OrphanLayersTotalMB MB" } else { Write-Warning "$($env:COMPUTERNAME) - Found $($OrphanLayer.count) orphan layers..." } } function GrantFullAccessToAdmins ($Path) { $NewAcl = Get-Acl -Path $Path # Set properties $identity = "BUILTIN\Administrators" $fileSystemRights = "FullControl" #$type = "Allow" # Create new rule $fileSystemAccessRuleArgumentList = $identity, $fileSystemRights, "None", "None","Allow" # $type (https://stackoverflow.com/a/37015095) $fileSystemAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList # Apply new rule $NewAcl.SetAccessRule($fileSystemAccessRule) Set-Acl -Path $Path -AclObject $NewAcl } # Purge untagged images if ( $(docker images -f "dangling=true" -q) ) { Invoke-Expression 'docker rmi $(docker images -f "dangling=true" -q)' } GrantFullAccessToAdmins "C:\ProgramData\docker\windowsfilter" Find-OrphanDockerLayers -RenameOrphanLayers # Due to short docker service shutdown timeout I will restart it untill all labeled layers be purged. while (Get-ChildItem -Path C:\ProgramData\Docker\windowsfilter -Directory -Filter "*-removing") { Stop-Service *docker* Restart-Service *docker* }
Discussion