mirror of
https://github.com/coredns/coredns.git
synced 2026-08-20 23:08:28 -04:00
plugin/kubernetes: Add support for topology-aware headless services via "az-pinned" subdomains (#8388)
This commit is contained in:
@@ -2,6 +2,8 @@ package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"strings"
|
||||
|
||||
discovery "k8s.io/api/discovery/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -17,6 +19,12 @@ type Endpoints struct {
|
||||
Index string
|
||||
IndexIP []string
|
||||
Subsets []EndpointSubset
|
||||
// Zones maps address IPs to their topology.kubernetes.io/zone,
|
||||
// lowercased. Nil unless the kubernetes plugin's `zonal` option
|
||||
// selected the zone-retaining transform, so default configurations
|
||||
// carry one nil pointer per slice and their addresses stay exactly
|
||||
// as slim as before.
|
||||
Zones map[string]string
|
||||
|
||||
*Empty
|
||||
}
|
||||
@@ -48,6 +56,18 @@ func EndpointsKey(name, namespace string) string { return name + "." + namespace
|
||||
|
||||
// EndpointSliceToEndpoints converts a *discovery.EndpointSlice to a *Endpoints.
|
||||
func EndpointSliceToEndpoints(obj meta.Object) (meta.Object, error) {
|
||||
return endpointSliceToEndpoints(obj, false /* withZones */)
|
||||
}
|
||||
|
||||
// EndpointSliceToEndpointsWithZones is EndpointSliceToEndpoints, but also
|
||||
// retains each endpoint's topology zone. Used only when the kubernetes
|
||||
// plugin's zonal option is enabled, so the default configuration's cache
|
||||
// stays exactly as slim as before.
|
||||
func EndpointSliceToEndpointsWithZones(obj meta.Object) (meta.Object, error) {
|
||||
return endpointSliceToEndpoints(obj, true /* withZones */)
|
||||
}
|
||||
|
||||
func endpointSliceToEndpoints(obj meta.Object, withZones bool) (meta.Object, error) {
|
||||
ends, ok := obj.(*discovery.EndpointSlice)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected object %v", obj)
|
||||
@@ -92,6 +112,14 @@ func EndpointSliceToEndpoints(obj meta.Object) (meta.Object, error) {
|
||||
if end.Hostname != nil {
|
||||
ea.Hostname = *end.Hostname
|
||||
}
|
||||
if withZones && end.Zone != nil {
|
||||
if e.Zones == nil {
|
||||
e.Zones = make(map[string]string)
|
||||
}
|
||||
// Lowercased once here: qnames arrive case-folded, so
|
||||
// lookups compare without folding per query.
|
||||
e.Zones[a] = strings.ToLower(*end.Zone)
|
||||
}
|
||||
// ignore pod names that are too long to be a valid label
|
||||
if end.TargetRef != nil && len(end.TargetRef.Name) < 64 {
|
||||
ea.TargetRefName = end.TargetRef.Name
|
||||
@@ -144,6 +172,9 @@ func (e *Endpoints) DeepCopyObject() runtime.Object {
|
||||
Subsets: make([]EndpointSubset, len(e.Subsets)),
|
||||
}
|
||||
copy(e1.IndexIP, e.IndexIP)
|
||||
if e.Zones != nil {
|
||||
e1.Zones = maps.Clone(e.Zones)
|
||||
}
|
||||
|
||||
for i, eps := range e.Subsets {
|
||||
sub := EndpointSubset{
|
||||
|
||||
Reference in New Issue
Block a user