aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2020-07-24 10:33:52 +0200
committerGravatar Miek Gieben <miek@miek.nl> 2020-07-24 10:33:52 +0200
commitccc6e0cff96d0de6737a5228dd9ea59c15c0831d (patch)
tree021bb3524e0ee627ee1a4ed42c5c7e6b4ef3f98d
parent6afcfb83904109b9841779449680ff34a925f948 (diff)
downloadcoredns-ccc6e0cff96d0de6737a5228dd9ea59c15c0831d.tar.gz
coredns-ccc6e0cff96d0de6737a5228dd9ea59c15c0831d.tar.zst
coredns-ccc6e0cff96d0de6737a5228dd9ea59c15c0831d.zip
Use weights from xDS
use the weights as reported. Set prio to 0 to signal it's not used. Signed-off-by: Miek Gieben <miek@miek.nl>
-rw-r--r--plugin/traffic/README.md6
-rw-r--r--plugin/traffic/traffic.go10
-rw-r--r--plugin/traffic/xds/assignment.go14
-rw-r--r--plugin/traffic/xds/client.go4
4 files changed, 21 insertions, 13 deletions
diff --git a/plugin/traffic/README.md b/plugin/traffic/README.md
index 139e4c209..65ca26e68 100644
--- a/plugin/traffic/README.md
+++ b/plugin/traffic/README.md
@@ -108,7 +108,7 @@ For SRV queries all endpoints are returned, the SRV target names are synthesized
## Matching Algorithm
-How are clients match against the data we receive from xDS endpoint?
+How are queries match against the data we receive from xDS endpoint?
1. Does the cluster exist? If not return NXDOMAIN, otherwise continue.
@@ -116,7 +116,9 @@ How are clients match against the data we receive from xDS endpoint?
endpoint return a NODATA response, otherwise continue.
3. If weights are assigned, use those to pick an endpoint, otherwise randomly pick one and return a
- response to the client.
+ response to the client. Weights are copied from the xDS data, priority is not used and set to 0
+ for all SRV records. Note that weights in SRV records are 16 bits, but xDS uses uint32; you have
+ been warned.
## Metrics
diff --git a/plugin/traffic/traffic.go b/plugin/traffic/traffic.go
index 2b3f886b7..977fe914e 100644
--- a/plugin/traffic/traffic.go
+++ b/plugin/traffic/traffic.go
@@ -103,7 +103,7 @@ func (t *Traffic) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
}
m.Answer = []dns.RR{&dns.AAAA{Hdr: dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 5}, AAAA: sockaddr.Address()}}
case dns.TypeSRV:
- sockaddrs, _ := t.c.All(cluster, true)
+ sockaddrs, weights, _ := t.c.All(cluster, true)
m.Answer = make([]dns.RR, 0, len(sockaddrs))
m.Extra = make([]dns.RR, 0, len(sockaddrs))
for i, sa := range sockaddrs {
@@ -111,7 +111,7 @@ func (t *Traffic) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
m.Answer = append(m.Answer, &dns.SRV{
Hdr: dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeSRV, Class: dns.ClassINET, Ttl: 5},
- Priority: 100, Weight: 100, Port: sa.Port(), Target: target})
+ Priority: 0, Weight: uint16(weights[i]), Port: sa.Port(), Target: target})
if sa.Address().To4() == nil {
m.Extra = append(m.Extra, &dns.AAAA{Hdr: dns.RR_Header{Name: target, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 5}, AAAA: sa.Address()})
@@ -120,7 +120,7 @@ func (t *Traffic) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
}
}
case dns.TypeTXT:
- sockaddrs, _ := t.c.All(cluster, false)
+ sockaddrs, weights, _ := t.c.All(cluster, false)
m.Answer = make([]dns.RR, 0, len(sockaddrs))
m.Extra = make([]dns.RR, 0, len(sockaddrs))
for i, sa := range sockaddrs {
@@ -128,7 +128,7 @@ func (t *Traffic) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
m.Answer = append(m.Answer, &dns.TXT{
Hdr: dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 5},
- Txt: []string{"100", "100", strconv.Itoa(int(sa.Port())), target, corepb2.HealthStatus_name[int32(sa.Health)]}})
+ Txt: []string{"0", strconv.Itoa(int(uint16(weights[i]))), strconv.Itoa(int(sa.Port())), target, corepb2.HealthStatus_name[int32(sa.Health)]}})
m.Extra = append(m.Extra, &dns.TXT{Hdr: dns.RR_Header{Name: target, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 5}, Txt: []string{sa.Address().String()}})
}
default:
@@ -162,7 +162,7 @@ func (t *Traffic) serveEndpoint(ctx context.Context, state request.Request, endp
return 0, nil
}
- sockaddrs, _ := t.c.All(cluster, healthy)
+ sockaddrs, _, _ := t.c.All(cluster, healthy)
if len(sockaddrs) < nr {
m.Ns = soa(state.Zone)
m.Rcode = dns.RcodeNameError
diff --git a/plugin/traffic/xds/assignment.go b/plugin/traffic/xds/assignment.go
index 8852dcb96..bf2929d80 100644
--- a/plugin/traffic/xds/assignment.go
+++ b/plugin/traffic/xds/assignment.go
@@ -126,21 +126,27 @@ func (a *assignment) Select(cluster string, healthy bool) (*SocketAddress, bool)
return nil, true
}
-// All returns all healthy endpoints.
-func (a *assignment) All(cluster string, healthy bool) ([]*SocketAddress, bool) {
+// All returns all healthy endpoints, together with their weights.
+func (a *assignment) All(cluster string, healthy bool) ([]*SocketAddress, []uint32, bool) {
cla := a.ClusterLoadAssignment(cluster)
if cla == nil {
- return nil, false
+ return nil, nil, false
}
sa := []*SocketAddress{}
+ we := []uint32{}
for _, ep := range cla.Endpoints {
for _, lb := range ep.GetLbEndpoints() {
if healthy && lb.GetHealthStatus() != corepb2.HealthStatus_HEALTHY {
continue
}
+ weight := lb.GetLoadBalancingWeight().GetValue()
+ if weight > 2^16 {
+ log.Warning("Weight in cluster %q > %d, truncating to %d in SRV responses", cluster, weight, uint16(weight))
+ }
+ we = append(we, weight)
sa = append(sa, &SocketAddress{lb.GetEndpoint().GetAddress().GetSocketAddress(), lb.GetHealthStatus()})
}
}
- return sa, true
+ return sa, we, true
}
diff --git a/plugin/traffic/xds/client.go b/plugin/traffic/xds/client.go
index c55a779e0..387721bc5 100644
--- a/plugin/traffic/xds/client.go
+++ b/plugin/traffic/xds/client.go
@@ -205,9 +205,9 @@ func (c *Client) Select(cluster string, healty bool) (*SocketAddress, bool) {
}
// All returns all endpoints.
-func (c *Client) All(cluster string, healty bool) ([]*SocketAddress, bool) {
+func (c *Client) All(cluster string, healty bool) ([]*SocketAddress, []uint32, bool) {
if cluster == "" {
- return nil, false
+ return nil, nil, false
}
return c.assignments.All(cluster, healty)
}