ค้นหาเว็บไซต์

การขยายคอนเทนเนอร์ PowerShell และ Docker


ฉันยังคงแก้ไขคำสั่ง PowerShell เพื่อรับข้อมูลเกี่ยวกับคอนเทนเนอร์ Docker ต่อไป Docker CLI นั้นใช้ได้ แต่เป็นเรื่องยากมากที่จะทำงานกับเอาต์พุตหรือทำอะไรกับมันมาก นั่นเป็นเหตุผลที่ฉันชอบที่จะมีวัตถุในไปป์ไลน์ PowerShell องค์ประกอบคอนเทนเนอร์ Docker อย่างหนึ่งที่ฉันเพิกเฉยมาจนถึงตอนนี้คือขนาดคอนเทนเนอร์ ความงามโดยรวมของคอนเทนเนอร์ก็คือมันมีขนาดเล็กจากการออกแบบ ดังนั้นทำไมไม่ลองหาข้อมูลนั้นดูล่ะ?

ขนาดคอนเทนเนอร์

คุณสามารถใช้ Docker CLI เพื่อแสดงขนาดคอนเทนเนอร์ได้

จากสิ่งที่ฉันบอกได้ นี่คือขนาดของเลเยอร์ที่เขียนได้ในคอนเทนเนอร์ สำหรับฉันนี่ดูเหมือนจะเป็น 0 ไบต์เสมอ ถึงกระนั้น ในที่สุดฉันก็อาจมีคอนเทนเนอร์ที่มีค่าจริง ดังนั้นฉันจึงต้องมีโค้ดเพื่อแตกมันออกมา

$name = "cow1"
$sz = docker ps -asf "name=$name" --format "{{json .}}" | Convertfrom-json | Select -expandproperty size
[regex]$rx = "\d+"
$szbytes = $rx.match($sz).value

การใช้เคล็ดลับ JSON ที่ฉันพูดถึงครั้งล่าสุดฉันสามารถแยกคุณสมบัติ Size ซึ่งในกรณีของฉันจะเป็น 0B ฉันใช้รูปแบบนิพจน์ทั่วไปเพื่อรับเฉพาะส่วนตัวเลขของสตริงนี้หรือ 0

รับไฟล์นักเทียบท่า

แต่ละคอนเทนเนอร์ยังรวมชุดของไฟล์ เช่น บันทึก ซึ่งจัดเก็บไว้ในตำแหน่งโปรแกรม Docker ด้วยการใช้การประมวลผล PowerShell เพียงเล็กน้อย ฉันสามารถรับตำแหน่งนั้นจากข้อมูลระบบ Docker

$dockpath = ((docker system info | select-string "docker root dir") -split ": ")[1]

ใน Windows ควรเป็น C:\ProgramData\Docker แต่ละคอนเทนเนอร์มีไดเร็กทอรีของตัวเอง

ชื่อโฟลเดอร์คือรหัสคอนเทนเนอร์ซึ่งฉันรู้วิธีรับอยู่แล้ว จากนั้นจึงเป็นเรื่องง่ายในการวัดขนาดรวมของไฟล์ทั้งหมด

$name = "cow1"
$ID = (docker inspect $name --format "{{json .ID}}") -replace '"',''
$stat = Get-Childitem (join-path $dockpath "containers\$ID") -file -recurse | 
Measure-Object -Property length -sum

$Stat ให้ค่าผลรวม 11977 แก่ฉัน

รวมไดรฟ์ข้อมูลคอนเทนเนอร์ Docker

สุดท้าย คอนเทนเนอร์อาจมีวอลุ่มที่เกี่ยวข้องสำหรับพื้นที่จัดเก็บข้อมูลถาวร

$c = docker inspect cow1 | Convertfrom-json

อีกครั้งนี่เป็นเรื่องง่ายที่จะวัด

$m = $c.mounts | foreach { get-childitem -path $_.source -file -recurse } | 
measure-object length -sum

จากนั้นฉันสามารถบวกค่าทั้งหมดเข้าด้วยกันเพื่อให้ได้ขนาดโดยประมาณของคอนเทนเนอร์ที่ใกล้เคียงกัน

อัปเดตฟังก์ชัน PowerShell

ด้วยเหตุนี้ ฉันจึงอัปเดตฟังก์ชัน Get-DockerContainer

Get-DockerContainer.ps1:

#requires -version 5.1

Function Get-DockerContainer {
    [cmdletbinding(DefaultParameterSetName = "name")]
    [alias("gdc")]
    [OutputType("Get-DockerContainer.myDockerContainer")]

    Param(
        [Parameter(Position = 0, HelpMessage = "Enter a docker container name. The default is all running containers.", ParameterSetName = "name")]
        [ValidateNotNullorEmpty()]
        [string[]]$Name,
        [Parameter(HelpMessage = "Get all containers, not just those that are running.", ParameterSetName = "all")]
        [switch]$All
    )

    Begin {
        Write-Verbose "[BEGIN  ] Starting: $($MyInvocation.Mycommand)"

        #define a class for my docker container objects
        Class myDockerContainer {

            [string]$ID
            [string]$Name
            [datetime]$Created
            [string]$State
            [Boolean]$IsRunning
            [datetime]$Started
            #define Finished as a generic object so it can be null or a datetime
            [object]$Finished
            [timespan]$Runtime
            [string]$Image
            [object[]]$Mount
            [string]$Platform
            [int]$Size
            [string]$Path

            #methods
            [timespan] GetRuntime([datetime]$Start, [datetime]$End) {
                return ($end - $start)
            }
            [string] GetImageName([string]$image) {
                $val = (docker image inspect ($image -split ":")[1] --format "{{json .RepoTags}}") -replace '\[|\]|"', ""
                return $val
            }
            [int] GetContainerSize() {

                $stat = Get-Childitem $this.path -file -recurse | Measure-Object length -sum

                $sz = docker ps -asf "name=$($this.name)" --format "{{json .}}" | ConvertFrom-Json | Select-Object -expandproperty size
                [regex]$rx = "\d+"
                [int]$szbytes = $rx.match($sz).value
                if ($this.mount) {
                    [int]$mnt = ($this.mount |
                            ForEach-Object { Get-ChildItem -path $_.source -file -recurse } |
                            Measure-Object length -sum).sum
                }
                else {
                    $mnt = 0
                }

                $totalsz = $stat.sum + $szbytes + $mnt

                return $totalsz
            }
            #the constructor
            myDockerContainer ($Name) {
                #get the docker installation directory
                $dockpath = ((docker system info | Select-String "docker root dir") -split ": ")[1]
                $json = docker container inspect $Name | ConvertFrom-Json

                $this.Name = $Name.replace('"', '')
                $this.Created = $json.Created
                $this.ID = $json.ID
                $this.IsRunning = $json.state.Running
                #adjust date to localtime because PowerShell Core converts it differently than Windows PowerShell
                $this.Started = ($json.state.startedat -as [datetime]).toLocalTime()
                $this.Finished = if ($this.IsRunning) { $null } else {$json.state.finishedat -as [datetime]}
                $this.Runtime = if ($this.IsRunning) { $this.GetRuntime($this.started, (Get-Date) )} else {$this.GetRuntime($this.started, $this.finished )   }
                $this.State = $json.state.status
                $this.image = $this.GetImageName($json.image)
                $this.platform = $json.platform
                $this.mount = $json.mounts
                $this.Path = Join-Path -path $dockpath -childpath "containers\$($this.ID)"
                $this.Size = $this.GetContainerSize()
            }
        } #close class

    } #begin
    Process {
        if ($all) {
            Write-Verbose "[PROCESS] Getting all containers"
            $names = docker container ls -a --no-trunc --format "{{json .Names}}"
        }
        elseif ($Name) {
            Write-Verbose "[PROCESS] Getting container $name"
            $names = $Name
        }
        else {
            Write-Verbose "[PROCESS] Getting running containers"
            $names = docker container ls --no-trunc --format "{{json .Names}}"
        }

        if ($names) {
            foreach ($name in $names) {
                Write-Verbose "[PROCESS] Processing $name"
                if (docker container ls -qaf Name=$name) {
                    [myDockerContainer]::new($name)
                }
                else {
                    Write-Warning "Failed to find a container named $name"
                }
            } #foreach $Name
        } #if $name
        else {
            Write-Warning "No containers found"
        }
    } #process
    End {
        Write-Verbose "[END    ] Ending: $($MyInvocation.Mycommand)"
    } #end
} #close function

#import a format file if found
# https://gist.github.com/jdhitsolutions/74e52f89471720fb29b7fbaed279e183
$fmt = "C:\scripts\mydockercontainer.format.ps1xml"
if (Test-Path -path $fmt) {
    Update-FormatData $fmt
}

<#
sample usage
get-dockercontainer
get-dockercontainer | select *
get-dockercontainer -all | format-table -view stats
#>

ฉันอัปเดตชั้นเรียนเพื่อรวมขนาด

การจัดรูปแบบ PowerShell

ฟังก์ชันนี้มีโค้ดสำหรับใช้ไฟล์ format.ps1xml ซึ่งฉันได้ใส่ไว้ใน Github ด้วย

mydockercontainer.format.ps1xml:



  
    
      
      default
      
        Get-DockerContainer.myDockerContainer
      
      
        @"
$($_.ID)
   Image Tag   : $($_.image)
"@
        
      
      
        
          
            
            7
            left
          
          
            
            22
            left
          
          
            
            8
            left
          
          
            
            10
            left
          
          
            
            21
            left
          
          
            
            21
            left
          
          
            
            20
            left
          
        
        
          
            
              
                Name
               TableColumnIt
              
                Created
               TableColumnIt
              
                State
               TableColumnIt
              
                IsRunning
               TableColumnIt
              
                Started
               TableColumnIt
              
                Finished
               TableColumnIt
              
                Runtime
               TableColumnIt
            
          
        
      
    
    
      
      stats
      
        Get-DockerContainer.myDockerContainer
      
      
        
          
            
            7
            left
          
          
            
            10
            left
          
          
            
            23
            right
          
          
            
            23
            right
          
          
            
            19
            right
          
          
            
            9
            right
          
        
        
          
            
              
                Name
               TableColumnIt
              
                State
               TableColumnIt
              
                Created
               TableColumnIt
              
                (Get-Date) - $_.Created
               TableColumnIt
              
                Runtime
               TableColumnIt
              
                Size
               TableColumnIt
            
          
        
      
    
  

มุมมองเริ่มต้นยังคงเป็นตาราง

แต่ฉันยังเพิ่มมุมมองตารางที่ 2 ที่เรียกว่า สถิติ

ตอนนี้ฉันมีคำสั่ง PowerShell ที่มีประโยชน์มากสำหรับการรับข้อมูลคอนเทนเนอร์ Docker เป็นอย่างน้อย

เนื่องจากอยู่ใน PowerShell ฉันจึงสามารถส่งออก ถ่ายโอนข้อมูลไปยังฐานข้อมูล สร้างรายงาน HTML หรือสิ่งอื่นใดที่คุณนึกถึงใน PowerShell อย่างที่ฉันบอกไป Docker CLI มีประโยชน์ แต่ PowerShell ไม่มีประโยชน์

บทความที่เกี่ยวข้อง