From eaa7f0d6ebb9432671fe07800bbfe8b43d7cd847 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Fri, 24 Jan 2020 12:00:07 +0100 Subject: [PATCH] Fix documentation and start parsing localities Signed-off-by: Miek Gieben --- plugin/traffic/README.md | 81 +++++++++++++++++++++++---------------- plugin/traffic/setup.go | 7 ++++ plugin/traffic/traffic.go | 16 ++++++-- 3 files changed, 66 insertions(+), 38 deletions(-) diff --git a/plugin/traffic/README.md b/plugin/traffic/README.md index 7c62708d5..ad77c0c33 100644 --- a/plugin/traffic/README.md +++ b/plugin/traffic/README.md @@ -9,7 +9,7 @@ The *traffic* plugin is a balancer that allows traffic steering, weighted responses and draining of clusters. The cluster information is retrieved from a service discovery manager that implements the service discovery protocols from Envoy -[implements](https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol). It connect to the +[implements](https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol). It connects to the manager using the Aggregated Discovery Service (ADS) protocol. A Cluster in Envoy is defined as: "A group of logically similar endpoints that Envoy connects to." @@ -48,41 +48,52 @@ traffic TO... This enabled the *traffic* plugin, with a default node ID of `coredns` and no TLS. -* **TO...** are the control plane endpoints to connect to. These must start with `grpc://`. The - port number defaults to 443, if not specified. + * **TO...** are the control plane endpoints to connect to. These must start with `grpc://`. The + port number defaults to 443, if not specified. The extended syntax is available if you want more control. ~~~ traffic TO... { node ID - locality REGION,ZONE,SUBZONE [REGION,ZONE,SUBZONE]... + locality REGION[,ZONE[,SUBZONE]] [REGION[,ZONE[,SUBZONE]]]... tls CERT KEY CA tls_servername NAME ignore_health } ~~~ -* `node` **ID** is how *traffic* identifies itself to the control plane. This defaults to `coredns`. -* `locality` has a list of **REGION,ZONE,SUBZONE**s. These tell *traffic* where its running and what should be - considered local traffic. Each **REGION,ZONE,SUBZONE** will be used to match clusters again while generating - responses. The list should descend in proximity. A `*` describes a wild card match. I.e. when - there are 3 regions, US, EU, ASIA, and this CoreDNS is running in EU, you can use: - `locality EU,*,* US,*,*, ASIA,*,*`. Only when the cluster's locality isn't UNKNOWN will this - matching happen. -* `tls` **CERT** **KEY** **CA** define the TLS properties for gRPC connection. If this is omitted an - insecure connection is attempted. From 0 to 3 arguments can be provided with the meaning as described below + * `node` **ID** is how *traffic* identifies itself to the control plane. This defaults to + `coredns`. - * `tls` - no client authentication is used, and the system CAs are used to verify the server certificate - * `tls` **CA** - no client authentication is used, and the file CA is used to verify the server certificate - * `tls` **CERT** **KEY** - client authentication is used with the specified cert/key pair. - The server certificate is verified with the system CAs. - * `tls` **CERT** **KEY** **CA** - client authentication is used with the specified cert/key pair. - The server certificate is verified using the specified CA file. + * `locality` has a list of **REGION,ZONE,SUBZONE** sets. These tell *traffic* where its running + and what should be considered local traffic. Each **REGION,ZONE,SUBZONE** set will be used + to match clusters against while generating responses. The list should descend in proximity. + **ZONE** or **ZONE** *and* **SUBZONE** may be omitted. This signifies a wild card match. + I.e. when there are 3 regions, US, EU, ASIA, and this CoreDNS is running in EU, you can use: + `locality EU US ASIA`. Each list must be separated using spaces. The elements within a set + should be separated with only a comma. -* `tls_servername` **NAME** allows you to set a server name in the TLS configuration. This is needed - because *traffic* connects to an IP address, so it can't infer the server name from it. -* `ignore_health` can be enabled to ignore endpoint health status, this can aid in debugging. + * `tls` **CERT** **KEY** **CA** define the TLS properties for gRPC connection. If this is omitted + an insecure connection is attempted. From 0 to 3 arguments can be provided with the meaning as + described below + + - `tls` - no client authentication is used, and the system CAs are used to verify the server + certificate + + - `tls` **CA** - no client authentication is used, and the file CA is used to verify the + server certificate + + - `tls` **CERT** **KEY** - client authentication is used with the specified cert/key pair. The + server certificate is verified with the system CAs. + + - `tls` **CERT** **KEY** **CA** - client authentication is used with the specified cert/key + pair. The server certificate is verified using the specified CA file. + + * `tls_servername` **NAME** allows you to set a server name in the TLS configuration. This is + needed because *traffic* connects to an IP address, so it can't infer the server name from it. + + * `ignore_health` can be enabled to ignore endpoint health status, this can aid in debugging. ## Naming Clusters @@ -99,27 +110,29 @@ is used in the configuration. ## Matching Algorithm -How are clients match against the data we receive from xDS endpoint? Ignoring `locality` for now, -it will go through the following steps: +How are clients match against the data we receive from xDS endpoint? Ignoring `locality` for now, it +will go through the following steps: -1. Does the cluster exist? If not return NXDOMAIN, otherwise continue. -2. Run through the endpoints, discard any endpoints that are not HEALTHY. If we are left with no - 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. +1. Does the cluster exist? If not return NXDOMAIN, otherwise continue. + +2. Run through the endpoints, discard any endpoints that are not HEALTHY. If we are left with no + 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. If `locality` *has* been specified there is an extra step between 2 and 3. -2a. Match the endpoints using the locality that groups several of them, it's the most specific match - from left to right in the `locality` list; if no **REGION,ZONE,SUBZONE** matches then try - **REGION,ZONE** and then **REGION**. If still not match, move on the to next one. If we found - none, we continue with step 4 above, ignoring any locality. +2a. Match the endpoints using the locality that groups several of them, it's the most specific +match from left to right in the `locality` list; if no **REGION,ZONE,SUBZONE** matches then try +**REGION,ZONE** and then **REGION**. If still not match, move on the to next one. If we found none, +we continue with step 4 above, ignoring any locality. ## Metrics If monitoring is enabled (via the *prometheus* plugin) then the following metric are exported: -* `coredns_traffic_clusters_tracked{}` the number of tracked clusters. + * `coredns_traffic_clusters_tracked{}` the number of tracked clusters. ## Ready diff --git a/plugin/traffic/setup.go b/plugin/traffic/setup.go index 0806d15c2..51b690a44 100644 --- a/plugin/traffic/setup.go +++ b/plugin/traffic/setup.go @@ -124,3 +124,10 @@ func parseTraffic(c *caddy.Controller) (*Traffic, error) { return t, nil } + +// parseLoc parses string s into loc's. Each loc must be space separated from the other, inside +// a loc we have region,zone,subzone, where subzone or subzone and zone maybe empty. If specified +// they must be comma separate (not spaces or anything). +func parseLoc(s string) ([]loc, error) { + return nil, nil +} diff --git a/plugin/traffic/traffic.go b/plugin/traffic/traffic.go index 4aee275ad..bbc7598e6 100644 --- a/plugin/traffic/traffic.go +++ b/plugin/traffic/traffic.go @@ -17,10 +17,11 @@ import ( // Traffic is a plugin that load balances according to assignments. type Traffic struct { - c *xds.Client - id string - health bool - origins []string + c *xds.Client + id string + health bool + origins []string + locality []loc Next plugin.Handler } @@ -181,3 +182,10 @@ func soa(z string) []dns.RR { // Name implements the plugin.Handler interface. func (t *Traffic) Name() string { return "traffic" } + +// loc holds the locality for this server. It a list of the set region, zone, subzone. +type loc struct { + region string + zone string + subzone string +}