Skip to content

Instantly share code, notes, and snippets.

@MattJeanes
Last active July 14, 2022 23:36
Show Gist options
  • Save MattJeanes/68a43d009e03cffa0004970e5780eaeb to your computer and use it in GitHub Desktop.
Save MattJeanes/68a43d009e03cffa0004970e5780eaeb to your computer and use it in GitHub Desktop.
Show a list of pods with their actual / request / limits for CPU and Memory all in a convenient place
param(
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[string]$Namespace
)
if (-not $Namespace) {
$Namespace = "default";
}
$ErrorActionPreference = "Stop"
$pods = kubectl get pod --all-namespaces -o json | ConvertFrom-Json
$top = kubectl top pod --all-namespaces
$nodes = kubectl get nodes -o json | ConvertFrom-Json
function Get-NormalizedCPU {
param(
[Parameter(Mandatory = $false)]
[string]$CPU
)
if (-not $CPU) {
return 0
}
elseif ($CPU.EndsWith("m")) {
return [int64]$CPU.TrimEnd("m")
}
elseif ($CPU.EndsWith("k")) {
return ([int64]$CPU.TrimEnd("k")) * 1000 * 1000
}
else {
return ([int64]$CPU) * 1000
}
}
function Get-NormalizedMemory {
param(
[Parameter(Mandatory = $false)]
[string]$Memory
)
if (-not $Memory) {
return 0
}
elseif ([int64]::TryParse($Memory, [ref]$null)) {
return [int64]$Memory
}
elseif ($Memory.EndsWith("Ki")) {
return ([int64]$Memory.TrimEnd("Ki")) * 1024
}
elseif ($Memory.EndsWith("Mi")) {
return ([int64]$Memory.TrimEnd("Mi")) * 1024 * 1024
}
elseif ($Memory.EndsWith("Gi")) {
return ([int64]$Memory.TrimEnd("Gi")) * 1024 * 1024 * 1024
}
elseif ($Memory.EndsWith("Ti")) {
return ([int64]$Memory.TrimEnd("Ti")) * 1024 * 1024 * 1024 * 1024
}
else {
Write-Error "Unsupported memory request unit on: $Memory"
}
}
function Get-FriendlyCPU {
param(
[Parameter(Mandatory = $true)]
[int64]$CPU,
[Parameter(Mandatory = $false)]
[int64]$CompareCPU
)
$friendlyCPU = "$($CPU)m"
if ($CompareCPU -and $CPU -ne 0) {
$compare = [Math]::Round(($CPU / $CompareCPU) * 100, 1)
$friendlyCPU = "$friendlyCPU ($compare%)"
}
return $friendlyCPU
}
function Get-FriendlyMemory {
param(
[Parameter(Mandatory = $true)]
[int64]$Memory,
[Parameter(Mandatory = $false)]
[int64]$CompareMemory
)
$friendlyMemory = "$([Math]::Round($Memory / 1024 / 1024))Mi"
if ($CompareMemory -and $Memory -ne 0) {
$compare = [Math]::Round(($Memory / $CompareMemory) * 100, 1)
$friendlyMemory = "$friendlyMemory ($compare%)"
}
return $friendlyMemory
}
function Get-PodResources {
param(
[Parameter(Mandatory = $true)]
$Pod
)
$requestCPU = 0
$limitCPU = 0
$requestMemory = 0
$limitMemory = 0
$containers = $Pod.spec.containers
$containers | ForEach-Object {
$requestCPU += Get-NormalizedCPU $_.resources.requests.cpu
$limitCPU += Get-NormalizedCPU $_.resources.limits.cpu
$requestMemory += Get-NormalizedMemory $_.resources.requests.memory
$limitMemory += Get-NormalizedMemory $_.resources.limits.memory
}
return @{
requestCPU = $requestCPU
limitCPU = $limitCPU
requestMemory = $requestMemory
limitMemory = $limitMemory
}
}
$actuals = @{}
$allMatches = ($top | Select-String ".+? +(.+?) +(\d+.+?) +(\d+.+?) *$" -AllMatches)
$allMatches.Matches | ForEach-Object {
$actuals[$_.Groups[1].Value] = @{
cpu = Get-NormalizedCPU $_.Groups[2].Value
memory = Get-NormalizedMemory $_.Groups[3].Value
}
}
$totalActualCPU = 0
$totalActualMemory = 0
$totalRequestCPU = 0
$totalRequestMemory = 0
$totalLimitCPU = 0
$totalLimitMemory = 0
$arr = @()
$nodeActuals = @{}
$pods.items | ForEach-Object {
$podResources = Get-PodResources $_
$podName = $_.metadata.name
$podNamespace = $_.metadata.namespace
$nodeName = $_.spec.nodeName
$actualCPU = $actuals[$podName].cpu
$actualMemory = $actuals[$podName].memory
if ($nodeName -and -not $nodeActuals.ContainsKey($nodeName)) {
$nodeActuals[$nodeName] = @{
actualCPU = 0
actualMemory = 0
requestCPU = 0
requestMemory = 0
limitCPU = 0
limitMemory = 0
}
}
if ($nodeName) {
$nodeActuals[$nodeName].actualCPU += $actualCPU
$nodeActuals[$nodeName].actualMemory += $actualMemory
$nodeActuals[$nodeName].requestCPU += $podResources.requestCPU
$nodeActuals[$nodeName].requestMemory += $podResources.requestMemory
$nodeActuals[$nodeName].limitCPU += $podResources.limitCPU
$nodeActuals[$nodeName].limitMemory += $podResources.limitMemory
}
$totalActualCPU += $actualCPU
$totalRequestCPU += $podResources.requestCPU
$totalLimitCPU += $podResources.limitCPU
$totalActualMemory += $actualMemory
$totalRequestMemory += $podResources.requestMemory
$totalLimitMemory += $podResources.limitMemory
$arr += @{
name = $podName
namespace = $podNamespace
actualCPU = Get-FriendlyCPU -CPU $actualCPU
requestCPU = Get-FriendlyCPU -CPU $podResources.requestCPU -CompareCPU $actualCPU
limitCPU = Get-FriendlyCPU -CPU $podResources.limitCPU -CompareCPU $actualCPU
actualMemory = Get-FriendlyMemory -Memory $actualMemory
requestMemory = Get-FriendlyMemory -Memory $podResources.requestMemory -CompareMemory $actualMemory
limitMemory = Get-FriendlyMemory -Memory $podResources.limitMemory -CompareMemory $actualMemory
}
}
$arr += @{
name = "total"
actualCPU = Get-FriendlyCPU -CPU $totalActualCPU
requestCPU = Get-FriendlyCPU -CPU $totalRequestCPU -CompareCPU $totalActualCPU
limitCPU = Get-FriendlyCPU -CPU $totalLimitCPU -CompareCPU $totalLimitCPU
actualMemory = Get-FriendlyMemory -Memory $totalActualMemory
requestMemory = Get-FriendlyMemory -Memory $totalRequestMemory -CompareMemory $totalActualMemory
limitMemory = Get-FriendlyMemory -Memory $totalLimitMemory -CompareMemory $totalActualMemory
}
$arr | Where-Object { $Namespace -in $_.namespace, "*" } | ForEach-Object { [PSCustomObject]$_ } | Format-Table -AutoSize name, namespace, actualCPU, requestCPU, limitCPU, actualMemory, requestMemory, limitMemory
$totalAllocatableCPU = 0
$totalAllocatableMemory = 0
$nodesArr = @()
$nodes.items | Where-Object { $_.metadata.labels.type -ne "virtual-kubelet" } | ForEach-Object {
$nodeAllocatableCPU = Get-NormalizedCPU $_.status.allocatable.cpu
$nodeAllocatableMemory = Get-NormalizedMemory $_.status.allocatable.memory
$totalAllocatableCPU += $nodeAllocatableCPU
$totalAllocatableMemory += $nodeAllocatableMemory
$nodeActualCPU = $nodeActuals[$_.metadata.name].actualCPU
$nodeActualMemory = $nodeActuals[$_.metadata.name].actualMemory
$nodeRequestCPU = $nodeActuals[$_.metadata.name].requestCPU
$nodeRequestMemory = $nodeActuals[$_.metadata.name].requestMemory
$nodeLimitCPU = $nodeActuals[$_.metadata.name].limitCPU
$nodeLimitMemory = $nodeActuals[$_.metadata.name].limitMemory
$nodesArr += @{
name = $_.metadata.name
allocatableCPU = Get-FriendlyCPU -CPU $nodeAllocatableCPU
allocatableMemory = Get-FriendlyMemory -Memory $nodeAllocatableMemory
actualCPU = Get-FriendlyCPU -CPU $nodeActualCPU -CompareCPU $nodeAllocatableCPU
actualMemory = Get-FriendlyMemory -Memory $nodeActualMemory -CompareMemory $nodeAllocatableMemory
requestCPU = Get-FriendlyCPU -CPU $nodeRequestCPU -CompareCPU $nodeAllocatableCPU
requestMemory = Get-FriendlyMemory -Memory $nodeRequestMemory -CompareMemory $nodeAllocatableMemory
limitCPU = Get-FriendlyCPU -CPU $nodeLimitCPU -CompareCPU $nodeAllocatableCPU
limitMemory = Get-FriendlyMemory -Memory $nodeLimitMemory -CompareMemory $nodeAllocatableMemory
}
}
$nodesArr | ForEach-Object { [PSCustomObject]$_ } | Format-Table -AutoSize name, allocatableCPU, actualCPU, requestCPU, limitCPU, allocatableMemory, actualMemory, requestMemory, limitMemory
Write-Host "Total actual/requests/allocatable CPU: $(Get-FriendlyCPU $totalActualCPU) / $(Get-FriendlyCPU $totalRequestCPU) / $(Get-FriendlyCPU $totalAllocatableCPU)"
Write-Host "Total actual/request/allocatable memory: $(Get-FriendlyMemory $totalActualMemory) / $(Get-FriendlyMemory $totalRequestMemory) / $(Get-FriendlyMemory $totalAllocatableMemory)"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment