My Profile Photo

Stefan Prodan

DevOps Consultant. DX at Weaveworks. Passionate about Cloud Native tech. Loves programming in Go and building Kubernetes operators.

Expose Kubernetes services over HTTPS with Ngrok

Have you ever wanted to expose a Kubernetes service running on Minikube on the internet and have a temporary HTTPS address for it? If so then Ngrok is a great fit to do that without any firewall, NAT or DNS configurations. If you are developing an application that works with webhooks or oauth callbacks Ngrok can create a tunnel between your Kubernetes service and their cloud platform and provide you with a unique HTTPS URL that you can use to test and debug your service.

I’ve made a Helm chart that you can use to deploy Ngrok on Kubernetes by specifying a ClusterIP service that will get exposed on the internet.

What follows is a step-by-step guide on how you can use Ngrok as a reverse proxy to receive GitHub notifications via webhooks in an application hosted on your local Minikube.

Deploy a webhook receiver

In order to receive notifications from GitHub you need a web application that exposes a HTTP POST endpoint and accepts a JSON payload. Podinfo is a tiny web app made with Go that can receive any kind of payload on the /echo route. Let’s deploy podinfo using Helm.

If you don’t have Helm running on your Kubernetes cluster here is how you can set it up.

First install Helm CLI:

brew install kubernetes-helm

Create a service account for Tiller:

kubectl -n kube-system create sa tiller

Create a cluster role binding for Tiller:

kubectl create clusterrolebinding tiller-cluster-rule \
    --clusterrole=cluster-admin \

Deploy Tiller in kube-system namespace:

helm init --skip-refresh --upgrade --service-account tiller

The podinfo and ngrok charts are hosted on GitHub. Add the k8s-podinfo repo:

helm repo add sp

Install podinfo:

helm install sp/podinfo --name webhook 

This deploys podinfo in the default namespace and creates a ClusterIP service with the address webhook-podinfo:9898.

apiVersion: v1
kind: Service
    app: podinfo
    chart: podinfo-0.1.0
    heritage: Tiller
    release: webhook
  name: webhook-podinfo
  namespace: default
  - name: http
    port: 9898
    protocol: TCP
    targetPort: http
    app: podinfo
    release: webhook
  type: ClusterIP

Deploy Ngrok

Before you begin go to and register for a free account.

Ngrok will create a token for you, use it when installing the Ngrok chart.

Install Ngrok by specifying the ClusterIP address you want to expose:

$ helm install sp/ngrok --name tunnel \
  --set token=NGROK-TOKEN \
  --set service.type=NodePort \
  --set expose.service=webhook-podinfo:9898

The above command deploys Ngrok in the default namespace and exposes the Ngrok web UI on a random node port. Find the port with:

kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services tunnel-ngrok

Now open a browser and navigate to http://<KUBE-IP>:<NGROK-PORT>/status. On the status page you should see the public HTTPS address generated by Ngrok.

Use curl to test if you can reach podinfo /echo route:

curl -d '{"message": "testing ngrok"}'

On the status page you should see that the total number of connections has increased.

Ngrok Status

Setup GitHub webhook

Go to GitHub and create a new repository or use one that you already have. On your repo page go to Settings -> Webhooks -> Add Webhook and enter the Ngrok HTTPS URL adding /echo at the end:

GitHub Webhook

For Content-type select application/json, check Send me everything and click on Add webhook.

Once you hit the add button GitHub will make a call to the /echo URL. Using Ngrok web UI you can inspect the GitHub payload. Navigate to http://<KUBE-IP>:<NGROK-PORT>/inspect/http and you should see the request body:

Ngrok Inspect

Ngrok not only makes it very easy to expose Kubernetes services on the internet but also gives a powerful tool to inspect the traffic to your applications.

You can tear all down by deleting the Helm releases with:

helm delete --purge tunnel webhook
comments powered by Disqus