https://github.com/mhausenblas/kruiser
A proxy that transparently exposes gRPC Kubernetes services cluster-externally
https://github.com/mhausenblas/kruiser
grpc kubernetes proxy
Last synced: 12 months ago
JSON representation
A proxy that transparently exposes gRPC Kubernetes services cluster-externally
- Host: GitHub
- URL: https://github.com/mhausenblas/kruiser
- Owner: mhausenblas
- License: apache-2.0
- Created: 2018-03-28T11:09:34.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-04-08T16:57:19.000Z (about 8 years ago)
- Last Synced: 2025-07-03T22:02:51.446Z (12 months ago)
- Topics: grpc, kubernetes, proxy
- Language: Go
- Homepage:
- Size: 120 KB
- Stars: 14
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Kruiser
A proxy that transparently exposes gRPC Kubernetes services cluster-externally.
Using [Ambassador](https://www.getambassador.io/) 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](#use-cases)
- [UC1: inter-cluster within the enterprise](#uc1-inter-cluster-within-the-enterprise)
- [UC2: public services](#uc2-public-services)
- [Install](#install)
- [Use](#use)
- [Example gRPC demo services](#example-grpc-demo-services)
- [Expose deployment](#expose-deployment)
- [Walkthroughs](#walkthroughs)
- [Minikube](#minikube)
- [GKE](#gke)
- [Cleanup](#cleanup)
## 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:
```bash
$ kubectl create namespace kruiser
$ go install .
```
## Use
### Example gRPC demo services
The two example gRPC [demo services](demo-services/) used below are:
- A simple echo service [yages.Echo](https://github.com/mhausenblas/yages/blob/master/main.go) available via `quay.io/mhausenblas/yages:0.1.0`
- The reference [helloworld.Greeter](https://github.com/grpc/grpc-go/blob/master/examples/helloworld/greeter_server/main.go) available via `quay.io/mhausenblas/grpc-gs:0.2`
As a generic gRPC client we use [fullstorydev/grpcurl](https://github.com/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](https://quay.io/repository/mhausenblas/gump?tag=0.1&tab=tags) 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:
```bash
$ 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:
```bash
$ 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.
```bash
$ kubectl create namespace kruiser
```
#### Minikube
First, install Ambassador with:
```bash
$ kubectl -n kruiser apply -f ambassador/admin.yaml
```
Next, deploy the two gRPC demo services:
```bash
$ kubectl -n kruiser apply -f demo-services/
```
Now you can invoke each of the gRPC demo services from outside Minikube like so:
```bash
$ 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:
```bash
$ 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.
```bash
$ 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:
```bash
$ kubectl -n kruiser apply -f ambassador/admin-rbac.yaml
```
And now deploy the two gRPC demo services:
```bash
$ 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`):
```bash
$ 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:
```bash
$ 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:
```bash
$ kubectl delete ns kruiser
```