การขยายคอนเทนเนอร์ 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 ไม่มีประโยชน์