-
Notifications
You must be signed in to change notification settings - Fork 259
fix topology-updater cpu report #1979
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,10 +19,10 @@ package resourcemonitor | |
import ( | ||
"context" | ||
"fmt" | ||
"k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" | ||
"strconv" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/api/resource" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
client "k8s.io/client-go/kubernetes" | ||
"k8s.io/klog/v2" | ||
|
@@ -57,58 +57,49 @@ func NewPodResourcesScanner(namespace string, podResourceClient podresourcesapi. | |
} | ||
|
||
// isWatchable tells if the the given namespace should be watched. | ||
func (resMon *PodResourcesScanner) isWatchable(podNamespace string, podName string, hasDevice bool) (bool, bool, error) { | ||
pod, err := resMon.k8sClient.CoreV1().Pods(podNamespace).Get(context.TODO(), podName, metav1.GetOptions{}) | ||
// In Scan(), if watchable is false, this pods scan will skip | ||
// so we can return directly if pod's namespace is not watchable | ||
func (resMon *PodResourcesScanner) isWatchable(podResource *podresourcesapi.PodResources) (bool, bool, error) { | ||
if resMon.namespace != "*" && resMon.namespace != podResource.Namespace { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(my preference is to always use GetNamespace everything else being equal) |
||
return false, false, nil | ||
} | ||
|
||
pod, err := resMon.k8sClient.CoreV1().Pods(podResource.Namespace).Get(context.TODO(), podResource.Name, metav1.GetOptions{}) | ||
if err != nil { | ||
return false, false, err | ||
} | ||
|
||
isIntegralGuaranteed := hasExclusiveCPUs(pod) | ||
podHasExclusiveCPUs := hasExclusiveCPUs(pod) | ||
AllenXu93 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
isPodGuaranteed := qos.GetPodQOS(pod) == corev1.PodQOSGuaranteed | ||
|
||
if resMon.namespace == "*" && (isIntegralGuaranteed || hasDevice) { | ||
return true, isIntegralGuaranteed, nil | ||
} | ||
// TODO: add an explicit check for guaranteed pods and pods with devices | ||
return resMon.namespace == podNamespace && (isIntegralGuaranteed || hasDevice), isIntegralGuaranteed, nil | ||
return isPodGuaranteed || hasDevice(podResource), podHasExclusiveCPUs, nil | ||
} | ||
|
||
// hasExclusiveCPUs returns true if a guaranteed pod is allocated exclusive CPUs else returns false. | ||
// In isWatchable() function we check for the pod QoS and proceed if it is guaranteed (i.e. request == limit) | ||
// and hence we only check for request in the function below. | ||
func hasExclusiveCPUs(pod *corev1.Pod) bool { | ||
var totalCPU int64 | ||
var cpuQuantity resource.Quantity | ||
for _, container := range pod.Spec.InitContainers { | ||
|
||
var ok bool | ||
if cpuQuantity, ok = container.Resources.Requests[corev1.ResourceCPU]; !ok { | ||
continue | ||
} | ||
totalCPU += cpuQuantity.Value() | ||
isInitContainerGuaranteed := hasIntegralCPUs(pod, &container) | ||
if !isInitContainerGuaranteed { | ||
return false | ||
if hasIntegralCPUs(&container) { | ||
return true | ||
} | ||
} | ||
for _, container := range pod.Spec.Containers { | ||
var ok bool | ||
if cpuQuantity, ok = container.Resources.Requests[corev1.ResourceCPU]; !ok { | ||
continue | ||
} | ||
totalCPU += cpuQuantity.Value() | ||
isAppContainerGuaranteed := hasIntegralCPUs(pod, &container) | ||
if !isAppContainerGuaranteed { | ||
return false | ||
if hasIntegralCPUs(&container) { | ||
return true | ||
} | ||
} | ||
|
||
//No CPUs requested in all the containers in the pod | ||
return totalCPU != 0 | ||
//No integralCPUs requested in all the containers of the pod | ||
return false | ||
} | ||
|
||
// hasIntegralCPUs returns true if a container in pod is requesting integral CPUs else returns false | ||
func hasIntegralCPUs(pod *corev1.Pod, container *corev1.Container) bool { | ||
cpuQuantity := container.Resources.Requests[corev1.ResourceCPU] | ||
func hasIntegralCPUs(container *corev1.Container) bool { | ||
cpuQuantity, ok := container.Resources.Requests[corev1.ResourceCPU] | ||
if !ok { | ||
return false | ||
} | ||
return cpuQuantity.Value()*1000 == cpuQuantity.MilliValue() | ||
} | ||
|
||
|
@@ -146,8 +137,7 @@ func (resMon *PodResourcesScanner) Scan() (ScanResponse, error) { | |
|
||
for _, podResource := range respPodResources { | ||
klog.InfoS("scanning pod", "podName", podResource.GetName()) | ||
hasDevice := hasDevice(podResource) | ||
isWatchable, isIntegralGuaranteed, err := resMon.isWatchable(podResource.GetNamespace(), podResource.GetName(), hasDevice) | ||
isWatchable, isExclusiveCPUs, err := resMon.isWatchable(podResource) | ||
if err != nil { | ||
return ScanResponse{}, fmt.Errorf("checking if pod in a namespace is watchable, namespace:%v, pod name %v: %w", podResource.GetNamespace(), podResource.GetName(), err) | ||
} | ||
|
@@ -165,19 +155,17 @@ func (resMon *PodResourcesScanner) Scan() (ScanResponse, error) { | |
Name: container.Name, | ||
} | ||
|
||
if isIntegralGuaranteed { | ||
cpuIDs := container.GetCpuIds() | ||
if len(cpuIDs) > 0 { | ||
var resCPUs []string | ||
for _, cpuID := range container.GetCpuIds() { | ||
resCPUs = append(resCPUs, strconv.FormatInt(cpuID, 10)) | ||
} | ||
contRes.Resources = []ResourceInfo{ | ||
{ | ||
Name: corev1.ResourceCPU, | ||
Data: resCPUs, | ||
}, | ||
} | ||
cpuIDs := container.GetCpuIds() | ||
if len(cpuIDs) > 0 && isExclusiveCPUs { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor: |
||
var resCPUs []string | ||
for _, cpuID := range container.GetCpuIds() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (re)use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Yes, the original code called it twice unnecessarily) |
||
resCPUs = append(resCPUs, strconv.FormatInt(cpuID, 10)) | ||
} | ||
contRes.Resources = []ResourceInfo{ | ||
{ | ||
Name: corev1.ResourceCPU, | ||
Data: resCPUs, | ||
}, | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
misplaced import