Skip to content

Expose web services directly on GKE nodes during development.

License

Notifications You must be signed in to change notification settings

bradhoekstra/kubehost

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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)[https://cloud.google.com/sdk/gcloud/reference/container/clusters/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.

About

Expose web services directly on GKE nodes during development.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Shell 100.0%