Git Product home page Git Product logo

kuberesolver's Introduction

kuberesolver

A Grpc name resolver by using kubernetes API. It comes with a small ~250 LOC kubernetes client to find service endpoints. Therefore it won't bloat your binaries.

USAGE

// Import the module
import "github.com/sercand/kuberesolver/v5"
	
// Register kuberesolver to grpc before calling grpc.Dial
kuberesolver.RegisterInCluster()

// it is same as
resolver.Register(kuberesolver.NewBuilder(nil /*custom kubernetes client*/ , "kubernetes"))

// if schema is 'kubernetes' then grpc will use kuberesolver to resolve addresses
cc, err := grpc.Dial("kubernetes:///service.namespace:portname", opts...)

An url can be one of the following, grpc naming docs

kubernetes:///service-name:8080
kubernetes:///service-name:portname
kubernetes:///service-name.namespace:8080
kubernetes:///service-name.namespace.svc.cluster_name
kubernetes:///service-name.namespace.svc.cluster_name:8080

kubernetes://namespace/service-name:8080
kubernetes://service-name:8080/
kubernetes://service-name.namespace:8080/
kubernetes://service-name.namespace.svc.cluster_name
kubernetes://service-name.namespace.svc.cluster_name:8080

* Please note that the cluster_name is not used in resolving the endpoints of a Service. It is only there to support fully qualified service names, e.g. test.default.svc.cluster.local.

Using alternative Schema

Use RegisterInClusterWithSchema(schema) instead of RegisterInCluster on start.

Client Side Load Balancing

You need to pass grpc.WithBalancerName option to grpc on dial:

grpc.DialContext(ctx,  "kubernetes:///service:grpc", grpc.WithBalancerName("round_robin"), grpc.WithInsecure())

This will create subconnections for each available service endpoints.

How is this different from dialing to service.namespace:8080

Connecting to a service by dialing to service.namespace:8080 uses DNS and it returns service stable IP. Therefore, gRPC doesn't know the endpoint IP addresses and it fails to reconnect to target services in case of failure.

Kuberesolver uses kubernetes API to get and watch service endpoint IP addresses. Since it provides and updates all available service endpoints, together with a client-side balancer you can achive zero downtime deployments.

RBAC

You need give GET and WATCH access to the endpoints if you are using RBAC in your cluster.

Using With TLS

You need to a certificate with name service-name.namespace in order to connect with TLS to your services.

kuberesolver's People

Contributors

bboreham avatar code-merc avatar cuihandong avatar dependabot[bot] avatar gouthamve avatar guelfey avatar gustavofagundes avatar jhump avatar johanwangloff avatar knutzuidema avatar lalalalatt avatar matang28 avatar narqo avatar peterxcli avatar sercand avatar stampy88 avatar thib92 avatar vincentye123 avatar wyattanderson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kuberesolver's Issues

grpc.Dial will block when using kuberesolver against a non-existing service

