Skip to content

Commit 70e7568

Browse files
committed
No OD version
1 parent 224c2af commit 70e7568

File tree

1 file changed

+18
-32
lines changed
  • staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory

1 file changed

+18
-32
lines changed

staging/src/k8s.io/apiserver/pkg/storage/storagebackend/factory/etcd3.go

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,9 @@ import (
4242
"k8s.io/klog/v2"
4343

4444
roundrobin "google.golang.org/grpc/balancer/roundrobin" // named import (not blank)
45-
_ "google.golang.org/grpc/balancer/weightedroundrobin"
45+
_ "google.golang.org/grpc/health" // Register health checking service
4646
"google.golang.org/grpc/resolver"
4747
dnsresolver "google.golang.org/grpc/resolver/dns" // named import
48-
_ "google.golang.org/grpc/xds"
49-
_ "google.golang.org/grpc/xds/googledirectpath" // Register xDS Google DirectPath components
5048

5149
"k8s.io/apimachinery/pkg/runtime"
5250
utilnet "k8s.io/apimachinery/pkg/util/net"
@@ -103,12 +101,6 @@ func init() {
103101
resolver.Register(dnsresolver.NewBuilder())
104102
resolver.SetDefaultScheme("dns")
105103
_ = roundrobin.Name
106-
107-
// Enable outlier detection support in gRPC
108-
// This is required for outlier_detection load balancing policy to work
109-
if os.Getenv("GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION") == "" {
110-
os.Setenv("GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION", "true")
111-
}
112104
}
113105

114106
// etcdClientDebugLevel translates ETCD_CLIENT_DEBUG into zap log level.
@@ -338,22 +330,16 @@ var newETCD3Client = func(c storagebackend.TransportConfig) (*kubernetes.Client,
338330
// which seems to be what we want as the metrics will be collected on each attempt (retry)
339331
grpc.WithChainUnaryInterceptor(grpcprom.UnaryClientInterceptor),
340332
grpc.WithChainStreamInterceptor(grpcprom.StreamClientInterceptor),
333+
// Use round-robin load balancing with health checking across all etcd endpoints.
334+
// The DNS resolver will resolve the service name to individual etcd member IPs,
335+
// and round-robin will distribute requests across them. gRPC health checking
336+
// will proactively detect soft failures (slow responses, high error rates) in
337+
// addition to hard failures detected by TCP keepalives.
341338
grpc.WithDefaultServiceConfig(`{
342-
"loadBalancingConfig": [{
343-
"outlier_detection_experimental": {
344-
"interval": "10s",
345-
"base_ejection_time": "30s",
346-
"max_ejection_time": "300s",
347-
"max_ejection_percent": 50,
348-
"failure_percentage_ejection": {
349-
"threshold": 20,
350-
"enforcement_percentage": 100,
351-
"minimum_hosts": 3,
352-
"request_volume": 5
353-
},
354-
"child_policy": [{"round_robin": {}}]
355-
}
356-
}]
339+
"loadBalancingConfig": [{"round_robin": {}}],
340+
"healthCheckConfig": {
341+
"serviceName": ""
342+
}
357343
}`),
358344
}
359345
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerTracing) && c.TracerProvider != nil {
@@ -367,10 +353,10 @@ var newETCD3Client = func(c storagebackend.TransportConfig) (*kubernetes.Client,
367353
dialOptions = append(dialOptions,
368354
grpc.WithStatsHandler(otelgrpc.NewClientHandler(tracingOpts...)))
369355
}
370-
// Configure endpoints for cross-member outlier detection:
371-
// Assume the endpoint is a DNS name (e.g., "dns:///etcd.namespace.svc:2379" or just "etcd.namespace.svc:2379").
372-
// gRPC's DNS resolver will resolve all IPs for the service and create subchannels to each,
373-
// enabling outlier detection to monitor and eject unhealthy members across the etcd cluster.
356+
// Configure endpoints for DNS-based load balancing:
357+
// Use DNS resolution to discover all etcd members. The DNS resolver will resolve the service
358+
// name to individual etcd member IPs, and round-robin load balancing will distribute requests
359+
// across them. etcd's built-in health checking handles failure detection.
374360
endpoints := c.ServerList
375361
useDNSResolver := false
376362

@@ -390,9 +376,9 @@ var newETCD3Client = func(c storagebackend.TransportConfig) (*kubernetes.Client,
390376
}
391377

392378
// IMPORTANT: Custom dialers bypass gRPC's resolver system. When using DNS-based resolution
393-
// for cross-member outlier detection, we must NOT use a custom dialer because it would
394-
// prevent the DNS resolver from resolving the service name to individual etcd member IPs.
395-
// The custom dialer is only needed for direct endpoint connections (non-DNS).
379+
// for load balancing, we must NOT use a custom dialer because it would prevent the DNS
380+
// resolver from resolving the service name to individual etcd member IPs. The custom dialer
381+
// is only needed for direct endpoint connections (non-DNS).
396382
klog.Infof("if egressDialer != nil && !useDNSResolver")
397383
if egressDialer != nil && !useDNSResolver {
398384
dialer := func(ctx context.Context, addr string) (net.Conn, error) {
@@ -408,7 +394,7 @@ var newETCD3Client = func(c storagebackend.TransportConfig) (*kubernetes.Client,
408394
}
409395
dialOptions = append(dialOptions, grpc.WithContextDialer(dialer))
410396
} else if egressDialer != nil && useDNSResolver {
411-
klog.Warningf("Egress dialer is configured but will be skipped for DNS-based outlier detection to allow gRPC DNS resolver to function properly")
397+
klog.Warningf("Egress dialer is configured but will be skipped for DNS-based load balancing to allow gRPC DNS resolver to function properly")
412398
}
413399

414400
klog.Infof("----------------Creating clientv3.Config with endpoints: %v", endpoints)

0 commit comments

Comments
 (0)