From ac1b747121d96ac775d4578b38fed03ed1e38985 Mon Sep 17 00:00:00 2001 From: Maxim Ivanov Date: Tue, 25 Aug 2026 13:23:07 +0100 Subject: [PATCH] feat(kube_inventory): collect metrics for native sidecar containers --- plugins/inputs/kube_inventory/pod.go | 19 +++++-- plugins/inputs/kube_inventory/pod_test.go | 64 +++++++++++++++++++++++ 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/plugins/inputs/kube_inventory/pod.go b/plugins/inputs/kube_inventory/pod.go index 38702b5e75dcf..04f19500b2417 100644 --- a/plugins/inputs/kube_inventory/pod.go +++ b/plugins/inputs/kube_inventory/pod.go @@ -35,12 +35,23 @@ func (ki *KubernetesInventory) gatherPod(p *corev1.Pod, acc telegraf.Accumulator return } - containerList := make(map[string]*corev1.ContainerStatus, len(p.Status.ContainerStatuses)) - for i := range p.Status.ContainerStatuses { - containerList[p.Status.ContainerStatuses[i].Name] = &p.Status.ContainerStatuses[i] + initContainers := make([]corev1.Container, 0, len(p.Spec.InitContainers)) + for _, c := range p.Spec.InitContainers { + if c.RestartPolicy != nil && *c.RestartPolicy == corev1.ContainerRestartPolicyAlways { + initContainers = append(initContainers, c) + } + } + ki.gatherPodContainers(p, initContainers, p.Status.InitContainerStatuses, acc) + ki.gatherPodContainers(p, p.Spec.Containers, p.Status.ContainerStatuses, acc) +} + +func (ki *KubernetesInventory) gatherPodContainers(p *corev1.Pod, containers []corev1.Container, statuses []corev1.ContainerStatus, acc telegraf.Accumulator) { + containerList := make(map[string]*corev1.ContainerStatus, len(statuses)) + for i := range statuses { + containerList[statuses[i].Name] = &statuses[i] } - for _, c := range p.Spec.Containers { + for _, c := range containers { cs, ok := containerList[c.Name] if !ok { cs = &corev1.ContainerStatus{} diff --git a/plugins/inputs/kube_inventory/pod_test.go b/plugins/inputs/kube_inventory/pod_test.go index 5888ab787a8ff..336f085ace66a 100644 --- a/plugins/inputs/kube_inventory/pod_test.go +++ b/plugins/inputs/kube_inventory/pod_test.go @@ -463,6 +463,70 @@ func TestPod(t *testing.T) { } } +func TestPodInitContainerResources(t *testing.T) { + ki := &KubernetesInventory{} + require.NoError(t, ki.createSelectorFilters()) + + restartPolicy := corev1.ContainerRestartPolicyAlways + acc := new(testutil.Accumulator) + ki.gatherPod(&corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "pod1", + Namespace: "ns1", + }, + Spec: corev1.PodSpec{ + NodeName: "node1", + InitContainers: []corev1.Container{ + { + Name: "sidecar", + Image: "image1:latest", + RestartPolicy: &restartPolicy, + Resources: corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + "memory": resource.MustParse("256Mi"), + }, + }, + }, + {Name: "init", Image: "image2"}, + }, + }, + Status: corev1.PodStatus{ + Phase: "Succeeded", + InitContainerStatuses: []corev1.ContainerStatus{ + { + Name: "sidecar", + State: corev1.ContainerState{ + Terminated: &corev1.ContainerStateTerminated{Reason: "Completed"}, + }, + }, + {Name: "init"}, + }, + }, + }, acc) + + require.Len(t, acc.Metrics, 1) + acc.AssertContainsTaggedFields(t, podContainerMeasurement, + map[string]interface{}{ + "restarts_total": int32(0), + "state_code": 1, + "state_reason": "Completed", + "terminated_reason": "Completed", + "resource_limits_memory_bytes": int64(268435456), + }, + map[string]string{ + "container_name": "sidecar", + "image": "image1", + "namespace": "ns1", + "node_name": "node1", + "pod_name": "pod1", + "phase": "Succeeded", + "readiness": "unready", + "state": "terminated", + "version": "latest", + }) +} + func TestPodSelectorFilter(t *testing.T) { cli := &client{} now := time.Now()