Skip to content

mhausenblas/kruiser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Kruiser

A proxy that transparently exposes gRPC Kubernetes services cluster-externally.

Using Ambassador as gRPC proxy, kruiser watches deployment in a target namespace that are labelled with grpc=expose. When it finds such a deployment, it creates a corresponding service of type NodePort proxying traffic to its pods from outside the cluster.

So far, I've tested kruiser on Minikube v0.24 with Kubernetes v1.8 and v1.9, as well as on GKE with Kubernetes v1.9 with and without RBAC.

Use cases

There are two main use cases:

UC1: inter-cluster within the enterprise

Imagine two or more clusters deployed within, say, a data center in an enterprise. In order for gRPC services to communicate across clusters, you need to proxy the traffic from one cluster to another.

UC2: public services

If you want to make your gRPC service publicly available, you need to somehow expose it, routing traffic from outside the cluster to the cluster-internal service.

Install

First, clone this repository with git clone https://github.com/mhausenblas/kruiser.git && cd kruiser.

Creating a namespaces for related apps rather than dumping all into the default namespace is a good practice, so let's do that first:

$ kubectl create namespace kruiser
$ go install .

Use

Example gRPC demo services

The two example gRPC demo services used below are:

  • A simple echo service yages.Echo available via quay.io/mhausenblas/yages:0.1.0
  • The reference helloworld.Greeter available via quay.io/mhausenblas/grpc-gs:0.2

As a generic gRPC client we use fullstorydev/grpcurl which you can either install locally, if you have Go installed, or as a container via the quay.io/mhausenblas/gump:0.1 container image.

Expose deployment

To expose a deployment, that is, creating an Ambassador-backed service proxying traffic to its pods from outside the cluster with kruiser you have to do two things: 1. define the gRPC service semantics, and 2. enable/disable the proxying.

Define the gRPC service semantics on the deployment you want to expose like so:

$ kubectl -n kruiser annotate deploy/ping kruiser.kubernetes.sh/container-port='9000'
$ kubectl -n kruiser annotate deploy/ping kruiser.kubernetes.sh/fq-service-name='yages.Echo'

And now, in order to trigger the service proxy to be created, label the deployment with kruiser.kubernetes.sh/grpc=expose, for example:

$ kubectl -n kruiser label deploy/ping kruiser.kubernetes.sh/grpc=expose

Note: use kubectl -n kruiser label deploy/ping kruiser.kubernetes.sh/grpc- to remove the label again.

Walkthroughs

In the following, I'll walk you through how you can use kruiser in a static manner, that is, manually exposing gRPC services cluster-externally. Along the way I explain how kruiser works.

$ kubectl create namespace kruiser

Minikube

First, install Ambassador with:

$ kubectl -n kruiser apply -f ambassador/admin.yaml

Next, deploy the two gRPC demo services:

$ kubectl -n kruiser apply -f demo-services/

Now you can invoke each of the gRPC demo services from outside Minikube like so:

$ grpcurl --plaintext $(minikube ip):31001 yages.Echo.Ping

$ grpcurl --plaintext  -d '{ "name" : "Michael" }' $(minikube ip):31000 helloworld.Greeter.SayHello

Alternatively, you can access one of the gRPC services via the gRPC jump pod like so:

$ kubectl -n kruiser run -it --rm gumpod \
          --restart=Never --image=quay.io/mhausenblas/gump:0.1

/go $ grpcurl --plaintext ping:9000 yages.Echo.Ping

GKE

Note that the GKE deployment in the following uses RBAC for access control.

As a preparation, you need to give your user certain rights.

$ cat ambassador/gke-crb.yaml | \
  sed s/__USER__/$(gcloud projects get-iam-policy $(gcloud config get-value core/project) | grep -m 1 user | awk '{split($0,u,":"); print u[2]}')/g | \
  kubectl -n kruiser apply -f -

Above, we replace the __USER__ placeholder in ambassador/gke-crb.yaml with the value of the user name of the active GKE project before creating the respective cluster-role binding.

Next, install Ambassador with:

$ kubectl -n kruiser apply -f ambassador/admin-rbac.yaml

And now deploy the two gRPC demo services:

$ kubectl -n kruiser apply -f demo-services/

To be able to access the services from outside the GKE cluster we first have to find values for external IPs of cluster nodes (store them for example in an env var NODE_IP):

$ kubectl get nodes --selector=kubernetes.io/role!=master \ 
                    -o jsonpath={.items[*].status.addresses[?\(@.type==\"ExternalIP\"\)].address}

Now, finally, you can invoke each of the gRPC demo services from outside the GKE cluster like so:

$ grpcurl --plaintext $(NODE_IP):31001 yages.Echo.Ping

$ grpcurl --plaintext  -d '{ "name" : "Michael" }' $(NODE_IP):31000 helloworld.Greeter.SayHello

Cleanup

When done, clean up with:

$ kubectl delete ns kruiser

About

A proxy that transparently exposes gRPC Kubernetes services cluster-externally

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages