mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-21 09:57:52 +00:00
Adding support for TopologyAwareHints to kube-proxy
This commit is contained in:
@@ -19,11 +19,80 @@ package proxy
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
// FilterTopologyEndpoint returns the appropriate endpoints based on the cluster
|
||||
// topology.
|
||||
// FilterEndpoints filters endpoints based on Service configuration, node
|
||||
// labels, and enabled feature gates. This is primarily used to enable topology
|
||||
// aware routing.
|
||||
func FilterEndpoints(endpoints []Endpoint, svcInfo ServicePort, nodeLabels map[string]string) []Endpoint {
|
||||
if svcInfo.NodeLocalExternal() || !utilfeature.DefaultFeatureGate.Enabled(features.EndpointSliceProxying) {
|
||||
return endpoints
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceTopology) {
|
||||
return deprecatedTopologyFilter(nodeLabels, svcInfo.TopologyKeys(), endpoints)
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) && svcInfo.NodeLocalInternal() {
|
||||
return filterEndpointsInternalTrafficPolicy(svcInfo.InternalTrafficPolicy(), endpoints)
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.TopologyAwareHints) {
|
||||
return filterEndpointsWithHints(endpoints, svcInfo.HintsAnnotation(), nodeLabels)
|
||||
}
|
||||
|
||||
return endpoints
|
||||
}
|
||||
|
||||
// filterEndpointsWithHints provides filtering based on the hints included in
|
||||
// EndpointSlices. If any of the following are true, the full list of endpoints
|
||||
// will be returned without any filtering:
|
||||
// * The AnnotationTopologyAwareHints annotation is not set to "auto" for this
|
||||
// Service.
|
||||
// * No zone is specified in node labels.
|
||||
// * No endpoints for this Service have a hint pointing to the zone this
|
||||
// instance of kube-proxy is running in.
|
||||
// * One or more endpoints for this Service do not have hints specified.
|
||||
func filterEndpointsWithHints(endpoints []Endpoint, hintsAnnotation string, nodeLabels map[string]string) []Endpoint {
|
||||
if hintsAnnotation != "auto" {
|
||||
if hintsAnnotation != "" && hintsAnnotation != "disabled" {
|
||||
klog.Warningf("Skipping topology aware endpoint filtering since Service has unexpected value for %s annotation: %s", v1.AnnotationTopologyAwareHints, hintsAnnotation)
|
||||
}
|
||||
return endpoints
|
||||
}
|
||||
|
||||
zone, ok := nodeLabels[v1.LabelTopologyZone]
|
||||
if !ok || zone == "" {
|
||||
klog.Warningf("Skipping topology aware endpoint filtering since node is missing %s label", v1.LabelTopologyZone)
|
||||
return endpoints
|
||||
}
|
||||
|
||||
filteredEndpoints := []Endpoint{}
|
||||
|
||||
for _, endpoint := range endpoints {
|
||||
if endpoint.GetZoneHints().Len() == 0 {
|
||||
klog.Warningf("Skipping topology aware endpoint filtering since one or more endpoints is missing a zone hint")
|
||||
return endpoints
|
||||
}
|
||||
if endpoint.GetZoneHints().Has(zone) {
|
||||
filteredEndpoints = append(filteredEndpoints, endpoint)
|
||||
}
|
||||
}
|
||||
|
||||
if len(filteredEndpoints) > 0 {
|
||||
klog.Warningf("Skipping topology aware endpoint filtering since no hints were provided for zone %s", zone)
|
||||
return filteredEndpoints
|
||||
}
|
||||
|
||||
return endpoints
|
||||
}
|
||||
|
||||
// deprecatedTopologyFilter returns the appropriate endpoints based on the
|
||||
// cluster topology. This will be removed in an upcoming release along with the
|
||||
// ServiceTopology feature gate.
|
||||
//
|
||||
// This uses the current node's labels, which contain topology information, and
|
||||
// the required topologyKeys to find appropriate endpoints. If both the endpoint's
|
||||
// topology and the current node have matching values for topologyKeys[0], the
|
||||
@@ -40,7 +109,7 @@ import (
|
||||
//
|
||||
// If topologyKeys is not specified or empty, no topology constraints will be
|
||||
// applied and this will return all endpoints.
|
||||
func FilterTopologyEndpoint(nodeLabels map[string]string, topologyKeys []string, endpoints []Endpoint) []Endpoint {
|
||||
func deprecatedTopologyFilter(nodeLabels map[string]string, topologyKeys []string, endpoints []Endpoint) []Endpoint {
|
||||
// Do not filter endpoints if service has no topology keys.
|
||||
if len(topologyKeys) == 0 {
|
||||
return endpoints
|
||||
@@ -81,13 +150,13 @@ func FilterTopologyEndpoint(nodeLabels map[string]string, topologyKeys []string,
|
||||
return filteredEndpoints
|
||||
}
|
||||
|
||||
// FilterLocalEndpoint returns the node local endpoints based on configured
|
||||
// InternalTrafficPolicy.
|
||||
// filterEndpointsInternalTrafficPolicy returns the node local endpoints based
|
||||
// on configured InternalTrafficPolicy.
|
||||
//
|
||||
// If ServiceInternalTrafficPolicy feature gate is off, returns the original
|
||||
// endpoints slice.
|
||||
// EndpointSlice.
|
||||
// Otherwise, if InternalTrafficPolicy is Local, only return the node local endpoints.
|
||||
func FilterLocalEndpoint(internalTrafficPolicy *v1.ServiceInternalTrafficPolicyType, endpoints []Endpoint) []Endpoint {
|
||||
func filterEndpointsInternalTrafficPolicy(internalTrafficPolicy *v1.ServiceInternalTrafficPolicyType, endpoints []Endpoint) []Endpoint {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) {
|
||||
return endpoints
|
||||
}
|
||||
|
Reference in New Issue
Block a user