@cryptotaxi247 / netdata-1 / commits / b62aac1ef

improvement(go.d/k8sstate): add deployment conditions (#19662)

Ilya Mashchenko committed Feb 17, 2025 at 22:26 UTC b62aac1ef3cb73a70118bcab317b4e57d1ed5233
6 files changed +64 -17
src/go/plugin/go.d/collector/k8s_state/charts.go
+17 -1
@@ -56,7 +56,8 @@ const (
56 )
57
58 const (
59 - prioDeploymentReplicas = 50500 + iota
59 + prioDeploymentConditions = 50500 + iota
60 + prioDeploymentReplicas
61 prioDeploymentAge
62 )
63
@@ -129,6 +130,7 @@ var containerChartsTmpl = module.Charts{
130 }
131
132 var deploymentChartsTmpl = module.Charts{
133 + deploymentConditionStatusChartTmpl.Copy(),
134 deploymentReplicasChartTmpl.Copy(),
135 deploymentAgeChartTmpl.Copy(),
136 }
@@ -759,6 +761,20 @@ func (c *Collector) addContainerCharts(ps *podState, cs *containerState) {
761 }
762
763 var (
764 + deploymentConditionStatusChartTmpl = module.Chart{
765 + IDSep: true,
766 + ID: "deployment_%s.conditions",
767 + Title: "Deployment Conditions",
768 + Units: "status",
769 + Fam: "deployment conditions",
770 + Ctx: "k8s_state.deployment_conditions",
771 + Priority: prioDeploymentConditions,
772 + Dims: module.Dims{
773 + {ID: "deploy_%s_condition_available", Name: "available"},
774 + {ID: "deploy_%s_condition_replica_failure", Name: "replica_failure"},
775 + {ID: "deploy_%s_condition_progressing", Name: "progressing"},
776 + },
777 + }
778 deploymentReplicasChartTmpl = module.Chart{
779 IDSep: true,
780 ID: "deployment_%s.replicas",
src/go/plugin/go.d/collector/k8s_state/collect.go
+21 -12
@@ -9,10 +9,11 @@ import (
9 "slices"
10 "time"
11
12 + appsv1 "k8s.io/api/apps/v1"
13 + corev1 "k8s.io/api/core/v1"
14 +
15 "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/module"
16 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/metrix"
14 -
15 - corev1 "k8s.io/api/core/v1"
17 )
18
19 const precision = 1000
@@ -331,21 +332,29 @@ func (c *Collector) collectDeploymentState(mx map[string]int64) {
332 mx[px+"current_replicas"] = ds.availableReplicas
333 mx[px+"ready_replicas"] = ds.readyReplicas
334
335 + mx[px+"condition_available"] = 0
336 + mx[px+"condition_progressing"] = 0
337 + mx[px+"condition_replica_failure"] = 0
338 +
339 + for _, cond := range ds.conditions {
340 + v := metrix.Bool(cond.Status == corev1.ConditionTrue)
341 + switch cond.Type {
342 + case appsv1.DeploymentAvailable:
343 + // https://github.com/kubernetes/kubernetes/blob/2b3da7dfc846fec7c4044a320f8f38b4a45367a3/pkg/controller/deployment/sync.go#L518-L525
344 + mx[px+"condition_available"] = v
345 + case appsv1.DeploymentProgressing:
346 + mx[px+"condition_available"] = v
347 + case appsv1.DeploymentReplicaFailure:
348 + mx[px+"condition_replica_failure"] = v
349 + }
350 + }
351 +
352 return false
353 })
354 }
355
356 func condStatusToInt(cs corev1.ConditionStatus) int64 {
339 - switch cs {
340 - case corev1.ConditionFalse:
341 - return 0
342 - case corev1.ConditionTrue:
343 - return 1
344 - case corev1.ConditionUnknown:
345 - return 0
346 - default:
347 - return 0
348 - }
357 + return metrix.Bool(cs == corev1.ConditionTrue)
358 }
359
360 func calcPercentage(value, total int64) int64 {
src/go/plugin/go.d/collector/k8s_state/collector_test.go
+13 -4
@@ -371,6 +371,13 @@ func TestCollector_Collect(t *testing.T) {
371 step1 := func(t *testing.T, collr *Collector) {
372 mx := collr.Collect(context.Background())
373 expected := map[string]int64{
374 + "deploy_default_replicaset01_age": 3,
375 + "deploy_default_replicaset01_condition_available": 1,
376 + "deploy_default_replicaset01_condition_progressing": 0,
377 + "deploy_default_replicaset01_condition_replica_failure": 0,
378 + "deploy_default_replicaset01_current_replicas": 1,
379 + "deploy_default_replicaset01_desired_replicas": 2,
380 + "deploy_default_replicaset01_ready_replicas": 3,
381 "discovery_node_discoverer_state": 1,
382 "discovery_pod_discoverer_state": 1,
383 "node_node01_age": 3,
@@ -480,10 +487,6 @@ func TestCollector_Collect(t *testing.T) {
487 "pod_default_pod01_status_reason_Other": 0,
488 "pod_default_pod01_status_reason_Shutdown": 0,
489 "pod_default_pod01_status_reason_UnexpectedAdmissionError": 0,
483 - "deploy_default_replicaset01_age": 3,
484 - "deploy_default_replicaset01_current_replicas": 1,
485 - "deploy_default_replicaset01_desired_replicas": 2,
486 - "deploy_default_replicaset01_ready_replicas": 3,
490 }
491
492 copyAge(expected, mx)
@@ -986,6 +989,12 @@ func newDeployment(name string) *appsv1.Deployment {
989 CreationTimestamp: metav1.Time{Time: time.Now()},
990 },
991 Status: appsv1.DeploymentStatus{
992 + Conditions: []appsv1.DeploymentCondition{
993 + {
994 + Type: appsv1.DeploymentAvailable,
995 + Status: corev1.ConditionTrue,
996 + },
997 + },
998 AvailableReplicas: 1,
999 Replicas: 2,
1000 ReadyReplicas: 3,
src/go/plugin/go.d/collector/k8s_state/metadata.yaml
+8
@@ -225,6 +225,14 @@ modules:
225 - name: k8s_namespace
226 description: Namespace.
227 metrics:
228 + - name: k8s_state.deployment_conditions
229 + description: Deployment Conditions
230 + unit: 'status'
231 + chart_type: line
232 + dimensions:
233 + - name: available
234 + - name: replica_failure
235 + - name: progressing
236 - name: k8s_state.deployment_replicas
237 description: Deployment Replicas
238 unit: 'replicas'
src/go/plugin/go.d/collector/k8s_state/state.go
+3
@@ -6,6 +6,7 @@ import (
6 "sync"
7 "time"
8
9 + appsv1 "k8s.io/api/apps/v1"
10 corev1 "k8s.io/api/core/v1"
11 )
12
@@ -166,6 +167,8 @@ type deploymentState struct {
167 name string
168 namespace string
169
170 + conditions []appsv1.DeploymentCondition
171 +
172 creationTime time.Time
173 replicas int64 // desired
174 availableReplicas int64 // current
src/go/plugin/go.d/collector/k8s_state/update_deployment_state.go
+2
@@ -29,6 +29,8 @@ func (c *Collector) updateDeploymentState(r resource) {
29 ds.creationTime = deploy.CreationTimestamp.Time
30 }
31
32 + ds.conditions = deploy.Status.Conditions
33 +
34 ds.replicas = int64(deploy.Status.Replicas)
35 ds.availableReplicas = int64(deploy.Status.AvailableReplicas)
36 ds.readyReplicas = int64(deploy.Status.ReadyReplicas)