Minikube tunnel is a magical incantation that makes your cloud-native services accessible from your local machine as if they were running on a real Kubernetes cluster.

Let’s see it in action. Imagine you have a simple Kubernetes deployment and a service of type LoadBalancer pointing to it:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: nginx:latest
        ports:
        - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

When you apply this to Minikube without minikube tunnel running, the EXTERNAL-IP for my-app-service will remain <pending>. This is because a LoadBalancer service type in a real cloud environment provisions an actual cloud load balancer, which Minikube, by itself, cannot do.

Now, start minikube tunnel in a separate terminal:

minikube tunnel

You’ll see output indicating it’s setting up network routes. Once it’s running, go back to your kubectl get svc output. The EXTERNAL-IP for my-app-service will now be an IP address, typically 127.0.0.1 or 192.168.x.x depending on your Minikube network configuration.

You can then access your service by navigating to http://127.0.0.1:80 (or whatever IP address is assigned) in your web browser. The request goes through the tunnel, is routed by Minikube to your service’s pods, and the response comes back the same way.

The core problem minikube tunnel solves is bridging the gap between Kubernetes’ abstract LoadBalancer service type and the reality of a local development environment. In a cloud, Kubernetes controllers watch for LoadBalancer services and interact with cloud provider APIs (AWS ELB, GCP Load Balancer, Azure Load Balancer) to provision external IPs and configure routing. On your laptop, there’s no cloud provider to talk to. minikube tunnel acts as a local proxy. It essentially creates a virtual network interface on your host machine and manipulates your host’s routing table to direct traffic destined for the LoadBalancer IP to your Minikube cluster. It also handles the reverse: traffic from the cluster to the external IP is correctly NATed and forwarded.

The primary lever you control is the type field in your Service definition. Setting it to LoadBalancer is the trigger. minikube tunnel then takes over the responsibility of making that LoadBalancer IP address reachable from your host. You don’t need to configure anything else within Minikube itself; the tunnel command handles the networking magic.

The most surprising aspect of minikube tunnel is how it intercepts and manipulates your host’s network stack. It doesn’t just forward traffic; it actively creates and manages routes. When minikube tunnel starts, it often runs a DHCP server within Minikube to assign an IP to the tunnel interface and then adds routes to your host’s operating system. This means that traffic destined for the IP address assigned to your LoadBalancer service is intercepted by the tunnel and directed into your Minikube VM, and replies are routed back out. It’s a sophisticated piece of network plumbing that makes the cloud abstraction feel real.

The next concept you’ll likely encounter is how to handle persistent storage for your applications within Minikube, which involves understanding PersistentVolumes and PersistentVolumeClaims.

Want structured learning?

Take the full Minikube course →