5

I know minikube should be used for local only, but i'd like to create a test environment for my applications.
In order to do that, I wish to expose my applications running inside the minikube cluster to external access (from any device on public internet - like a 4G smartphone).

note : I run minikube with --driver=docker

kubectl get services

NAME      TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
web8080   NodePort   10.99.39.162   <none>        8080:31613/TCP   3d1h

minikube ip

192.168.49.2

One way to do it is as follows :

firewall-cmd --add-port=8081/tcp
kubectl port-forward --address 0.0.0.0 services/web8080 8081:8080

then I can access it using :

curl localhost:8081      (directly from the machine running the cluster inside a VM)
curl 192.168.x.xx:8081   (from my Mac in same network - this is the private ip of the machine running the cluster inside a VM)
curl 84.xxx.xxx.xxx:8081 (from a phone connected in 4G - this is the public ip exposed by my router)

I don't want to use this solution because kubectl port-forward is weak and need to be run every time the port-forwarding is no longer active.

How can I achieve this ?

(EDITED) - USING LOADBALANCER

when using LoadBalancer type and minikube tunnel, I can expose the service only inside the machine running the cluster.

kubectl get services

NAME         TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
my-service   LoadBalancer   10.111.61.218   10.111.61.218   8080:31831/TCP   3d3h

curl 10.111.61.218:8080 (inside the machine running the cluster) is working
but curl 192.168.x.xx:8080 (from my Mac on same LAN) is not working

Thanks

samasoulé
  • 193
  • 2
  • 3
  • 11

5 Answers5

4

Minikube as a development tool for a single node Kubernetes cluster provides inherent isolation layer between Kubernetes and the external devices (being specific the inbound traffic to your cluster from LAN/WAN).

Different --drivers are allowing for flexibility when it comes to the place where your Kubernetes cluster will be spawned and how it will behave network wise.

A side note (workaround)!

As your minikube already resides in a VM and uses --driver=docker you could try to use --driver=none (you will be able to curl VM_IP:NodePort from the LAN). It will spawn your Kubernetes cluster directly on the VM.

Consider checking it's documentation as there are some certain limitations/disadvantages:


As this setup is already basing on the VM (with unknown hypervisor) and the cluster is intended to be exposed outside of your LAN, I suggest you going with the production-ready setup. This will inherently eliminate the connectivity issues you are facing. Kubernetes cluster will be provisioned directly on a VM and not in the Docker container.

Explaining the --driver=docker used: It will spawn a container on a host system with Kubernetes inside of it. Inside of this container, Docker will be used once again to spawn the necessary Pods to run the Kubernetes cluster.

As for the tools to provision your Kubernetes cluster you will need to chose the option that suits your needs the most. Some of them are the following:

After you created your Kubernetes cluster on a VM you could forward the traffic from your router directly to your VM.


Additional resources that you might find useful:

Dawid Kruk
  • 8,982
  • 2
  • 22
  • 45
2

curl $(minikube ip):$NODE_PORT : Now we can test that the app is exposed outside of the cluster using curl, the IP of the Node and the externally exposed port.

For you : curl 192.168.49.2:31613

Sahadat Hossain
  • 3,583
  • 2
  • 12
  • 19
  • yes this works when i'm on the machine running the cluster, but i'd like to do the same from a smartphone using 4G or another device on public internet. I can make it work using `kubectl port-forwarding` but would like a more robust solution – samasoulé Feb 07 '21 at 12:50
  • thanks for the response, I've managed to have : `NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-service LoadBalancer 10.111.61.218 10.111.61.218 8080:31831/TCP 3d3h` and can access it using curl `10.111.61.218:8080` from the machine running the cluster, but same issue, how to expose this service to the public internet ? when doing `curl 192.168.x.xx:8080` from another local machine, it is not exposed. another way to ask the question, how to have the LoadBalancer get an external public ip ? – samasoulé Feb 07 '21 at 13:11
  • basically external ip is provided by any cloud service provider, you need to have an account in any cloud service provider. Another thing I got, does it help, have a [look](https://itnext.io/expose-local-kubernetes-service-on-internet-using-ngrok-2888a1118b5b) – Sahadat Hossain Feb 07 '21 at 13:13
  • thanks for the link, I read it few minutes ago and will give it a try, I think it works like `kubectl port-forwarding` but may be more efficient :) – samasoulé Feb 07 '21 at 13:16
  • 1
    quick feedback : `ngrok` allows you to "host" your `{minikube-ip}:{node-port}` on a random public DNS name, for example `http://6fc4fc83dd61.ngrok.io` using the command `ngrok http {minikube-ip}:{node-port}`. be careful, you have limited connections per minute etc, see the Pricing on ngrok website – samasoulé Feb 07 '21 at 15:52
  • not really the perfect solution because for each new deployment, you have to run again the command to expose your service through `ngrok` :( – samasoulé Feb 07 '21 at 15:55
1

Use nginx reverse-proxy https://www.zepworks.com/posts/access-minikube-remotely-kvm/

install nginx, then in nginx.conf add this

stream {
    server {
        listen 8081;
        proxy_pass  192.168.49.2:8080;
    }
}

restart nginx

aaa
  • 118
  • 1
  • 7
  • This works!, just correcting the answer syntactically, before the ip, append http:// , remove stream {} and add the proxy_pass statement like this , "location / { proxy_pass 192.168.49.2:8080}" – Manoj Majumdar Apr 14 '22 at 11:46
0

One way that I use to get around the fact that the process of kubectl port-forward stops after a while is to create a detach session using tmux following this. With that, I haven't had any problems with the exact same Minikube cluster configuration that you have.

-1

You can also use Apache's Reverse proxy rules to achieve the same as below:

ProxyRequests Off
ProxyPreserveHost On ProxyVia Full

ProxyPass / http://192.168.59.110/ ProxyPassReverse / http://192.168.59.110/

The complete scenario (for a bare-metal machine) is available here for review and can be replicated for understanding.