Kubexpose: A Kubernetes Operator, for fun and profit!
Tags: kubernetes, go, docker
Published: 2021-09-19 04:40:11

Say you have a web service running as a Kubernetes `Deployment`. There are a bunch of ways to access it over a public URL, but [Kubexpose](https://github.com/abhirockzz/kubexpose-operator) makes it easy to do so. It's a [Kubernetes Operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) backed by a [Custom Resource Definition](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) and the corresponding controller implementation.

> `Kubexpose` is built using [kubebuilder](kubebuilder.io) and [available on GitHub](https://github.com/abhirockzz/kubexpose-operator)

![](https://media.giphy.com/media/idH8hdCYBSThguUPnj/giphy.gif?cid=ecf05e47l23bjcbsl7arj8f2ft2g9chb69hkift19x86onj0&rid=giphy.gif&ct=g)

To try it out, jump into the next section or scroll down to **How it works?** to learn more

## Quick start

Any Kubernetes cluster will work (`minikube`, `kind`, Docker Desktop, on the cloud, whatever...).

To deploy the operator and required components:

```bash
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubexpose-operator/master/kubexpose-all-in-one.yaml
```

Make sure the Operator is up and running:

```bash
export OPERATOR_NAMESPACE=kubexpose-operator-system

# check Pods
kubectl get pods -n $OPERATOR_NAMESPACE

# check logs
kubectl logs -f $(kubectl get pods --namespace $OPERATOR_NAMESPACE -o=jsonpath='{.items[0].metadata.name}') -c manager -n $OPERATOR_NAMESPACE
```

Create a `nginx` Deployment to test things out — this is the one you want to expose over the internet using a public URL).

Along with it, create a `kubexpose` resource — which will help you access `ngnix` Deployment over the Internet!

```bash
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubexpose-operator/master/quickstart/nginx.yaml

kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubexpose-operator/master/quickstart/kubexpose.yaml
```

Wait for a few seconds and check the public URL at which the Nginx `Deployment` can be accessed:

```bash
kubectl get kubexpose/kubexpose-test -o=jsonpath='{.status.url}'
```

> Access the public URL using your browser or test it using `curl`

Confirm that the `Service` and `Deployment` have been created as well:

```bash
kubectl get svc/nginx-test-svc-kubexpose-test
kubectl get deployment/nginx-test-expose-kubexpose-test
```

> You can try out other scenarios such as trying to `Deployment` and/or `Service` - the Operator will reconcile or bring things back to the state as specified in the resource.

To delete the `kubexpose` resource:

```bash
kubectl delete kubexpose/kubexpose-test
```

> This will also delete the `Service` and `Deployment` which were created for this resource

To uninstall the Operator:

```bash
kubectl delete -f https://raw.githubusercontent.com/abhirockzz/kubexpose-operator/master/kubexpose-all-in-one.yaml
```

> This will delete the CRD, `kubexpose` operator and other resources.

## How does it work?

Behind the scenes, `Kubexpose` uses the awesome [ngrok](https://ngrok.com/) project to get the job done!
When you create a `kubexpose` resource, the operator:

- Creates a `ClusterIP` type `Service` for the `Deployment` you want to access (naming format: `<deployment name>-svc-<kubexpose resource name>`)
- Creates a `Deployment` (using this [ngrok Docker image](https://hub.docker.com/r/wernight/ngrok/)) that runs `ngrok` - which is configured to point to the `Service` (naming format: `<deployment name>-expose-<kubexpose resource name>`). It's equivalent to starting `ngrok` as such: `ngrok http foo-svc-bar 80`

![](https://miro.medium.com/max/1400/1*j2nb3_3HfuBz2QovyO9lmA.jpeg)

> The `Deployment` and `Service` and owned and managed by the Kubexpose resource instance.

Enjoy!