kuberesolver

package module
v3.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 18, 2021 License: Apache-2.0 Imports: 20 Imported by: 8

README

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/v3"
	
// 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://namespace/service-name:8080
kubernetes://service-name:8080/
kubernetes://service-name.namespace:8080/

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.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewBuilder

func NewBuilder(client K8sClient, schema string) resolver.Builder

NewBuilder creates a kubeBuilder which is used by grpc resolver.

func RegisterInCluster

func RegisterInCluster()

RegisterInCluster registers the kuberesolver builder to grpc with kubernetes schema

func RegisterInClusterWithSchema

func RegisterInClusterWithSchema(schema string)

RegisterInClusterWithSchema registers the kuberesolver builder to the grpc with custom schema

Types

type Address

type Address struct {
	IP        string           `json:"ip"`
	TargetRef *ObjectReference `json:"targetRef,omitempty"`
}

type Endpoints

type Endpoints struct {
	Kind       string   `json:"kind"`
	ApiVersion string   `json:"apiVersion"`
	Metadata   Metadata `json:"metadata"`
	Subsets    []Subset `json:"subsets"`
}

type Event

type Event struct {
	Type   EventType `json:"type"`
	Object Endpoints `json:"object"`
}

Event represents a single event to a watched resource.

type EventType

type EventType string
const (
	Added    EventType = "ADDED"
	Modified EventType = "MODIFIED"
	Deleted  EventType = "DELETED"
	Error    EventType = "ERROR"
)

type K8sClient

type K8sClient interface {
	Do(req *http.Request) (*http.Response, error)
	GetRequest(url string) (*http.Request, error)
	Host() string
}

K8sClient is minimal kubernetes client interface

func NewInClusterK8sClient

func NewInClusterK8sClient() (K8sClient, error)

NewInClusterK8sClient creates K8sClient if it is inside Kubernetes

func NewInsecureK8sClient

func NewInsecureK8sClient(apiURL string) K8sClient

NewInsecureK8sClient creates an insecure k8s client which is suitable to connect kubernetes api behind proxy

type Metadata

type Metadata struct {
	Name            string            `json:"name"`
	Namespace       string            `json:"namespace"`
	ResourceVersion string            `json:"resourceVersion"`
	Labels          map[string]string `json:"labels"`
}

type ObjectReference

type ObjectReference struct {
	Kind      string `json:"kind"`
	Name      string `json:"name"`
	Namespace string `json:"namespace"`
}

type Port

type Port struct {
	Name string `json:"name"`
	Port int    `json:"port"`
}

type Subset

type Subset struct {
	Addresses []Address `json:"addresses"`
	Ports     []Port    `json:"ports"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL