An open API service indexing awesome lists of open source software.

https://github.com/googlecontainertools/kubehost

Expose web services directly on GKE nodes during development.
https://github.com/googlecontainertools/kubehost

Last synced: 4 months ago
JSON representation

Expose web services directly on GKE nodes during development.

Awesome Lists containing this project

README

          

# 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 --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.


> ### :warning: 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:

```bash
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:
```bash
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](https://cloud.google.com/load-balancing/)
with one simple command:

```bash
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:

```bash
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](https://github.com/doitintl/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.