Skip to content

Commit 68ba091

Browse files
authored
Merge pull request kubernetes#130844 from danwinship/improved-traffic-distribution
KEP-3015 PreferSameZone/PreferSameNode traffic distribution
2 parents 5c4071c + 88f8e66 commit 68ba091

File tree

64 files changed

+2826
-716
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+2826
-716
lines changed

api/openapi-spec/swagger.json

Lines changed: 22 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/openapi-spec/v3/apis__discovery.k8s.io__v1_openapi.json

Lines changed: 28 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/kube-proxy/app/server.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ type ProxyServer struct {
168168
Recorder events.EventRecorder
169169
NodeRef *v1.ObjectReference
170170
HealthzServer *healthcheck.ProxyHealthServer
171-
Hostname string
171+
NodeName string
172172
PrimaryIPFamily v1.IPFamily
173173
NodeIPs map[v1.IPFamily]net.IP
174174
flagz flagz.Reader
@@ -197,7 +197,7 @@ func newProxyServer(ctx context.Context, config *kubeproxyconfig.KubeProxyConfig
197197
metrics.SetShowHidden()
198198
}
199199

200-
s.Hostname, err = nodeutil.GetHostname(config.HostnameOverride)
200+
s.NodeName, err = nodeutil.GetHostname(config.HostnameOverride)
201201
if err != nil {
202202
return nil, err
203203
}
@@ -207,7 +207,7 @@ func newProxyServer(ctx context.Context, config *kubeproxyconfig.KubeProxyConfig
207207
return nil, err
208208
}
209209

210-
rawNodeIPs := getNodeIPs(ctx, s.Client, s.Hostname)
210+
rawNodeIPs := getNodeIPs(ctx, s.Client, s.NodeName)
211211
s.PrimaryIPFamily, s.NodeIPs = detectNodeIPs(ctx, rawNodeIPs, config.BindAddress)
212212

213213
if len(config.NodePortAddresses) == 1 && config.NodePortAddresses[0] == kubeproxyconfig.NodePortAddressesPrimary {
@@ -226,8 +226,8 @@ func newProxyServer(ctx context.Context, config *kubeproxyconfig.KubeProxyConfig
226226

227227
s.NodeRef = &v1.ObjectReference{
228228
Kind: "Node",
229-
Name: s.Hostname,
230-
UID: types.UID(s.Hostname),
229+
Name: s.NodeName,
230+
UID: types.UID(s.NodeName),
231231
Namespace: "",
232232
}
233233

cmd/kube-proxy/app/server_linux.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ func (o *Options) platformApplyDefaults(config *proxyconfigapi.KubeProxyConfigur
8181
func (s *ProxyServer) platformSetup(ctx context.Context) error {
8282
logger := klog.FromContext(ctx)
8383
if s.Config.DetectLocalMode == proxyconfigapi.LocalModeNodeCIDR {
84-
logger.Info("Watching for node, awaiting podCIDR allocation", "hostname", s.Hostname)
85-
node, err := waitForPodCIDR(ctx, s.Client, s.Hostname)
84+
logger.Info("Watching for node, awaiting podCIDR allocation", "node", s.NodeName)
85+
node, err := waitForPodCIDR(ctx, s.Client, s.NodeName)
8686
if err != nil {
8787
return err
8888
}
@@ -157,7 +157,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
157157
*config.IPTables.LocalhostNodePorts,
158158
int(*config.IPTables.MasqueradeBit),
159159
localDetectors,
160-
s.Hostname,
160+
s.NodeName,
161161
s.NodeIPs,
162162
s.Recorder,
163163
s.HealthzServer,
@@ -179,7 +179,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
179179
*config.IPTables.LocalhostNodePorts,
180180
int(*config.IPTables.MasqueradeBit),
181181
localDetectors[s.PrimaryIPFamily],
182-
s.Hostname,
182+
s.NodeName,
183183
s.NodeIPs[s.PrimaryIPFamily],
184184
s.Recorder,
185185
s.HealthzServer,
@@ -217,7 +217,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
217217
config.Linux.MasqueradeAll,
218218
int(*config.IPTables.MasqueradeBit),
219219
localDetectors,
220-
s.Hostname,
220+
s.NodeName,
221221
s.NodeIPs,
222222
s.Recorder,
223223
s.HealthzServer,
@@ -243,7 +243,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
243243
config.Linux.MasqueradeAll,
244244
int(*config.IPTables.MasqueradeBit),
245245
localDetectors[s.PrimaryIPFamily],
246-
s.Hostname,
246+
s.NodeName,
247247
s.NodeIPs[s.PrimaryIPFamily],
248248
s.Recorder,
249249
s.HealthzServer,
@@ -267,7 +267,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
267267
config.Linux.MasqueradeAll,
268268
int(*config.NFTables.MasqueradeBit),
269269
localDetectors,
270-
s.Hostname,
270+
s.NodeName,
271271
s.NodeIPs,
272272
s.Recorder,
273273
s.HealthzServer,
@@ -285,7 +285,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
285285
config.Linux.MasqueradeAll,
286286
int(*config.NFTables.MasqueradeBit),
287287
localDetectors[s.PrimaryIPFamily],
288-
s.Hostname,
288+
s.NodeName,
289289
s.NodeIPs[s.PrimaryIPFamily],
290290
s.Recorder,
291291
s.HealthzServer,

cmd/kube-proxy/app/server_linux_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ func TestProxyServer_platformSetup(t *testing.T) {
703703
s := &ProxyServer{
704704
Config: tt.config,
705705
Client: client,
706-
Hostname: "nodename",
706+
NodeName: "nodename",
707707
NodeIPs: map[v1.IPFamily]net.IP{
708708
v1.IPv4Protocol: netutils.ParseIPSloppy("127.0.0.1"),
709709
v1.IPv6Protocol: net.IPv6zero,

cmd/kube-proxy/app/server_windows.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
9393
proxier, err = winkernel.NewDualStackProxier(
9494
config.SyncPeriod.Duration,
9595
config.MinSyncPeriod.Duration,
96-
s.Hostname,
96+
s.NodeName,
9797
s.NodeIPs,
9898
s.Recorder,
9999
s.HealthzServer,
@@ -105,7 +105,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
105105
s.PrimaryIPFamily,
106106
config.SyncPeriod.Duration,
107107
config.MinSyncPeriod.Duration,
108-
s.Hostname,
108+
s.NodeName,
109109
s.NodeIPs[s.PrimaryIPFamily],
110110
s.Recorder,
111111
s.HealthzServer,

pkg/apis/core/types.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4560,12 +4560,27 @@ const (
45604560

45614561
// These are valid values for the TrafficDistribution field of a Service.
45624562
const (
4563-
// Indicates a preference for routing traffic to endpoints that are in the
4564-
// same zone as the client. Setting this value gives implementations
4565-
// permission to make different tradeoffs, e.g. optimizing for proximity
4566-
// rather than equal distribution of load. Users should not set this value
4567-
// if such tradeoffs are not acceptable.
4563+
// Indicates a preference for routing traffic to endpoints that are in the same
4564+
// zone as the client. Users should not set this value unless they have ensured
4565+
// that clients and endpoints are distributed in such a way that the "same zone"
4566+
// preference will not result in endpoints getting overloaded.
45684567
ServiceTrafficDistributionPreferClose = "PreferClose"
4568+
4569+
// Indicates a preference for routing traffic to endpoints that are in the same
4570+
// zone as the client. Users should not set this value unless they have ensured
4571+
// that clients and endpoints are distributed in such a way that the "same zone"
4572+
// preference will not result in endpoints getting overloaded.
4573+
// This is an alias for "PreferClose", but it is an Alpha feature and is only
4574+
// recognized if the PreferSameTrafficDistribution feature gate is enabled.
4575+
ServiceTrafficDistributionPreferSameZone = "PreferSameZone"
4576+
4577+
// Indicates a preference for routing traffic to endpoints that are on the same
4578+
// node as the client. Users should not set this value unless they have ensured
4579+
// that clients and endpoints are distributed in such a way that the "same node"
4580+
// preference will not result in endpoints getting overloaded.
4581+
// This is an Alpha feature and is only recognized if the
4582+
// PreferSameTrafficDistribution feature gate is enabled.
4583+
ServiceTrafficDistributionPreferSameNode = "PreferSameNode"
45694584
)
45704585

45714586
// These are the valid conditions of a service.

pkg/apis/core/validation/validation.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"path/filepath"
2626
"reflect"
2727
"regexp"
28+
"slices"
2829
"strings"
2930
"sync"
3031
"unicode"
@@ -6194,8 +6195,21 @@ func validateServiceTrafficDistribution(service *core.Service) field.ErrorList {
61946195
return allErrs
61956196
}
61966197

6197-
if *service.Spec.TrafficDistribution != v1.ServiceTrafficDistributionPreferClose {
6198-
allErrs = append(allErrs, field.NotSupported(field.NewPath("spec").Child("trafficDistribution"), *service.Spec.TrafficDistribution, []string{v1.ServiceTrafficDistributionPreferClose}))
6198+
var supportedTrafficDistribution []string
6199+
if !utilfeature.DefaultFeatureGate.Enabled(features.PreferSameTrafficDistribution) {
6200+
supportedTrafficDistribution = []string{
6201+
v1.ServiceTrafficDistributionPreferClose,
6202+
}
6203+
} else {
6204+
supportedTrafficDistribution = []string{
6205+
v1.ServiceTrafficDistributionPreferClose,
6206+
v1.ServiceTrafficDistributionPreferSameZone,
6207+
v1.ServiceTrafficDistributionPreferSameNode,
6208+
}
6209+
}
6210+
6211+
if !slices.Contains(supportedTrafficDistribution, *service.Spec.TrafficDistribution) {
6212+
allErrs = append(allErrs, field.NotSupported(field.NewPath("spec").Child("trafficDistribution"), *service.Spec.TrafficDistribution, supportedTrafficDistribution))
61996213
}
62006214

62016215
return allErrs

pkg/apis/core/validation/validation_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16413,12 +16413,38 @@ func TestValidateServiceCreate(t *testing.T) {
1641316413
s.Spec.TrafficDistribution = ptr.To("PreferClose")
1641416414
},
1641516415
numErrs: 0,
16416+
}, {
16417+
name: "valid: trafficDistribution field set to PreferSameZone with feature gate",
16418+
tweakSvc: func(s *core.Service) {
16419+
s.Spec.TrafficDistribution = ptr.To("PreferSameZone")
16420+
},
16421+
featureGates: []featuregate.Feature{features.PreferSameTrafficDistribution},
16422+
numErrs: 0,
16423+
}, {
16424+
name: "valid: trafficDistribution field set to PreferSameNode with feature gate",
16425+
tweakSvc: func(s *core.Service) {
16426+
s.Spec.TrafficDistribution = ptr.To("PreferSameNode")
16427+
},
16428+
featureGates: []featuregate.Feature{features.PreferSameTrafficDistribution},
16429+
numErrs: 0,
1641616430
}, {
1641716431
name: "invalid: trafficDistribution field set to Random",
1641816432
tweakSvc: func(s *core.Service) {
1641916433
s.Spec.TrafficDistribution = ptr.To("Random")
1642016434
},
1642116435
numErrs: 1,
16436+
}, {
16437+
name: "invalid: trafficDistribution field set to PreferSameZone without feature gate",
16438+
tweakSvc: func(s *core.Service) {
16439+
s.Spec.TrafficDistribution = ptr.To("PreferSameZone")
16440+
},
16441+
numErrs: 1,
16442+
}, {
16443+
name: "invalid: trafficDistribution field set to PreferSameNode without feature gate",
16444+
tweakSvc: func(s *core.Service) {
16445+
s.Spec.TrafficDistribution = ptr.To("PreferSameNode")
16446+
},
16447+
numErrs: 1,
1642216448
},
1642316449
}
1642416450

pkg/apis/discovery/types.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,16 @@ type EndpointConditions struct {
133133

134134
// EndpointHints provides hints describing how an endpoint should be consumed.
135135
type EndpointHints struct {
136-
// forZones indicates the zone(s) this endpoint should be consumed by to
137-
// enable topology aware routing. May contain a maximum of 8 entries.
136+
// forZones indicates the zone(s) this endpoint should be consumed by when
137+
// using topology aware routing. May contain a maximum of 8 entries.
138138
ForZones []ForZone
139+
140+
// forNodes indicates the node(s) this endpoint should be consumed by when
141+
// using topology aware routing.
142+
// This is an Alpha feature and is only used when the PreferSameTrafficDistribution
143+
// feature gate is enabled. May contain a maximum of 8 entries.
144+
// +featureGate=PreferSameTrafficDistribution
145+
ForNodes []ForNode
139146
}
140147

141148
// ForZone provides information about which zones should consume this endpoint.
@@ -144,6 +151,12 @@ type ForZone struct {
144151
Name string
145152
}
146153

154+
// ForNode provides information about which nodes should consume this endpoint.
155+
type ForNode struct {
156+
// name represents the name of the node.
157+
Name string
158+
}
159+
147160
// EndpointPort represents a Port used by an EndpointSlice.
148161
type EndpointPort struct {
149162
// The name of this port. All ports in an EndpointSlice must have a unique

0 commit comments

Comments
 (0)