Skip to content

Commit e360afe

Browse files
authored
[loadbalancingexporter] Support the timeout period of k8s resolver list watch can be configured (#31904)
**Link to tracking Issue:** close #31757 --------- Signed-off-by: Jared Tan <[email protected]>
1 parent e677a5a commit e360afe

File tree

6 files changed

+51
-9
lines changed

6 files changed

+51
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: loadbalancingexporter
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Support the timeout period of k8s resolver list watch can be configured.
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [31757]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []

exporter/loadbalancingexporter/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Refer to [config.yaml](./testdata/config.yaml) for detailed examples on using th
7070
* The `k8s` node accepts the following optional properties:
7171
* `service` Kubernetes service to resolve, e.g. `lb-svc.lb-ns`. If no namespace is specified, an attempt will be made to infer the namespace for this collector, and if this fails it will fall back to the `default` namespace.
7272
* `ports` port to be used for exporting the traces to the addresses resolved from `service`. If `ports` is not specified, the default port 4317 is used. When multiple ports are specified, two backends are added to the load balancer as if they were at different pods.
73+
* `timeout` resolver timeout in go-Duration format, e.g. `5s`, `1d`, `30m`. If not specified, `1s` will be used.
7374
* The `awsCloudMap` node accepts the following properties:
7475
* `namespace` The CloudMap namespace where the service is register, e.g. `cloudmap`. If no `namespace` is specified, this will fail to start the Load Balancer exporter.
7576
* `serviceName` The name of the service that you specified when you registered the instance, e.g. `otelcollectors`. If no `serviceName` is specified, this will fail to start the Load Balancer exporter.

exporter/loadbalancingexporter/config.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ type DNSResolver struct {
5454

5555
// K8sSvcResolver defines the configuration for the DNS resolver
5656
type K8sSvcResolver struct {
57-
Service string `mapstructure:"service"`
58-
Ports []int32 `mapstructure:"ports"`
57+
Service string `mapstructure:"service"`
58+
Ports []int32 `mapstructure:"ports"`
59+
Timeout time.Duration `mapstructure:"timeout"`
5960
}
6061

6162
type AWSCloudMapResolver struct {

exporter/loadbalancingexporter/loadbalancer.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func newLoadBalancer(params exporter.CreateSettings, cfg component.Config, facto
8585
if err != nil {
8686
return nil, err
8787
}
88-
res, err = newK8sResolver(clt, k8sLogger, oCfg.Resolver.K8sSvc.Service, oCfg.Resolver.K8sSvc.Ports)
88+
res, err = newK8sResolver(clt, k8sLogger, oCfg.Resolver.K8sSvc.Service, oCfg.Resolver.K8sSvc.Ports, oCfg.Resolver.K8sSvc.Timeout)
8989
if err != nil {
9090
return nil, err
9191
}

exporter/loadbalancingexporter/resolver_k8s.go

+17-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"strconv"
1414
"strings"
1515
"sync"
16+
"time"
1617

1718
"go.opencensus.io/stats"
1819
"go.opencensus.io/tag"
@@ -37,6 +38,10 @@ var (
3738
k8sResolverSuccessFalseMutators = []tag.Mutator{k8sResolverMutator, successFalseMutator}
3839
)
3940

41+
const (
42+
defaultListWatchTimeout = 1 * time.Second
43+
)
44+
4045
type k8sResolver struct {
4146
logger *zap.Logger
4247
svcName string
@@ -48,6 +53,8 @@ type k8sResolver struct {
4853
epsListWatcher cache.ListerWatcher
4954
endpointsStore *sync.Map
5055

56+
lwTimeout time.Duration
57+
5158
endpoints []string
5259
onChangeCallbacks []func([]string)
5360

@@ -60,12 +67,16 @@ type k8sResolver struct {
6067
func newK8sResolver(clt kubernetes.Interface,
6168
logger *zap.Logger,
6269
service string,
63-
ports []int32) (*k8sResolver, error) {
70+
ports []int32, timeout time.Duration) (*k8sResolver, error) {
6471

6572
if len(service) == 0 {
6673
return nil, errNoSvc
6774
}
6875

76+
if timeout == 0 {
77+
timeout = defaultListWatchTimeout
78+
}
79+
6980
nAddr := strings.SplitN(service, ".", 2)
7081
name, namespace := nAddr[0], "default"
7182
if len(nAddr) > 1 {
@@ -84,12 +95,12 @@ func newK8sResolver(clt kubernetes.Interface,
8495
epsListWatcher := &cache.ListWatch{
8596
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
8697
options.FieldSelector = epsSelector
87-
options.TimeoutSeconds = ptr.To[int64](1)
98+
options.TimeoutSeconds = ptr.To[int64](int64(timeout.Seconds()))
8899
return clt.CoreV1().Endpoints(namespace).List(context.Background(), options)
89100
},
90101
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
91102
options.FieldSelector = epsSelector
92-
options.TimeoutSeconds = ptr.To[int64](1)
103+
options.TimeoutSeconds = ptr.To[int64](int64(timeout.Seconds()))
93104
return clt.CoreV1().Endpoints(namespace).Watch(context.Background(), options)
94105
},
95106
}
@@ -106,6 +117,7 @@ func newK8sResolver(clt kubernetes.Interface,
106117
epsListWatcher: epsListWatcher,
107118
handler: h,
108119
stopCh: make(chan struct{}),
120+
lwTimeout: timeout,
109121
}
110122
h.callback = r.resolve
111123

@@ -134,7 +146,8 @@ func (r *k8sResolver) start(_ context.Context) error {
134146
r.logger.Debug("K8s service resolver started",
135147
zap.String("service", r.svcName),
136148
zap.String("namespace", r.svcNs),
137-
zap.Int32s("ports", r.port))
149+
zap.Int32s("ports", r.port),
150+
zap.Duration("timeout", r.lwTimeout))
138151
return nil
139152
}
140153

exporter/loadbalancingexporter/resolver_k8s_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func TestK8sResolve(t *testing.T) {
5656
}
5757

5858
cl := fake.NewSimpleClientset(endpoint)
59-
res, err := newK8sResolver(cl, zap.NewNop(), service, ports)
59+
res, err := newK8sResolver(cl, zap.NewNop(), service, ports, defaultListWatchTimeout)
6060
require.NoError(t, err)
6161

6262
require.NoError(t, res.start(context.Background()))
@@ -241,7 +241,7 @@ func Test_newK8sResolver(t *testing.T) {
241241
}
242242
for _, tt := range tests {
243243
t.Run(tt.name, func(t *testing.T) {
244-
got, err := newK8sResolver(fake.NewSimpleClientset(), tt.args.logger, tt.args.service, tt.args.ports)
244+
got, err := newK8sResolver(fake.NewSimpleClientset(), tt.args.logger, tt.args.service, tt.args.ports, defaultListWatchTimeout)
245245
if tt.wantErr != nil {
246246
require.Error(t, err, tt.wantErr)
247247
} else {

0 commit comments

Comments
 (0)