3 minutes
Replacing ngrok with ktunnel
ngrok is a tool that proxies traffic from a subdomain (like http://2fb551c6b2fd.ngrok.io) to a port on your localhost. I’ve been using it off and on for years. There’s a couple use cases I’ve used it for:
- Forward web traffic to a local next.js / webpack server, to show a website in progress without having to deploy it. This way I can send an ngrok link to a friend/coworker and they can see the latest.
- Forward api traffic from a device (ex. an iPhone if I’m working on an iOS app) to my local api server.
It’s been very useful, but recently I’ve switched to
ktunnel
. ktunnel
deploys a service on
kubernetes, which will proxy traffic to a local port of your choice. It’s more
work to set up than ngrok
, so it won’t be worth the hassle for a lot of
people, but there’s a few upsides to self-hosting.
The biggest benefit for me is that I can use my own domain, so instead of a random ngrok subdomain I’ll set it up on something like http://apiproxy.mbuffett.com. Additionally, there’s no connections limit, you’re only limited by the server you’re hosting your cluster on. Last but not least, it’s free if you have a cluster available, which I happened to have.
Requirements
I’ll assume that you have a kubernetes cluster running. If you don’t, and want to get started with one,
you can start a cluster and connect to it with kubectl pretty quickly. I
recommend Digital Ocean, they have an easier setup than AWS/GKE. Once you’re at
the point where you can run kubectl get all
, and have an ingress controller
set up (I use
kong), then you’re
good to go.
Running
First, you’ll need to install ktunnel
, check out the installation instructions
here for the latest. I built from source
but you can also get the latest binary. After that, you can start ktunnel like
this:
ktunnel expose ktunnel-proxy <LOCAL_PORT>
This will create aservice on your cluster called ktunnel-proxy
, which will
take traffic on port 80 and forward it to your localhost on port <LOCAL_PORT>
.
The next step is to expose the new service to the world. To do that, create an ingress that looks like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ktunnel-proxy
spec:
rules:
- host: proxy.<YOUR_TLD>
http:
paths:
- path: /
backend:
serviceName: ktunnel-proxy
servicePort: 80
Of course, you’ll also have to set up DNS to get traffic from YOUR_TLD
to go to
your cluster. If you’re using Digital Ocean, you can point the A records to
a load balancer that points to your cluster.
So after this, when you go to proxy.<YOUR_TLD>
:
- DNS will resolve to your cluster IP
- The ingress controller will direct traffic to the
ktunnel-proxy
service - The
ktunnel-proxy
service will direct traffic to your<LOCAL_PORT>
on your localhost
Gotchas
Keep in mind that the termination process for ktunnel will try to delete the
service and deployment it created on startup. If you’ve lost internet connection
or something, it’s possible this doesn’t get run. If ktunnel
isn’t able to
start up, you may want to run kubectl get services
and see if there’s a stray
ktunnel
service hanging around.
If you play games, my PSN is mbuffett, always looking for fun people to play with.
If you're into chess, I've made a repertoire builder. It uses statistics from hundreds of millions of games at your level to find the gaps in your repertoire, and uses spaced repetition to quiz you on them.
If you want to support me, you can buy me a coffee.
526 Words
2020-08-01 17:19 +0000