Skip to content
Expose web services directly on GKE nodes during development.
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
AUTHORS Initial release of kubehost Oct 2, 2018
CONTRIBUTING.md Initial release of kubehost Oct 2, 2018
CONTRIBUTORS Initial release of kubehost Oct 2, 2018
LICENSE Initial release of kubehost Oct 2, 2018
README.md Fix get-credentials link in README.md Oct 3, 2018
kubehost Initial release of kubehost Oct 2, 2018

README.md

kubehost

Kubehost helps you expose services directly on nodes of your Google Kubernetes Engine (GKE) cluster.

The common way to expose a service and get an external IP is kubectl expose <deployment> --type=LoadBalancer", which will expose your deployment on a production-grade Google Cloud Load Balancer. Sometimes you just want to expose a service on your VM directly, like during development where uptime and reliability are not as important. That's where Kubehost comes in.

Kubehost uses existing features of GKE to expose your service directly onto one of the VMs in your cluster, by creating a Pod that runs on the VM's network and forwards traffic to your in-cluster (ClusterIP) service, and creating firewall rules to permit external traffic. While you could do this manually, Kubehost takes the toil out of managing this configuration by automating the necessary actions.


⚠️ For development use only

kubehost is NOT designed for production use! Nodes in GKE are designed to be redundant, meaning they can fail. When the node on which your service is exposed via kubehost fails or is upgraded, your service will experience several minutes of downtime. By comparison, if you use a production-grade Google Cloud Load Balancer (and you have enough replicas of your Pod spread over multiple nodes with properly implemented health and readiness checks) then a node can fail with only minimal impact to the availability of your service. At any time you can upgrade to a Google Cloud Load Balancer with the kubehost upgrade command.

Installation

kubehost is a bash script. To install, clone this repository and add it to your $PATH, or copy kubehost to your /usr/local/bin/.

You may need to set the executable permission, i.e. chmod +x kubehost.

Configuration

Before using kubehost, you need to ensure both gcloud and kubectl are configured with your desired project & cluster.

  1. run gcloud init to select your account, project and region containing the GKE cluster.
  2. run get-credentials to configure kubectl.

Exposing a Deployment with kubehost

  1. Create your deployment like normal.
  2. Create a ClusterIP service for your deployment (this is the default service type, so no need to specify any type), on your desired external port.
  3. Run kubehost bind ${SERVICE}, where ${SERVICE} is the name of the Kubernetes service you created at step 2.

What this does is create some "glue" in the form of a hostPort deployment so that your service is bound to port you specified in the service on your node's external IP (read "under the hood" for a longer technical description). It also opens the necessary GCP firewall rules.

To undo, kubehost unbind ${SERVICE}

Complete example:

kubectl run hello --image gcr.io/google-samples/hello-app:1.0 --port 8080
kubectl expose deployment hello --port 80 --target-port 8080 --name hello-service
kubehost bind hello-service

Cleanup:

kubehost unbind hello-service
kubectl delete deployment hello
kubectl delete service hello-service

Switching between hostPort and a Load Balancer

Upgrading to a Load Balancer from hostPort

Is your app ready for prime time? Remove the hostPort Pod "glue", and convert your Service into one backed by a Google Cloud Load Balancer with one simple command:

kubehost upgrade ${SERVICE}

Where ${SERVICE} is the name of your Cluster IP service.

Downgrading a Load Balancer to hostPort

Did you already expose your service with a Load Balancer and found it's more than you needed? Convert it to an internal ClusterIP service, and expose it on a host in one command with:

kubehost downgrade ${SERVICE}

Where ${SERVICE} is the name of your Kubernetes service of type LoadBalancer.

Limitations

  • Kubehost currently works with services that have a single port. If you need to expose two ports, create two ClusterIP services.
  • Kubehost is not designed for production usage, see the note above.
  • Kubehost doesn't give you a static IP. The IP address of node may change which will affect your service. You can create a static IP and use the kubeIP operator to keep it assigned through node maintenance events.

Under the Hood

What Kubehost is doing when you call bind is creating a Kubernetes Deployment with a single replica of a Pod that uses hostPort to bind onto the host's network interface. The container in this Pod forwards traffic to your ClusterIP service.

While you could instead change your deployment to use hostPort directly we think this approach is superior, as:

  1. It's closer to the production Kubernetes experience where deployments have a matching service to receive traffic.
  2. It's easier to switch between this and a production setup by changing the Service type to LoadBalancer, and removing the hostPort deployment (and vice-versa) – no need to modify your application deployment.
  3. Your deployment's replica count isn't limited by available ports.
You can’t perform that action at this time.