Если директория 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*
}
Enter your comment. Wiki syntax is allowed:
S Y Y F B
 
  • ms_windows_ms_sql/windows_docker_purge_orphan_layers.txt
  • Last modified: 2021/12/25 09:51
  • by admin