I Exposed My $70 Kubernetes Cluster to the Internet (Without Opening a Single Port)

Published: (January 10, 2026 at 08:28 PM EST)
2 min read
Source: Dev.to

Source: Dev.to

The Problem

Locally I accessed Grafana via http://192.168.0.173:30300.
Opening ports to the internet is like leaving your front door unlocked. I didn’t want to risk a crypto‑miner running on my GTX 1070 Ti.

I needed a solution that was:

  • Secure – no open ports.
  • Free – staying on a budget.
  • Public – reachable via subdomain.domain.com.

Enter Cloudflare Tunnel.

The Zero Trust Switch

DNS Migration

Old wayNew way
Squarespace Registrar → Netlify DNSSquarespace Registrar → Cloudflare DNS → Netlify (main site) + Tunnel (subdomains)

I migrated my nameservers to Cloudflare, which automatically imported my existing records with zero downtime.

Deploying cloudflared to Kubernetes

Instead of running the binary on each node (Pop!_OS desktop, Ubuntu laptop), I deployed the tunnel connector as a native Kubernetes deployment.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cloudflared
spec:
  replicas: 2
  template:
    spec:
      containers:
        - name: cloudflared
          image: cloudflare/cloudflared:latest
          args:
            - tunnel
            - --no-autoupdate
            - run
            - --token
            - $(TUNNEL_TOKEN)

Now the cluster dials out to Cloudflare automatically. If a node reboots, Kubernetes reschedules the pod and the tunnel reconnects instantly.

Goodbye NodePorts, Hello Subdomains

In the Cloudflare Dashboard (Network > Tunnels) I mapped public hostnames to internal ClusterIPs (or NodePorts):

  • grafana.bhargavmantha.dev → http://192.168.0.173:30300
  • ollama.bhargavmantha.dev → http://192.168.0.173:31434
  • uptime.bhargavmantha.dev → http://192.168.0.173:30001

SSL certificates are handled automatically by Cloudflare at the edge, so I get the padlock icon without configuring cert‑manager or Let’s Encrypt inside the cluster.

Lessons Learned

Lesson 1 – Ingress Controllers are Overkill for Homelabs

I spent days trying to get Traefik or Nginx Ingress to work with MetalLB on a bare‑metal cluster. Cloudflare Tunnel bypasses that entire layer. I don’t need an Ingress Controller; I just need a connector.

Lesson 2 – Security Can Be Convenient

By putting everything behind Cloudflare, I can later add an Access Application layer—e.g., protect grafana.bhargavmantha.dev with a Google/GitHub login screen, adding 2FA to apps that don’t support it natively.

Current State

  • Publicly Accessible: Grafana, Uptime Kuma, Open WebUI.
  • Cost: $0 (Cloudflare Free Tier).
  • Security: 0 open ports.
Back to Blog

Related posts

Read more »

Hello, Newbie Here.

Hi! I'm falling back into the realm of S.T.E.M. I enjoy learning about energy systems, science, technology, engineering, and math as well. One of the projects I...