Skip to content

Commit 74575cf

Browse files
committed
🎨 improve logging and stability
modified: README.md; modified: controllers/pod_controller.go; modified: controllers/pod_controller_functions.go; modified: controllers/pod_controller_types.go
1 parent 22fa4ed commit 74575cf

File tree

4 files changed

+25
-25
lines changed

4 files changed

+25
-25
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
**kube-reqsizer** is a kubernetes controller that will measure the usage of pods over time and optimize (reduce/increase) their requests based on the average usage.
1818

19-
When all required conditions meet, the controller calculates the result requirements based on all the samples taken so far a pod.
20-
It then goes "upstream" to the parent controller of that pod, for example *Deployment*, and updates the relevant containers for the pod inside the deployment as a reconciliation, as if its desired state is the new state with the new requirements.
19+
When all required conditions meet, the controller calculates the result requirements based on all the samples taken so far a pod and its peers in the same deployment controller.
20+
It then goes "upstream" to the parent controller of that pod, for example *Deployment*, and updates the relevant containers for the pods inside the deployment as a reconciliation, as if its desired state is the new state with the new requirements.
2121

2222
<img src="./assets/example.png" width="200">
2323

controllers/pod_controller.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ const (
4040
)
4141

4242
func cacheKeyFunc(obj interface{}) (string, error) {
43-
return obj.(PodRequests).Name, nil
43+
return obj.(PodRequests).Name + obj.(PodRequests).Namespace, nil
4444
}
4545

46-
var cacheStore = cache.NewTTLStore(cacheKeyFunc, 48*time.Hour)
46+
var cacheStore = cache.NewStore(cacheKeyFunc)
4747

4848
// Reconcile handles a reconciliation request for a Pod.
4949
func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
@@ -59,37 +59,40 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
5959
// we'll ignore not-found errors, since they can't be fixed by an immediate
6060
// requeue (we'll need to wait for a new notification), and we can get them
6161
// on deleted requests.
62-
return ctrl.Result{}, err
62+
return ctrl.Result{}, nil
6363
}
64-
log.Error(err, "unable to fetch Pod")
65-
return ctrl.Result{}, err
64+
log.Error(nil, "unable to fetch Pod")
65+
return ctrl.Result{}, nil
6666
}
6767

6868
annotation, err := r.NamespaceOrPodHaveAnnotation(pod, ctx)
6969
if err != nil {
70-
log.Error(err, "failed to get annotations")
71-
return ctrl.Result{}, err
70+
log.Error(nil, "failed to get annotations")
71+
return ctrl.Result{}, nil
7272
}
7373
ignoreAnnotation, err := r.NamespaceOrPodHaveIgnoreAnnotation(pod, ctx)
7474
if err != nil {
75-
log.Error(err, "failed to get annotations")
76-
return ctrl.Result{}, err
75+
log.Error(nil, "failed to get annotations")
76+
return ctrl.Result{}, nil
7777
}
7878

7979
if ((!r.EnableAnnotation) || (r.EnableAnnotation && annotation)) && !ignoreAnnotation {
8080
data, err := r.ClientSet.RESTClient().Get().AbsPath(fmt.Sprintf("apis/metrics.k8s.io/v1beta1/namespaces/%v/pods/%v", pod.Namespace, pod.Name)).DoRaw(ctx)
8181

8282
if err != nil {
83-
log.Error(err, "failed to get stats from pod")
84-
return ctrl.Result{}, err
83+
log.Error(nil, "failed to get stats from pod")
84+
return ctrl.Result{}, nil
8585
}
8686
PodUsageData := GeneratePodRequestsObjectFromRestData(data)
87-
88-
SumPodRequest := PodRequests{Name: pod.Name, ContainerRequests: []ContainerRequests{}}
87+
err, _, _, deploymentName := r.GetPodParentKind(pod, ctx)
88+
if err != nil {
89+
deploymentName = pod.Name
90+
}
91+
SumPodRequest := PodRequests{Name: deploymentName, Namespace: pod.Namespace, ContainerRequests: []ContainerRequests{}}
8992

9093
SumPodRequest.ContainerRequests = PodUsageData.ContainerRequests
9194

92-
LatestPodRequest, err := fetchFromCache(cacheStore, pod.Name)
95+
LatestPodRequest, err := fetchFromCache(cacheStore, deploymentName+pod.Namespace)
9396
if err != nil {
9497
SumPodRequest.Sample = 0
9598
log.Info(fmt.Sprint("Adding cache sample ", SumPodRequest.Sample))

controllers/pod_controller_functions.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"encoding/json"
66
"errors"
7-
"fmt"
87
"strconv"
98
"strings"
109
"time"
@@ -78,7 +77,7 @@ func (r *PodReconciler) UpdateKubeObject(pod client.Object, ctx context.Context)
7877
return ctrl.Result{}, nil
7978
}
8079
log.Error(err, "unable to update pod")
81-
return ctrl.Result{}, err
80+
return ctrl.Result{}, nil
8281
}
8382
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
8483
}
@@ -87,7 +86,7 @@ func UpdatePodController(podspec *corev1.PodSpec, Requests []NewContainerRequest
8786
for _, podContainer := range Requests {
8887
for i, depContainer := range podspec.Containers {
8988
if depContainer.Name == podContainer.Name {
90-
log.Info(fmt.Sprint("Setting", podContainer.Requests))
89+
// log.Info(fmt.Sprint("Setting", podContainer.Requests))
9190
podspec.Containers[i].Resources = podContainer.Requests
9291
}
9392
}
@@ -169,7 +168,7 @@ func GetPodRequests(pod corev1.Pod) PodRequests {
169168
}
170169
containerData = append(containerData, ContainerRequests{Name: c.Name, CPU: int64(nanoCores), Memory: int64(miMemory)})
171170
}
172-
return PodRequests{pod.Name, containerData, 0}
171+
return PodRequests{pod.Name, pod.Namespace, containerData, 0}
173172
}
174173

175174
func addToCache(cacheStore cache.Store, object PodRequests) error {
@@ -209,7 +208,7 @@ func GeneratePodRequestsObjectFromRestData(restData []byte) PodRequests {
209208
kiMemory, _ := strconv.Atoi(strings.ReplaceAll(c.Usage.Memory, "Ki", ""))
210209
containerData = append(containerData, ContainerRequests{Name: c.Name, CPU: int64(nanoCores / 1000000), Memory: int64(kiMemory / 1000)})
211210
}
212-
return PodRequests{data.Metadata.Name, containerData, 0}
211+
return PodRequests{data.Metadata.Name, data.Metadata.Namespace, containerData, 0}
213212
}
214213

215214
func (r *PodReconciler) MinimumUptimeOfPodInParent(pod corev1.Pod, ctx context.Context) bool {
@@ -244,19 +243,16 @@ func (r *PodReconciler) GetPodParentKind(pod corev1.Pod, ctx context.Context) (e
244243
return err, nil, nil, ""
245244
}
246245
deployment, err := r.ClientSet.AppsV1().Deployments(pod.Namespace).Get(ctx, replica.OwnerReferences[0].Name, metav1.GetOptions{})
247-
deployment.Annotations["reqsizer.jatalocks.github.io/changed"] = "true"
248246
if replica.OwnerReferences[0].Kind == "Deployment" {
249247
return err, &deployment.Spec.Template.Spec, deployment, deployment.Name
250248
} else {
251249
return errors.New("Is Owned by Unknown CRD"), nil, nil, ""
252250
}
253251
case "DaemonSet":
254252
deployment, err := r.ClientSet.AppsV1().DaemonSets(pod.Namespace).Get(ctx, pod.OwnerReferences[0].Kind, metav1.GetOptions{})
255-
deployment.Annotations["reqsizer.jatalocks.github.io/changed"] = "true"
256253
return err, &deployment.Spec.Template.Spec, deployment, deployment.Name
257254
case "StatefulSet":
258255
deployment, err := r.ClientSet.AppsV1().StatefulSets(pod.Namespace).Get(ctx, pod.OwnerReferences[0].Kind, metav1.GetOptions{})
259-
deployment.Annotations["reqsizer.jatalocks.github.io/changed"] = "true"
260256
return err, &deployment.Spec.Template.Spec, deployment, deployment.Name
261257
default:
262258
return errors.New("Is Owned by Unknown CRD"), nil, nil, ""

controllers/pod_controller_types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ type PodReconciler struct {
3131
}
3232

3333
type PodRequests struct {
34-
Name string
34+
Name string // Name of Deployment Controller
35+
Namespace string
3536
ContainerRequests []ContainerRequests
3637
Sample int
3738
// TimeSinceFirstSample float64

0 commit comments

Comments
 (0)