{"id":21712734,"url":"https://github.com/mhausenblas/kruiser","last_synced_at":"2025-07-03T22:04:19.009Z","repository":{"id":140043630,"uuid":"127128207","full_name":"mhausenblas/kruiser","owner":"mhausenblas","description":"A proxy that transparently exposes gRPC Kubernetes services cluster-externally","archived":false,"fork":false,"pushed_at":"2018-04-08T16:57:19.000Z","size":123,"stargazers_count":14,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-03T22:02:51.446Z","etag":null,"topics":["grpc","kubernetes","proxy"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mhausenblas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-28T11:09:34.000Z","updated_at":"2020-10-30T03:09:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"36bb6755-e0f9-4ebb-8a06-fdea834d06e2","html_url":"https://github.com/mhausenblas/kruiser","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mhausenblas/kruiser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhausenblas%2Fkruiser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhausenblas%2Fkruiser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhausenblas%2Fkruiser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhausenblas%2Fkruiser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mhausenblas","download_url":"https://codeload.github.com/mhausenblas/kruiser/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mhausenblas%2Fkruiser/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263410759,"owners_count":23462295,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["grpc","kubernetes","proxy"],"created_at":"2024-11-25T23:41:23.047Z","updated_at":"2025-07-03T22:04:18.871Z","avatar_url":"https://github.com/mhausenblas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kruiser\n\nA proxy that transparently exposes gRPC Kubernetes services cluster-externally.\n\nUsing [Ambassador](https://www.getambassador.io/) as gRPC proxy, `kruiser` \nwatches 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.\n\nSo 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.\n\n- [Use cases](#use-cases)\n  - [UC1: inter-cluster within the enterprise](#uc1-inter-cluster-within-the-enterprise)\n  - [UC2: public services](#uc2-public-services)\n- [Install](#install)\n- [Use](#use)\n  - [Example gRPC demo services](#example-grpc-demo-services)\n  - [Expose deployment](#expose-deployment)\n  - [Walkthroughs](#walkthroughs)\n    - [Minikube](#minikube)\n    - [GKE](#gke)\n    - [Cleanup](#cleanup)\n\n## Use cases\n\nThere are two main use cases:\n\n### UC1: inter-cluster within the enterprise\n\nImagine 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.\n\n### UC2: public services\n\nIf 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.\n\n\n## Install \n\nFirst, clone this repository with `git clone https://github.com/mhausenblas/kruiser.git \u0026\u0026 cd kruiser`.\n\nCreating a namespaces for related apps rather than dumping all into the `default` namespace is a good practice, so let's do that first:\n\n```bash\n$ kubectl create namespace kruiser\n$ go install .\n```\n\n## Use\n\n### Example gRPC demo services\n\nThe two example gRPC [demo services](demo-services/) used below are:\n\n- A simple echo service [yages.Echo](https://github.com/mhausenblas/yages/blob/master/main.go) available via `quay.io/mhausenblas/yages:0.1.0`\n- 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`\n\nAs 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\u0026tab=tags) container image.\n\n### Expose deployment\n\nTo 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.\n\nDefine the gRPC service semantics on the deployment you want to expose like so:\n\n```bash\n$ kubectl -n kruiser annotate deploy/ping kruiser.kubernetes.sh/container-port='9000'\n$ kubectl -n kruiser annotate deploy/ping kruiser.kubernetes.sh/fq-service-name='yages.Echo'\n```\n\nAnd now, in order to trigger the service proxy to be created, label the deployment with `kruiser.kubernetes.sh/grpc=expose`, for example:\n\n```bash\n$ kubectl -n kruiser label deploy/ping kruiser.kubernetes.sh/grpc=expose\n```\n\nNote: use `kubectl -n kruiser label deploy/ping kruiser.kubernetes.sh/grpc-` to remove the label again.\n\n### Walkthroughs\n\nIn 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.\n\n\n```bash\n$ kubectl create namespace kruiser\n```\n\n#### Minikube \n\nFirst, install Ambassador with:\n\n```bash\n$ kubectl -n kruiser apply -f ambassador/admin.yaml\n```\n\nNext, deploy the two gRPC demo services:\n\n```bash\n$ kubectl -n kruiser apply -f demo-services/\n```\n\nNow you can invoke each of the gRPC demo services from outside Minikube like so:\n\n```bash\n$ grpcurl --plaintext $(minikube ip):31001 yages.Echo.Ping\n\n$ grpcurl --plaintext  -d '{ \"name\" : \"Michael\" }' $(minikube ip):31000 helloworld.Greeter.SayHello\n```\n\nAlternatively, you can access one of the gRPC services via the gRPC jump pod like so:\n\n```bash\n$ kubectl -n kruiser run -it --rm gumpod \\\n          --restart=Never --image=quay.io/mhausenblas/gump:0.1\n\n/go $ grpcurl --plaintext ping:9000 yages.Echo.Ping\n```\n\n#### GKE\n\nNote that the GKE deployment in the following uses RBAC for access control.\n\nAs a preparation, you need to give your user certain rights.\n\n```bash\n$ cat ambassador/gke-crb.yaml | \\\n  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 | \\\n  kubectl -n kruiser apply -f -\n```\n\nAbove, 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.\n\nNext, install Ambassador with:\n\n```bash\n$ kubectl -n kruiser apply -f ambassador/admin-rbac.yaml\n```\n\nAnd now deploy the two gRPC demo services:\n\n```bash\n$ kubectl -n kruiser apply -f demo-services/\n```\n\nTo 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`):\n\n```bash\n$ kubectl get nodes --selector=kubernetes.io/role!=master \\ \n                    -o jsonpath={.items[*].status.addresses[?\\(@.type==\\\"ExternalIP\\\"\\)].address}\n```\n\nNow, finally, you can invoke each of the gRPC demo services from outside the GKE cluster like so: \n\n```bash\n$ grpcurl --plaintext $(NODE_IP):31001 yages.Echo.Ping\n\n$ grpcurl --plaintext  -d '{ \"name\" : \"Michael\" }' $(NODE_IP):31000 helloworld.Greeter.SayHello\n```\n\n#### Cleanup\n\nWhen done, clean up with:\n\n```bash\n$ kubectl delete ns kruiser\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmhausenblas%2Fkruiser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmhausenblas%2Fkruiser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmhausenblas%2Fkruiser/lists"}