Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

Commit

Permalink
compute QoS & display
Browse files Browse the repository at this point in the history
  • Loading branch information
pnickolov committed Sep 21, 2021
1 parent 09ee71f commit a20bac3
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
6 changes: 6 additions & 0 deletions app/model/model.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package model

const (
QOS_GUARANTEED = "guaranteed"
QOS_BURSTABLE = "burstable"
QOS_BESTEFFORT = "besteffort"
)

type AppMetadata struct {
//Cluster string // needed?
//Name string
Expand Down
52 changes: 52 additions & 0 deletions cmd/analysis.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,50 @@ func analyzeContainers(app *appmodel.App) {
// TODO
}

func computePodQoS(app *appmodel.App) string {
// following the rules at https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/
// note: ignoring the init containers
// TODO: use other sources to get the QoS, use this one to (a) populate QoS if no QoS info found and
// (b) validate the QoS found (e.g., degrade)

allMatch := true // assume all containers, all resources match the guaranteed requirements
oneMatch := false // track if at least one container, one resource has resources specified
for i := range app.Containers {
c := &app.Containers[i]

if c.Cpu.Limit > 0 {
if c.Cpu.Request > 0 && c.Cpu.Request != c.Cpu.Limit {
allMatch = false
}
oneMatch = true
} else if c.Cpu.Request > 0 {
allMatch = false
oneMatch = true
} else {
allMatch = false
}
if c.Memory.Limit > 0 {
if c.Memory.Request > 0 && c.Memory.Request != c.Memory.Limit {
allMatch = false
}
oneMatch = true
} else if c.Memory.Request > 0 {
allMatch = false
oneMatch = true
} else {
allMatch = false
}
}

if allMatch {
return appmodel.QOS_GUARANTEED
} else if oneMatch {
return appmodel.QOS_BURSTABLE
} else {
return appmodel.QOS_BESTEFFORT
}
}

// --- App-level Analysis ----------------------------------------------------

func preAnalyzeApp(app *appmodel.App) {
Expand All @@ -195,6 +239,14 @@ func preAnalyzeApp(app *appmodel.App) {
}
}
}

computedQos := computePodQoS(app)
if app.Settings.QosClass == "" {
app.Settings.QosClass = computedQos
} else if app.Settings.QosClass != computedQos {
log.Warnf("Computed QoS class %q does not match discovered QoS class %q for app %v; assuming the latter",
computedQos, app.Settings.QosClass, app.Metadata)
}
}

func analyzeApp(app *appmodel.App) {
Expand Down
5 changes: 3 additions & 2 deletions cmd/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (table *AppTable) outputTableHeader() {
const RIGHT = tablewriter.ALIGN_RIGHT
const LEFT = tablewriter.ALIGN_LEFT

table.t.SetHeader([]string{"Rating", "Confidence", "Namespace", "Deployment", "Container", "Instances", "CPU", "Mem", "Reason"})
table.t.SetHeader([]string{"Rating", "Confidence", "Namespace", "Deployment", "QoS Class", "Instances", "CPU", "Mem", "Reason"})
table.t.SetColumnAlignment([]int{RIGHT, RIGHT, LEFT, LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT})
table.t.SetFooter([]string{})
table.t.SetCenterSeparator("")
Expand All @@ -98,7 +98,7 @@ func (table *AppTable) outputTableApp(app *appmodel.App) {
fmt.Sprintf("%d%%", app.Analysis.Confidence),
app.Metadata.Namespace,
app.Metadata.Workload,
app.Analysis.MainContainer,
app.Settings.QosClass,
fmt.Sprintf("%.0fx%d", app.Metrics.AverageReplicas, len(app.Containers)),
fmt.Sprintf("%.0f%%", app.Metrics.CpuUtilization),
fmt.Sprintf("%.0f%%", app.Metrics.MemoryUtilization),
Expand Down Expand Up @@ -135,6 +135,7 @@ func (table *AppTable) outputDetailApp(app *appmodel.App) {
table.t.Rich([]string{"Deployment", app.Metadata.Workload}, nil)
table.t.Rich([]string{"Kind", fmt.Sprintf("%v (%v)", app.Metadata.WorkloadKind, app.Metadata.WorkloadApiVersion)}, nil)
table.t.Rich([]string{"Main Container", app.Analysis.MainContainer}, nil)
table.t.Rich([]string{"Pod QoS Class", app.Settings.QosClass}, nil)

table.t.Rich([]string{"Rating", fmt.Sprintf("%4d%%", app.Analysis.Rating)}, appColors)
table.t.Rich([]string{"Confidence", fmt.Sprintf("%4d%%", app.Analysis.Confidence)}, appColors)
Expand Down

0 comments on commit a20bac3

Please sign in to comment.