-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Initial vtadmin-api, clusters, and service discovery #7187
Initial vtadmin-api, clusters, and service discovery #7187
Conversation
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
This will make greater cohesion at the cluster layer between vtsql and discovery, I promise. Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
…me here This adds the following: - multiplexed gRPC/HTTP server. I'm not using the `servenv` gRPC setup, because I want to get a workable version out the door without having to work our existing code too closely into the vitess grpc set up (plus, vitess doesn't support the multiplexing that I want). We can definitely revisit bringing these together later. - complete implementation of the VTAdminServer interface, as well as an HTTP-wrapped interface to it. This requires a bunch of plumbing to do in an ergonomic way, which is what `vtadmin/http` is for, as well as `vtadmin/errors`. - Add the CLI entrypoint Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
…CLI-powered map Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
1. vtsql needs a discovery 1, mistaken wg.Done() replaced with Wait() Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
The glog package sets these on the global flagset on init, and exposes no way to attach those flags, and only those flags, to a different flagset, so we're stuck looking them up by hard-coded name. Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
…entation!) Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Plugins are an interesting beast in Go. Historically in Vitess, we've required users to compile their own code directly into the binary, which is definitely a barrier to entry if you just want to use default images for the most part. AFAIK, the stdlib plugin is dead in the water. The most common option I've seen for plugins is probably https://github.com/hashicorp/go-plugin. For the time being and for v1, I would probably not worry about plugin compatibility, and just make it pluggable with a function like you describe, allowing for users to just compile their code with the binary if they want. We can revisit plugins more broadly another time. |
Just pointing out that plugins are described in the overall feature but not actually implemented in this PR. It's something I definitely want to have in the fully-finished vtadmin, but I don't have particularly strong feelings besides "there should be some way to provide additional implementations that aren't in vitess:master". I'll take a look at that repo! |
Is there a way I can disable the race detector test? It's failing on the grpcserver tests that I wrote, which are .... actually designed that way 😅 I don't want to add a mutex to the |
Signed-off-by: Andrew Mason <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a minor thing I noticed: all new source files should carry the copyright notice, new files should say (c) 2020.
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Sara Bee <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great.
I will merge it once the codeowners conflict is resolved.
go/vt/vtadmin/api_test.go
Outdated
assert.Error(t, err) | ||
} | ||
|
||
func TestGetTabet(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: TestGetTabet => TestGetTablet
go/vt/vtadmin/http/handlers/trace.go
Outdated
// return NewJSONResponse(api.Something(ctx)) | ||
// } | ||
// | ||
// An unnamed route will get a span named "vtfun:http:<unnamed route>". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Two references to VTFun in the comments :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😅 ✅
Signed-off-by: Andrew Mason <[email protected]>
Signed-off-by: Andrew Mason <[email protected]>
@rohit-nayak-ps should be good to go now! |
Backport
NO
Status
READY
Description
This is the initial implementation of the vtadmin-api! It doesn't have everything, but this was the, uhh, smallest reasonable place to draw a line of "$thing that works and can do something useful". At a high level, this adds:
cobra
, etc), this lives ingo/vt/vtadmin/grpcserver
. I think it makes sense to leave this as-is for now, and figure out how to unify this with theservenv.GRPCServer
later. Happy to hear disagreements, though!VTAdmin Clusters
A mini design doc in a PR!
Abstract
One of the bigger benefits of VTAdmin over the vtctld API / admin UI is that VTAdmin provides a single place to view and administer many Vitess clusters than a single one.
This document proposes designs for the following components for VTAdmin:
Expected Use Cases
We expect most clusters to be either environments (e.g. dev/prod/qa), or geographic regions, whether AWS (us-east-1, eu-north-1, ap-northeast-1), GCP (us-west1, europe-north1, asia-northeast2), Azure (East US, Norway East, Japan East), or others. Clusters in theory can be any arbitrary way a Vitess user choose to splice up their keyspaces, so hard-coding a list of expected names (i.e. AWS regions) prohibits many use cases.
Different clusters need different configurations, even for the same overall deployment. A small list of things that may differ per-cluster:
Goal
Define the concept of a generalized cluster. Clusters should provide maximal flexibility in configuration, allowing VTAdmin users to tweak as much behavior as possible without making code changes or rebuilding the
vtadmin-api
binaries (so-ldflags
–based solutions are out).Non-Goal
Allow VTAdmin users to change the behavior of VTAdmin clusters at runtime. Though this is possible with the proposed design, it is sufficiently complex to warrant a separate design document. We should get a v1 landed and used in production first, and then revisit runtime configuration. It may also turn out it’s not a highly-desired feature.
Proposal
To support a generalized cluster in vtadmin-api, we propose two things:
Additionally, allowing these configurations to be read from YAML files, to provide better ergonomics.
Cluster definition
Clusters will be created via configs (see
vtadmin/cluster/config.go
). VTAdmin can then maintain a mapping of map[string]*cluster.Cluster and delegate all logic to a specific cluster depending on the name parameter of a given function/http endpoint/gRPC endpoint/etc, and return an error if a cluster with that name was never configured.During startup, vtadmin-api parses three flags,
-cluster-config
, a path to a YAML representation of cluster configs,-cluster-defaults
, for setting options common to all or most of your clusters, and-cluster
, a repeated flag for specifying per-cluster options and overriding global options. Then, the levels of configs are merged according to the following precedence:Finally, each fully-merged cluster config is used to produce a
*cluster.Cluster
, which the API uses.To facilitate flexible, independent configurations, both of these flags take a DSN as their argument, loosely described as follows:
That "discovery-" wildcard provides per-discovery-implementation level configuration. The second segment (going by
-
as the separator) should be the name of the corresponding discovery implementation (e.g."``consul``"
,"``etcd2``"
). This value groups the flags, with thediscovery-${impl}-
prefix removed. These flags are then passed along the given discovery implementation’s factory, which can parse those flags with its own implementation-specificflag.FlagSet
.Note: We also add
vtsql-*
flags similarly, and expect to addvtctl-*
flags, depending on how that cluster-specific services may need to be configured, but discovery is more complicated and interesting, so it’s the thing we discuss.This leads to the following example usage (with a bash helper to make it look nice):
This approach has some downsides, namely:
DiscoveryImpl
andDiscoveryFlagsByImpl
is deferred until discovery-creation time. This makes a subpar parsing experience, in that technically invalid flags don’t get caught during the initialflag.Parse()
in vtadmin-api’s entrypoint. This is also true ofVtSQLFlags
.flag.FlagSet
and use that to parse the deferred flags.-cluster discovery=consul,discovery-etcd2-foo=bar
) and have those silently ignored. This is in fact required to support the-cluster-defaults
functionality, as different clusters may use different discovery implementations, and we need to support setting defaults for both implementations. In my opinion, this is fine, and just something to document and be aware of.For completeness, the YAML representation of this config is:
Discovery
VTAdmin will provide several discovery implementations out-of-the-box. These include:
consul
- this PRstaticfile
- Tentatively planned for v1etcd2
k8s
zk
VTAdmin will also support custom discovery implementations via plugin loading. First, though, we will consider the built-in case.
VTAdmin discovery will maintain a private factory registry, similar to many other Vitess components. During cluster initialization, a cluster will call
discovery.New(clusterName, impl, args)
.New
will lookup the corresponding factory for that discovery implementation, and call it with the given cluster name and args; theseargs
are the flags described above, and a factory should parse these using a FlagSet.This looks like:
Discovery Plugins
In the event the builtin discovery implementations do not work for all use cases, users may write their own, which vtadmin will load via package plugin. They should provide a file which exports a function
New(cluster string, args []string) (discovery.Discovery, error)
, compile their code withgo build -buildmode=plugin
, and make the resulting.so
file accessible to vtadmin-api [1].Then in their command-line flags, specify
discovery=plugin:/path/to/my.so
, and their plugin will be registered and used. Discovery flags should then be set withdiscovery-my.so-*
(this exact spec may change depending on how much it complicates the implementation).The
New
function above then becomes:Consul Discovery
This PR includes an implementation of consul-backed service discovery, which is also documented to serve as a reference for future implementations.
One note: The current interface uses
tags []string
as a parameter to every function because it maps nicely onto the internal implementation details of consul. This may not work as well for other discovery service APIs, in which case our options are probably:map[string]string
and accept that each implementation needs to handle arbitrary maps.Appendix
[1]: Sample custom plugin:
Related Issue(s)
List related PRs against other branches:
Todos
go/vt/vtadmin
documenting alpha state of the service, "use at your risk, api not subject to backwards-compatibility guarantees" etc etcKnown bugs
(vtsql.DB).Dial()
returns an error if the user does not provide a credentials flag to vtsql for a cluster. This is becausevitessdriver.OpenWithConfiguration
only callsRegisterDialer
iflen(c.GRPCDialOptions) > 0
, and without the credentials options, that is the case. The fix is either to have vitessdriver.Configuration take an option to always register, or to make the call tovtgateconn.RegisterDialer
ourselves before callingOpenWithConfiguration
Deployment Notes
Notes regarding deployment of the contained body of work. These should note any
db migrations, etc.
Impacted Areas in Vitess
List general components of the application that this PR will affect: