Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Service configs in DNS. #5

Merged
merged 13 commits into from
Mar 28, 2017
Merged
114 changes: 114 additions & 0 deletions A2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
Service Config via DNS
----------------------
* Author(s): Mark D. Roth (roth@google.com)
* Approver: a11r
* Status: Draft
* Implemented in: N/A
* Last updated: 2017-01-19
* Discussion at: https://groups.google.com/d/topic/grpc-io/DkweyrWEXxU/discussion

## Abstract

This document proposes a mechanism for encoding gRPC service config data
in DNS for use in the open-source world.

## Background

The [service
config](https://github.com/grpc/grpc/blob/master/doc/service_config.md)
mechanism was originally designed for use inside of Google. However,
all but one part of the original design will work fine in the open-source
world. That one part is the specification of how the service config
data will be encoded in DNS.

### Related Proposals:

N/A

## Proposal

There are two parts to this proposal. The first part is to add some
JSON wrapping for controlling how service config changes are canary
tested. The second part describes how the service config is encoded in
DNS.

### Canarying Changes

When deploying a change to a service config, it is useful to be able to
canary test changes to avoid wide-spread breakage by slowly increasing the
number of clients that see the new version. To that end, multiple
service configs choices can be listed, in order, along with criteria that
determine which choice will be selected by a given client:

```
# A list of one or more service config choices.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: While this isn't actually JSON, JSON (when it supports comments) uses // for comments. You could then also use the ```json for the start of the block to get syntax highlighting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, didn't know that. Fixed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ```json thing didn't work right, so I removed it.

# The first matching entry wins.
[
{
# Criteria used to select this choice.
# Client language (e.g., 'c++', 'java', 'go', 'python', etc)
# Percentage: integer from 0 to 100 indicating the percentage of
# clients that should use this choice.
'clientLanguage': string,
'percentage': number,

# The service config data object for clients that match the above
# criteria. (The format for this object is defined in
# https://github.com/grpc/grpc/blob/master/doc/service_config.md.)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make this a proper markdown link?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like there's an easy way to do that inside of a triple-backtick block.

'serviceConfig': object
}
]
```

### Encoding in DNS TXT Records

In DNS, the service config data (in the form documented in the previous
section) will be encoded in a TXT record with the attribute name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably call out some references of how this is done for long configs, since <character-string> is limited to 255 bytes. Specifically, that multiple strings in a single TXT RR are concatenated without space (SPF spec has most clear description). I see that mentioned in passing later, but it should be in this section, since this defines the design.

It seems like it may be prudent to reference https://tools.ietf.org/html/rfc1464 as well, either to describe that's the format we're using or explicitly saying we aren't following it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the references. I was aware of them but hadn't added them to the doc, although I should have. Fixed.

`grpc_config`. The attribute value will be a JSON list containing
service config choices. For example, here is an example TXT record:

```
myserver 3600 TXT "grpc_config=[{'serviceConfig':{'loadBalancingPolicy':'round_robin','methodConfig':[{'name':[{'service':'MyService','method':'Foo'}],'waitForReady':true}]}}]"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 3600 ? Is this recommended (required?) value or just an example? In either case, probably should be state explicitly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just an example TTL value. There's no requirement for any particular value here (any more than there is for the content of the TXT record itself).

```

Note that because TXT records must be ASCII, this also imposes the
restruction that the contents of the service config are also ASCII
(e.g., service and method names, load balancing policy names, etc).

## Rationale

The service config is designed to be returned as part of name
resolution, so encoding it in DNS makes the most sense. Sites that use
a naming system other than DNS can, of course, implement their own
resolvers with their own mechanism for encoding service config data.

When encoding the service config in DNS, TXT records are the "obvious"
choice, since the service config is effectively additional metadata
associated with the DNS name.

## Implementation

The implementation will be done in C-core first. Once the new c-ares
DNS resolver code (https://github.com/grpc/grpc/pull/7771) has been
merged, we will extend it to query for the TXT records and return the
resulting service config JSON data.

## Open issues (if applicable)

DNS TXT records do have some limitations that need to be taken into
account here.

TXT records are limited to 255 bytes per string. There can be multiple
strings, which will be concatenated together. However, there are a few
considerations with regard to length limitations:

- If a DNS response exceeds 512 bytes, it will fall back from UDP to
TCP, which adds overhead.
- The total DNS response cannot exceed 65536 bytes.
- It is not clear whether individual DNS implementations will allow
anywhere close to 65536 bytes, even though the spec says that they
should.

Feedback is requested on whether these considerations will be a
significant drawback for this design (in which case the design will
probably have to be changed).