The correct thing to do (implied by grpc/grpc-go#976) is to return an empty []Address from watcher.Next:


goroutine 1 [select]:
github.com/weaveworks/service/vendor/google.golang.org/grpc.DialContext(0x10ed6e0, 0xc420019b78, 0xc42022a8c0, 0x19, 0xc420233ff0, 0x3, 0x3, 0x0, 0x0, 0x0)
	/go/src/github.com/weaveworks/service/vendor/google.golang.org/grpc/clientconn.go:373 +0x60a
github.com/weaveworks/service/vendor/google.golang.org/grpc.Dial(0xc42022a8c0, 0x19, 0xc420233ff0, 0x3, 0x3, 0xc42022a920, 0x19, 0x2)
	/go/src/github.com/weaveworks/service/vendor/google.golang.org/grpc/clientconn.go:268 +0x72
github.com/weaveworks/service/vendor/github.com/weaveworks/common/httpgrpc.NewClient(0x7ffd9ed00245, 0x13, 0xc4201dd3e0, 0x10e7960, 0xc4201dd3e0)
	/go/src/github.com/weaveworks/service/vendor/github.com/weaveworks/common/httpgrpc/httpgrpc.go:81 +0x395
main.routes(0x10ed5a0, 0xc4200555c0, 0xc420187780, 0xbb0c8d, 0xd, 0x1, 0x7ffd9ecffe90, 0x16, 0x0, 0x0, ...)
	....

goroutine 92 [select]:
github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver.(*kubeResolver).watch(0xc42022a8e0, 0xc42022a8cd, 0x7, 0xc4201df260, 0xc4201df200, 0x0, 0x0)
	/go/src/github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver/resolver.go:73 +0x499
github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver.(*kubeResolver).Resolve.func1()
	/go/src/github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver/resolver.go:38 +0x52
github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver.until.func1(0xc4201e92f0)
	/go/src/github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver/util.go:20 +0x43
github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver.until(0xc4201e92f0, 0x3b9aca00, 0xc4201df260)
	/go/src/github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver/util.go:21 +0x73
created by github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver.(*kubeResolver).Resolve
	/go/src/github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver/resolver.go:42 +0x1aa

...

goroutine 91 [chan receive]:
github.com/weaveworks/service/vendor/google.golang.org/grpc.DialContext.func2(0xc420236000, 0xc42022a8c0, 0x19, 0x0, 0x0, 0xc4201df1a0, 0xc4201dd99c)
	/go/src/github.com/weaveworks/service/vendor/google.golang.org/grpc/clientconn.go:358 +0x12f
created by github.com/weaveworks/service/vendor/google.golang.org/grpc.DialContext
	/go/src/github.com/weaveworks/service/vendor/google.golang.org/grpc/clientconn.go:372 +0x3d3

...

goroutine 93 [select]:
github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver.(*watcher).Next(0xc4201df2c0, 0xc4200b9a00, 0xc420025660, 0x41365e, 0xc4201de540, 0xc420011ea0)
	/go/src/github.com/weaveworks/service/vendor/github.com/sercand/kuberesolver/watcher.go:39 +0xe2f
github.com/weaveworks/service/vendor/google.golang.org/grpc.(*roundRobin).watchAddrUpdates(0xc4201df0e0, 0x0, 0x0)
	/go/src/github.com/weaveworks/service/vendor/google.golang.org/grpc/balancer.go:168 +0x64
github.com/weaveworks/service/vendor/google.golang.org/grpc.(*roundRobin).Start.func1(0xc4201df0e0)
	/go/src/github.com/weaveworks/service/vendor/google.golang.org/grpc/balancer.go:239 +0x2b
created by github.com/weaveworks/service/vendor/google.golang.org/grpc.(*roundRobin).Start
	/go/src/github.com/weaveworks/service/vendor/google.golang.org/grpc/balancer.go:243 +0x148

Note I don't agree with this gRPC behaviour, but it doesn't seem like they're going to change that - at least, I'll take that up separately with them.

Unauthorize Operation

Hello Guys

I'm facing the same issue in Aws EKS

EKS Data:

Server Version: version.Info{Major:"1", Minor:"18+", GitVersion:"v1.18.9-eks-d1db3c", GitCommit:"d1db3c46e55f95d6a7d3e5578689371318f95ff9", GitTreeState:"clean", BuildDate:"2020-10-20T22:18:07Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"linux/amd64"}

My Role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: mag-dev
  namespace: mag-dev
rules:
- apiGroups:
  - ""
  resources:
  - configmaps
  - secrets
  - endpoints
  - services
  verbs:
  - get
  - list
  - watch

My Headless service

---
apiVersion: v1
kind: Service
metadata:
  name: gubernator
  namespace: ratelimit
  labels:
    app: gubernator
spec:
  type: ClusterIP
  clusterIP: None
  ports:
    - name: grpc-port
      targetPort: 81
      protocol: TCP
      port: 81
    - name: http-port
      targetPort: 80
      protocol: TCP
      port: 80
  selector:
    app: gubernator

My grpc conn

kuberesolver.RegisterInCluster()
resolver.Register(kuberesolver.NewBuilder(nil /*custom kubernetes client*/, "kubernetes"))
return grpc.Dial(address, grpc.WithBalancerName("round_robin"), grpc.WithInsecure())

address value : kubernetes:///gubernator.ratelimit:81

Would you guys have any ideia what i'm doing wrong?

Originally posted by @matheus-meneses in #8 (comment)

connection errors during watch do not cause a reconnect

AFAICT kubeBuilder.Build should reconnect when the witcher encounters an error:

kuberesolver/builder.go

Lines 177 to 183 in b382846

go until(func() {
r.wg.Add(1)
err := r.watch()
if err != nil && err != io.EOF {
grpclog.Errorf("kuberesolver: watching ended with error='%v', will reconnect again", err)
}
}, time.Second, time.Second*30, ctx.Done())

But tkResolver.watch() only returns an error during the initial connection establishment in watchEndpoints(). All other cases in the select return a nil error:

kuberesolver/builder.go

Lines 278 to 299 in b382846

func (k *kResolver) watch() error {
defer k.wg.Done()
// watch endpoints lists existing endpoints at start
sw, err := watchEndpoints(k.ctx, k.k8sClient, k.target.serviceNamespace, k.target.serviceName)
if err != nil {
return err
}
for {
select {
case <-k.ctx.Done():
return nil
case <-k.t.C:
k.resolve()
case up, hasMore := <-sw.ResultChan():
if hasMore {
k.handle(up.Object)
} else {
return nil
}
}
}
}

watchEndpoints sets up a newStreamWatcher which loops over the channel and closes it in case of an error:

kuberesolver/stream.go

Lines 69 to 93 in b382846

func (sw *streamWatcher) receive() {
defer close(sw.result)
defer sw.Stop()
for {
obj, err := sw.Decode()
if err != nil {
// Ignore expected error.
if sw.stopping() {
return
}
switch err {
case io.EOF:
// watch closed normally
case context.Canceled:
// canceled normally
case io.ErrUnexpectedEOF:
grpclog.Infof("kuberesolver: Unexpected EOF during watch stream event decoding: %v", err)
default:
grpclog.Infof("kuberesolver: Unable to decode an event from the watch stream: %v", err)
}
return
}
sw.result <- obj
}
}

until() only wraps panics ... and will silently stop restarting watch() after 30secs

Am I missing something? How does the actual reconnect happen on intermediate connection errors after the 30 seconds? There is a timer that updates the endpoints every 30min, but the watcher is just not restarted.

I'm asking because we encountered the kubernetes API to be unavailable for minutes during a cluster upgrade.

Does kuberesolver watch all endpoints?

If I use RegisterInCluster does it automatically watch all endpoints? If so, is there a way to make it so it only watches certain endpoints? My cluster has tons of stuff in it and I only need it to watch one.

Not work with grpc v1.53.0

The latest version v3.3.1 does not work with grpc v1.53.0. When compiling, I get the following error:

../go1.18.1/pkg/mod/github.com/sercand/kuberesolver/[email protected]/builder.go:81:12: invalid operation: end == "" (mismatched types func() string and untyped string)
../go1.18.1/pkg/mod/github.com/sercand/kuberesolver/[email protected]/builder.go:82:9: cannot use target.Authority (variable of type string) as type func() string in assignment
../go1.18.1/pkg/mod/github.com/sercand/kuberesolver/[email protected]/builder.go:86:12: invalid operation: end == "" (mismatched types func() string and untyped string)
../go1.18.1/pkg/mod/github.com/sercand/kuberesolver/[email protected]/builder.go:91:23: cannot use end (variable of type func() string) as type string in argument to strings.LastIndex
../go1.18.1/pkg/mod/github.com/sercand/kuberesolver/[email protected]/builder.go:92:10: cannot use end (variable of type func() string) as type string in assignment
../go1.18.1/pkg/mod/github.com/sercand/kuberesolver/[email protected]/builder.go:97:39: cannot use end (variable of type func() string) as type string in argument to net.SplitHostPort

This is because in grpc v1.53.0, the "target.Endpoint" is a function. Can you fix it?

transport: Error while dialing dial tcp too many colons in address

I am using latest grpc version (google.golang.org/grpc v1.30.0)
I am getting "too many colons in address" error for kubernetes:///greeter:8080

10:28PM INF Server (mkit.service.account) starting at: [::]:8080
10:28PM INF Subchannel Connectivity change to CONNECTING module=grpc
10:28PM INF Subchannel picks a new address "kubernetes:///service-name:8080" to connect module=grpc
10:28PM INF base.baseBalancer: handle SubConn state change: 0xc000575840, CONNECTING module=grpc
10:28PM WRN grpc: addrConn.createTransport failed to connect to {kubernetes:///service-name:8080 localhost <nil> 0 <nil>}. Err: connection error: desc = "transport: Error while dialing dial tcp: address kubernetes:///service-name:8080: too many colons in address". Reconnecting... module=grpc
10:28PM INF Subchannel Connectivity change to TRANSIENT_FAILURE module=grpc
10:28PM INF base.baseBalancer: handle SubConn state change: 0xc000575840, TRANSIENT_FAILURE module=grpc
10:28PM INF Subchannel Connectivity change to CONNECTING module=grpc
10:28PM INF Subchannel picks a new address "kubernetes:///service-name:8080" to connect module=grpc
10:28PM INF base.baseBalancer: handle SubConn state change: 0xc000575840, CONNECTING module=grpc
10:28PM WRN grpc: addrConn.createTransport failed to connect to {kubernetes:///service-name:8080 localhost <nil> 0 <nil>}. Err: connection error: desc = "transport: Error while dialing dial tcp: address kubernetes:///service-name:8080: too many colons in address". Reconnecting... module=grpc
10:28PM INF Subchannel Connectivity change to TRANSIENT_FAILURE module=grpc
10:28PM INF base.baseBalancer: handle SubConn state change: 0xc000575840, TRANSIENT_FAILURE module=grpc

Headless service required?

I might be totally crazy, but I seem to remember kuberesolver requiring you set up a headless service in order for it to work. Now that I'm looking again I don't see any mention of it.

Was it ever required and now is not with the new version?

ServiceAccount token rotation

We received a report for SpiceDB, our project that leverages kuberesolver (thanks!) from @williamdclt

I’m looking at what we’re missing to upgrade our Kubernetes clusters to 1.21. The only change that could affect us (at least from my research) is that Service Account tokens now expire and are rotated.

As a refresher, Service Accounts are Kubernetes’s equivalent to an AWS IAM Role, it’s an identity for a machine. Service Accounts are linked to Pods, and Kubernetes generates a token to authenticate the SA, and injects this token into the pods in a well-known path.

Starting with 1.21, these tokens expire and are rotated on disk automatically. Official SDKs already support reading the token from disk when it expires.

However we have an issue for SpiceDB: it uses the Kubernetes API to discover sibling instances of SpiceDB (for dispatch IIRC), based on kuberesolver. However kuberesolver doesn’t use the official Go Kubernetes SDK, it implements its own lightweight client, initialized here https://github.com/sercand/kuberesolver/blob/master/kubernetes.go#L59-L86. I couldn’t find it its source code any reference to refreshing that token.

The default expiration period for these tokens is 90d in 1.21, but it will be reduced to minutes our hours in following updates.
This means that if a SpiceDB pod is alive for more than 90d (and much less later), it won’t be able to refresh its list of siblings for dispatch.

We're willing to submit some code if we can get the proper guidance and agreement on a solution.

cc @josephschorr @jakedt @ecordell

Need more documentation about setup

is need some configuration when running on kubernetes cluster
like RBAC or something like that?

this error messages:
ERROR: 2019/10/29 03:34:29 kuberesolver: watching ended with error='invalid response code 403', will reconnect again

Unable to use kuberesolver with go modules since addition of go.mod

I am not 100% sure what to do about this, but the error message is:

module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2

And the relevant Go issue is: golang/go#35732

I believe the root of the problem is that the import path does not end in /v2, but the tag is v2.3.0. This was previously fine because there was no go.mod on this repo, allowing for the use of +incompatible, but now that the repo has a go.mod, that does not work anymore.

I was able to temporarily work around this by using a computed version without referencing the tags, but it's sad to lose that version metadata.

Randomizing of round robin order?

Is there a way to get it so each client of kuberesolver connects to things in a random order? I have a situation where I have 500 clients connecting to 100 servers and it appears like there's still some big imbalances. I believe that could be fixed by randomizing the order in which this returns results when it first connects so that connections would be more evenly distributed.

Or maybe I'm misunderstanding how the internals of this work and someone could help me with a different approach?

Question about TLS and certificates

Hey guys, I recently added kuberesolver to my project but unfortunately I cannot make it work properly.
I created a headless service in k8s, added the DNS to my TLS certificates, but when I fire a request from a pod to another pod running the gRPC server, it throws me this error:

transport: authentication handshake failed: x509: certificate is valid for my-service-headless, not my-service-c9bd84f49-fjgg8

This means that it is resolving the headless pods, and firing the requests directly to them, bypassing the DNS names in the certificates.

Not sure if I managed to explain that properly, sorry
Does anyone has any clue on how to solve this? I even tried to force the Host header in the gRPC request to bypass this, but with no success :(

Best practices to use this library

Hi @sercand,

I have some questions about how to use this library and what are the best practices. Current README.md suggests to use this along with a client side load balancing policy. My question here is, Suppose grpc.Dial(...) has been already called and resolver respond with (let's say) 3 endpoints and therefore the returned conn from conn, err := grpc.Dial(...) with round_robin policy currently has a connection to each of these 3 endpoints. Now what happens if server scales up and increases the number of endpoints.

Am i expect to see the outgoing load also goes to new endpoints when using the old conn?
Do i need to Dial periodically or something?
What is the difference between using kuberesolver and a headless service?
What is the best practice to use this library?

I'll appreciate your time if you have any thoughts.

Question about reconnection and context

How well does this perform when using grpc.DialContext()? ie if a connection was established then the endpoints change, is the connection restablished using the original context which might have a cancellation signal?

I'd love to use this, if only to prevent errors like rpc error: code = Unavailable desc = transport is closing

kuberesolver didn't update endpoints when service changed

I have some frontends using kuberesolver to update and find backends and talk to them. I deployed updated backends and one of the frontends never updated to see the new backends, just started erroring with:

2017/11/19 13:02:10 grpc: addrConn.resetTransport failed to create client transport: connection error: desc = "transport: dial tcp 10.60.2.10:9095: getsockopt: connection refused"; Reconnecting to {10.60.2.10:9095 <nil>}

On the other frontends, at around the same time, I get:

2017/11/19 13:02:10 kuberesolver: 10.60.2.10:9095 DELETED from querier
2017/11/19 13:02:10 Failed to dial 10.60.2.10:9095: context canceled; please retry.
2017/11/19 13:02:27 kuberesolver: 10.60.2.11:9095 ADDED to querier
2017/11/19 13:02:37 grpc: addrConn.resetTransport failed to create client transport: connection error: desc = "transport: dial tcp 10.60.1.8:9095: getsockopt: connection refused"; Reconnecting to {10.60.1.8:9095 <nil>}
2017/11/19 13:02:37 kuberesolver: 10.60.1.8:9095 DELETED from querier
2017/11/19 13:02:37 Failed to dial 10.60.1.8:9095: context canceled; please retry.
2017/11/19 13:02:53 kuberesolver: 10.60.1.18:9095 ADDED to querier
2017/11/19 13:03:03 grpc: addrConn.resetTransport failed to create client transport: connection error: desc = "transport: dial tcp 10.60.0.8:9095: getsockopt: connection refused"; Reconnecting to {10.60.0.8:9095 <nil>}
2017/11/19 13:03:03 kuberesolver: 10.60.0.8:9095 DELETED from querier

Looking at the goroutine dump for the frontend with the failures, I see that one of the watch goroutines is just sitting there (maybe didn't get events from api-server?):

goroutine 30 [select, 2397 minutes]:
github.com/sercand/kuberesolver.(*kubeResolver).watch(0xc4201c3f20, 0xc4201c3f0d, 0x7, 0xc4201c4c60, 0xc4201c4c00, 0x0, 0x0)
	vendor/github.com/sercand/kuberesolver/resolver.go:73 +0x56b
github.com/sercand/kuberesolver.(*kubeResolver).Resolve.func1()
	vendor/github.com/sercand/kuberesolver/resolver.go:38 +0x52
github.com/sercand/kuberesolver.until.func1(0xc4201c1cb0)
	vendor/github.com/sercand/kuberesolver/util.go:20 +0x43
github.com/sercand/kuberesolver.until(0xc4201c1cb0, 0x3b9aca00, 0xc4201c4c60)
	vendor/github.com/sercand/kuberesolver/util.go:21 +0x73
created by github.com/sercand/kuberesolver.(*kubeResolver).Resolve
	vendor/github.com/sercand/kuberesolver/resolver.go:42 +0x1ac

The only other similar stack trace:

goroutine 50 [select, 28 minutes]:
github.com/sercand/kuberesolver.(*kubeResolver).watch(0xc420226740, 0xc42022672d, 0xb, 0xc4201c4f60, 0xc4201c4f00, 0x0, 0x0)
	vendor/github.com/sercand/kuberesolver/resolver.go:73 +0x56b
github.com/sercand/kuberesolver.(*kubeResolver).Resolve.func1()
	vendor/github.com/sercand/kuberesolver/resolver.go:38 +0x52
github.com/sercand/kuberesolver.until.func1(0xc420230060)
	vendor/github.com/sercand/kuberesolver/util.go:20 +0x43
github.com/sercand/kuberesolver.until(0xc420230060, 0x3b9aca00, 0xc4201c4f60)
	vendor/github.com/sercand/kuberesolver/util.go:21 +0x73
created by github.com/sercand/kuberesolver.(*kubeResolver).Resolve
	vendor/github.com/sercand/kuberesolver/resolver.go:42 +0x1ac

Which corresponds nicely with the two kuberesolver-d backend services I have.

Perhaps there should be a timeout in this watch, to catch intermittent errors like this? I think this is how the kubernetes golang client behaves.

When endpoint lookup fails there should be a better error message

Currently when a resolver lookup fails the error:

ERROR: 2020/10/27 19:56:13 kuberesolver: lookup endpoints failed: invalid response code 404

Is printed, it would be nice to have some context about the namespace/service it was trying to look up. Happy to do a PR to edit that error message if you want, looks like it's produced here.

Licencing information

Hi!

It'd be nice to know under which licence this code is to understand how one can re-use it. It may have some inbound licences too (ie. if you have taken some code from elsewhere) that it'd be good to document if the inbound licence requires it (some requires you to leave the copyright intact, etc.).

Thanks!

Use pod's namespace instead of default

Hello!
Thanks for the library, it's really very helpful!

I'd like to ask about using default namespace in case of we do not set namespace in url string, for example:

kubernetes:///test:8090

In this case default namespace will be used to get endpoints.

Is there a reason to use default namespace? Shouldn't we get pod's namespase from file /var/run/secrets/kubernetes.io/serviceaccount/namespace?

Zone aware routing

Hi @sercand,

first of all thanks for bringing up this beautiful little project. We're doing a lot of gRPC based communication in a multi-AZ cluster with lot's of movement. Thus this project is a lifesaver to keep track of active endpoints.

Based on the multi-AZ setup and a microservice based data-pipeline architecture, we however see intra-region data transfer costs rising since a while, which of course is not a big surprise ;)
To mitigate those costs we planned to add a zone aware routing feature to this module. An quiet similar idea has been described a while ago at https://github.com/kubernetes/ingress-nginx which are also working on endpoints directly, so I will simply link the draft here https://github.com/kubernetes/ingress-nginx/blob/master/docs/enhancements/20190815-zone-aware-routing.md#proposal. Of course please ignore the NGINX specific Lua parts ;)

Would you be open for a PR here or would you like to keep this module as clean as possible?

Document ServerName

This is non-obvious and took me a bit to figure out: The ‘ServerName’ attribute of resolver.Addresses that KubeResolver returns is (generally) set to the pod’s name. This means that if you are using KubeResolver with MTLS, you need a cert signed to the pod specifically. Not coincidentally, I’ve built a tool that does just that

This is reasonable default behavior, though I’d also like to see the ability to leave the hostname as servicename, or service-name.namespace - These make sense as naming behaviors, and match what you would expect if you’re already connecting via cluster DNS.

Support for fully qualified service name

Hi,

I wanted to add support for fully qualified service names of the form:

<service>.<namespace>.svc.<base-cluster-domain-name>

So for example, alpaca.default.svc.cluster.local is the alpaca service in the default namespace.
Want to see if there was a good reason not to do this before putting a PR together.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.