Skip to content

Commit b2238b9

Browse files
authored
[receiver/k8s_cluster] Do not store unused service data in k8s API cache (open-telemetry#23434)
To reduce RAM utilization. Resolves open-telemetry#23433 This is the last PR to reduce the memory footprint of k8s API informers. Other objects are more static and usually don't have a lot of instances in user clusters, so there is no need to reduce their size.
1 parent 1c84fb2 commit b2238b9

File tree

5 files changed

+119
-18
lines changed

5 files changed

+119
-18
lines changed

receiver/k8sclusterreceiver/informer_transform.go

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/node"
1515
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/pod"
1616
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/replicaset"
17+
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/service"
1718
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/statefulset"
1819
)
1920

@@ -35,6 +36,8 @@ func transformObject(object interface{}) (interface{}, error) {
3536
return demonset.Transform(o), nil
3637
case *appsv1.StatefulSet:
3738
return statefulset.Transform(o), nil
39+
case *corev1.Service:
40+
return service.Transform(o), nil
3841
}
3942
return object, nil
4043
}

receiver/k8sclusterreceiver/informer_transform_test.go

+19
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,25 @@ func TestTransformObject(t *testing.T) {
9393
},
9494
same: false,
9595
},
96+
{
97+
name: "service",
98+
object: &corev1.Service{
99+
Spec: corev1.ServiceSpec{
100+
Selector: map[string]string{
101+
"app": "my-app",
102+
},
103+
Type: corev1.ServiceTypeClusterIP,
104+
},
105+
},
106+
want: &corev1.Service{
107+
Spec: corev1.ServiceSpec{
108+
Selector: map[string]string{
109+
"app": "my-app",
110+
},
111+
},
112+
},
113+
same: false,
114+
},
96115
{
97116
// This is a case where we don't transform the object.
98117
name: "hpa",

receiver/k8sclusterreceiver/internal/pod/pods.go

+2-18
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
package pod // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/pod"
55

66
import (
7-
"fmt"
87
"strings"
98
"time"
109

@@ -17,7 +16,6 @@ import (
1716
batchv1 "k8s.io/api/batch/v1"
1817
corev1 "k8s.io/api/core/v1"
1918
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
20-
"k8s.io/apimachinery/pkg/labels"
2119
"k8s.io/apimachinery/pkg/types"
2220
"k8s.io/client-go/tools/cache"
2321

@@ -26,6 +24,7 @@ import (
2624
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/constants"
2725
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/container"
2826
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/metadata"
27+
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/service"
2928
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/utils"
3029
)
3130

@@ -184,7 +183,7 @@ func GetMetadata(pod *corev1.Pod, mc *metadata.Store, logger *zap.Logger) map[ex
184183
}
185184

186185
if mc.Services != nil {
187-
meta = maps.MergeStringMaps(meta, getPodServiceTags(pod, mc.Services))
186+
meta = maps.MergeStringMaps(meta, service.GetPodServiceTags(pod, mc.Services))
188187
}
189188

190189
if mc.Jobs != nil {
@@ -268,21 +267,6 @@ func logError(err error, ref *v1.OwnerReference, podUID types.UID, logger *zap.L
268267
)
269268
}
270269

271-
// getPodServiceTags returns a set of services associated with the pod.
272-
func getPodServiceTags(pod *corev1.Pod, services cache.Store) map[string]string {
273-
properties := map[string]string{}
274-
275-
for _, ser := range services.List() {
276-
serObj := ser.(*corev1.Service)
277-
if serObj.Namespace == pod.Namespace &&
278-
labels.Set(serObj.Spec.Selector).AsSelectorPreValidated().Matches(labels.Set(pod.Labels)) {
279-
properties[fmt.Sprintf("%s%s", constants.K8sServicePrefix, serObj.Name)] = ""
280-
}
281-
}
282-
283-
return properties
284-
}
285-
286270
// getWorkloadProperties returns workload metadata for provided owner reference.
287271
func getWorkloadProperties(ref *v1.OwnerReference, labelKey string) map[string]string {
288272
uidKey := metadata.GetOTelUIDFromKind(strings.ToLower(ref.Kind))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package service // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/service"
5+
import (
6+
"fmt"
7+
8+
corev1 "k8s.io/api/core/v1"
9+
"k8s.io/apimachinery/pkg/labels"
10+
"k8s.io/client-go/tools/cache"
11+
12+
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/constants"
13+
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/metadata"
14+
)
15+
16+
// Transform transforms the pod to remove the fields that we don't use to reduce RAM utilization.
17+
// IMPORTANT: Make sure to update this function before using new service fields.
18+
func Transform(service *corev1.Service) *corev1.Service {
19+
return &corev1.Service{
20+
ObjectMeta: metadata.TransformObjectMeta(service.ObjectMeta),
21+
Spec: corev1.ServiceSpec{
22+
Selector: service.Spec.Selector,
23+
},
24+
}
25+
}
26+
27+
// GetPodServiceTags returns a set of services associated with the pod.
28+
func GetPodServiceTags(pod *corev1.Pod, services cache.Store) map[string]string {
29+
properties := map[string]string{}
30+
31+
for _, ser := range services.List() {
32+
serObj := ser.(*corev1.Service)
33+
if serObj.Namespace == pod.Namespace &&
34+
labels.Set(serObj.Spec.Selector).AsSelectorPreValidated().Matches(labels.Set(pod.Labels)) {
35+
properties[fmt.Sprintf("%s%s", constants.K8sServicePrefix, serObj.Name)] = ""
36+
}
37+
}
38+
39+
return properties
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package service
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
corev1 "k8s.io/api/core/v1"
11+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
)
13+
14+
func TestTransform(t *testing.T) {
15+
originalService := &corev1.Service{
16+
ObjectMeta: metav1.ObjectMeta{
17+
Name: "my-service",
18+
Namespace: "default",
19+
Labels: map[string]string{
20+
"app": "my-app",
21+
},
22+
Annotations: map[string]string{
23+
"annotation1": "value1",
24+
},
25+
},
26+
Spec: corev1.ServiceSpec{
27+
Selector: map[string]string{
28+
"app": "my-app",
29+
},
30+
Ports: []corev1.ServicePort{
31+
{
32+
Name: "http",
33+
Port: 80,
34+
Protocol: corev1.ProtocolTCP,
35+
},
36+
},
37+
Type: corev1.ServiceTypeClusterIP,
38+
},
39+
}
40+
wantService := &corev1.Service{
41+
ObjectMeta: metav1.ObjectMeta{
42+
Name: "my-service",
43+
Namespace: "default",
44+
Labels: map[string]string{
45+
"app": "my-app",
46+
},
47+
},
48+
Spec: corev1.ServiceSpec{
49+
Selector: map[string]string{
50+
"app": "my-app",
51+
},
52+
},
53+
}
54+
assert.EqualValues(t, wantService, Transform(originalService))
55+
}

0 commit comments

Comments
 (0)