plugin/k8s_external: Resolve headless services (#5505)

*add option for resolving headless Services without external IPs in k8s_external

Signed-off-by: Tomas Kohout <tomas.kohout1995@gmail.com>
This commit is contained in:
TomasKohout
2022-08-30 20:59:27 +02:00
committed by GitHub
parent b218b56063
commit 6782b7fb42
15 changed files with 491 additions and 81 deletions

View File

@@ -2,9 +2,11 @@ package external
import (
"context"
"strings"
"github.com/coredns/coredns/plugin"
"github.com/coredns/coredns/plugin/etcd/msg"
"github.com/coredns/coredns/plugin/kubernetes"
"github.com/coredns/coredns/plugin/transfer"
"github.com/coredns/coredns/request"
@@ -40,7 +42,7 @@ func (e *External) Transfer(zone string, serial uint32) (<-chan []dns.RR, error)
ch <- []dns.RR{&dns.NS{Hdr: nsHdr, Ns: nsName}}
// Add Nameserver A/AAAA records
nsRecords := e.externalAddrFunc(state)
nsRecords := e.externalAddrFunc(state, e.headless)
for i := range nsRecords {
// externalAddrFunc returns incomplete header names, correct here
nsRecords[i].Header().Name = nsName
@@ -48,10 +50,12 @@ func (e *External) Transfer(zone string, serial uint32) (<-chan []dns.RR, error)
ch <- []dns.RR{nsRecords[i]}
}
svcs := e.externalServicesFunc(zone)
svcs, headlessSvcs := e.externalServicesFunc(zone, e.headless)
srvSeen := make(map[string]struct{})
for i := range svcs {
name := msg.Domain(svcs[i].Key)
if svcs[i].TargetStrip == 0 {
// Add Service A/AAAA records
s := request.Request{Req: &dns.Msg{Question: []dns.Question{{Name: name}}}}
@@ -81,6 +85,55 @@ func (e *External) Transfer(zone string, serial uint32) (<-chan []dns.RR, error)
}
}
}
for key, svcs := range headlessSvcs {
// we have to strip the leading key because it's either port.protocol or endpoint
name := msg.Domain(key[:strings.LastIndex(key, "/")])
switchKey := key[strings.LastIndex(key, "/")+1:]
switch switchKey {
case kubernetes.Endpoint:
// headless.namespace.example.com records
s := request.Request{Req: &dns.Msg{Question: []dns.Question{{Name: name}}}}
as, _ := e.a(ctx, svcs, s)
if len(as) > 0 {
ch <- as
}
aaaas, _ := e.aaaa(ctx, svcs, s)
if len(aaaas) > 0 {
ch <- aaaas
}
// Add bare SRV record, ensuring uniqueness
recs, _ := e.srv(ctx, svcs, s)
ch <- recs
for _, srv := range recs {
ch <- []dns.RR{srv}
}
for i := range svcs {
// endpoint.headless.namespace.example.com record
s := request.Request{Req: &dns.Msg{Question: []dns.Question{{Name: msg.Domain(svcs[i].Key)}}}}
as, _ := e.a(ctx, []msg.Service{svcs[i]}, s)
if len(as) > 0 {
ch <- as
}
aaaas, _ := e.aaaa(ctx, []msg.Service{svcs[i]}, s)
if len(aaaas) > 0 {
ch <- aaaas
}
// Add bare SRV record, ensuring uniqueness
recs, _ := e.srv(ctx, []msg.Service{svcs[i]}, s)
ch <- recs
for _, srv := range recs {
ch <- []dns.RR{srv}
}
}
case kubernetes.PortProtocol:
s := request.Request{Req: &dns.Msg{Question: []dns.Question{{Name: name}}}}
recs, _ := e.srv(ctx, svcs, s)
ch <- recs
}
}
ch <- []dns.RR{soa}
close(ch)
}()