Hi ,
I installed minikube on my mac and created deployment and a service for my nodejs app. I tested that everything is working by getting the URL of my service using the following command:
minikube service my-nodejs-app --url
and then i run this URL in the browser and got results. The problem is when i tried to access the same URL from another machine inside the same network it didn't worked.
my service .yml file is:
apiVersion: v1
kind: Service
metadata:
name: my-nodejs-app
spec:
type: NodePort
ports:
- port: 80
targetPort: 1337
protocol: TCP
name: app-server
selector:
app: my-nodejs-app
#
Thanks in advanced for any help.
Minikube creates a network for itself and the VM. You have two options if you want to externally expose your service
Port Forward a Pod
$ kubectl port-forward -h
Forward one or more local ports to a pod.
Examples:
# Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod
kubectl port-forward mypod 5000 6000
# Listen on port 8888 locally, forwarding to 5000 in the pod
kubectl port-forward mypod 8888:5000
# Listen on a random port locally, forwarding to 5000 in the pod
kubectl port-forward mypod :5000
# Listen on a random port locally, forwarding to 5000 in the pod
kubectl port-forward mypod 0:5000
Options:
-p, --pod='': Pod name
Usage:
kubectl port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N] [options]
Use "kubectl options" for a list of global command-line options (applies to all commands).
Port Forward a Service
ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -L 30000:localhost:30000
Hi @r2d4 thanks for your answer.
I tried to expose the service and its again work only on my local machine (when i am running the cluster). I open the browser and go to localhost:30000 and see the dashboard but when i tried to access it from another computer in the same network i get "page not found". On the other machine i tried with the ip address of the machine where minikube runs but i still get page not found.
Ah right, you'll need to do something like:
ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -L 30000:0.0.0.0:30000
using 0.0.0.0
instead of localhost
to be able to access it from somewhere else.
Hi @dlorenc thanks but it still not working.. I use 0.0.0.0 and then tried to access it from another machine in the same network but I still get the site can't be reached..
I tried with the ip address where kuberenetes is hosted (http://192.168.1.14:30000) and also with minikube ip address (http://192.168.99.100:30000) and both not working ..
The only solution that currently works for me is to setup a nginx reverse proxy that forward the traffic to the kubernetes cluster but the question is.. do i must use this setup?
You should use the IP of your machine on the network that you're trying to access. The 192.168.1.x subnet is for your machine and the VM that runs kubernetes.
Hi,
All the suggested solution above not worked for me.. The only thing that works is to have a nginx proxy that forward the requests from the localhost to the pod ip address.
@r2d4 do you have more ideas how it can be done maybe? it's still not working for me and i really want to avoid the nginx workaround...
thanks.
I have the same problem, and the suggestions commented above work only to redirect to localhost or 127.0.0.1 but if I try to access by mi IP it doesn't work.
Also, if I try to access from another computer in the network it doesn't work too
for me it works if I bind to all interfaces like this:
ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -L \*:30000:0.0.0.0:30000
When using VirtualBox as hypervisor, you can also use the VirtualBox NAT port forwarding feature to allow access to services exposed through NodePorts from outside.
Something like this (limited range, exposing the entire default NodePort range of 30000-32767 takes forever...):
for port in {30000..30100}; do VBoxManage controlvm minikube natpf1 "NodePort$port,tcp,,$port,,$port"; done
You can combine that with a reverse SSH tunnel to a VPS so anyone can have temporary access from the public internet:
R_ARGS=$(for port in {30000..30100}; do echo -n "-R $port:localhost:$port "; done)
autossh -M 0 -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ExitOnForwardFailure=yes -o ServerAliveInterval=5 -o ServerAliveCountMax=3 [email protected] -N $R_ARGS
To delete the VirtualBox port forward rules:
for port in {30000..30100}; do VBoxManage controlvm minikube natpf1 delete "NodePort$port"; done
The SSH forward method is easier though, and hypervisor agnostic I suppose, so thanks for that!
@siwyd VirtualBox port forward rules worked for me. Thanks!
@The-Crocop can you please explain that a little bit more? When I do this command it just puts me into the minikube ssh. How can I then access my service from another computer in my LAN?
@ranhsd did you ever figure this out? Where did you learn about the nginx workaround?
Hi @xandriaw I was able to do it only via nginx and it was my "common sense" ...
Ran.
same as @ranhsd, I was only able to do it using nginx
@zak905 @xandriaw
can you please suggest or post the nginx solution that worked for you.I am also facing the same situation :(
it depends on what kind of connections you establish, here are examples for each case. I hope that helps.
#this import is only relevant if you are using streams
load_module /usr/lib/nginx/modules/ngx_stream_module.so;
http {
server {
#your host ip address
listen 150.90.22.22:9999;
client_max_body_size 20M;
#e.g for a Rest call
location /someendpoint {
#your minikube local ip + svc port
proxy_pass http://192.168.99.100:32608;
}
#e.g if you are serving files like html and you need to access from the browser, you need to add proxy_set_header
location / {
proxy_pass http://192.168.99.100:31622/;
proxy_set_header Host $host:$server_port;
}
}
stream {
#if you have non http connections, like database for example, you need to use streams
server {
#different port
listen 150.90.22.22:3333;
proxy_pass 192.168.99.100:30105;
}
}
Similarly as some others (@ranhsd, @xandriaw) I had problems when binding my minikube service to my local network. I managed to make forwarding work using these commands (you could also replace the wildcard \*
by your machine local IP address):
service_name=web # This is what you need to replace with your own service
service_port=$(minikube service $service_name --url | cut -d':' -f3)
ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -NL \*:${service_port}:0.0.0.0:${service_port}
Then in another terminal we can test it:
❯ curl http://0.0.0.0:32491/
{"hello":"world"}
❯ curl http://192.168.200.141:32491/
{"hello":"world"}
I struggled to make it work so I'll post my failures here, maybe it will help people and maybe someone will be able to explain why it worked.
First, when I ran the @The-Crocop command it opened an ssh terminal on my minikube machine:
❯ ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -L \*:32491:0.0.0.0:8089
_ _
_ _ ( ) ( )
___ ___ (_) ___ (_)| |/') _ _ | |_ __
/' _ ` _ `\| |/' _ `\| || , < ( ) ( )| '_`\ /'__`\
| ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )( ___/
(_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____)
$
I found in the ssh
documentation that -N could be what is needed here :
❯ man ssh
-N Do not execute a remote command. This is useful for just forwarding ports.
So I tried:
❯ ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -N -L \*:32491:0.0.0.0:8089
Which seems do nothing but keeps the task pending (which is most likely what we want):
❯ ps | grep $(lsof -ti:32491)
72600 ttys014 0:00.02 ssh -i /Users/cglacet/.minikube/machines/minikube/id_rsa [email protected] -N -L *:32491:0.0.0.0:8089
But in the end I can't access the service on this port, the service is still available on my machine via the url: $(minikube service web --url)
. I though maybe the port is the problem, so I tried to investigate:
❯ cat /etc/services | grep 8089
# 8089-8099 Unassigned
That seemed ok to me, but I don't know much about this so I tried another port anyway (since I had no idea, I simply used the same port as my service was running on, port 32491):
❯ cat /etc/services | grep 32491
❯ ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -N -L \*:32491:0.0.0.0:32491
And this time, it worked … No idea why tho.
@cglacet Thanks for the solution.
This from your solution works for me:
service_name=web # This is what you need to replace with your own service
service_port=$(minikube service $service_name --url | cut -d':' -f3)
ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -NL \*:${service_port}:0.0.0.0:${service_port}
@parikmaan If the above mentioned solution works, then were you able to access the service from an external machine? I mean, the problem is when trying to access the same URL from another machine inside the same network. Did it work or only the http://localhost:${service_port}
worked?
Did you get it work for http://<host_machine_ip>:${service_port}
from a different machine in same network?
@cglacet
❯ curl http://0.0.0.0:32491/
{"hello":"world"}
❯ curl http://192.168.200.141:32491/
{"hello":"world"}
Did you run these curl commands in another terminal in host machine or in a terminal from completely different machine? Because running these commands in host machine will work, but the issue is to actually curl to the links from a different machine.
@arviCV My goal was to access my kubernetes instance which lies in minikube (a VM). Normally I would access it via a specific ip/port that is only available on my local machine (minikube ip
). By doing what I proposed, I managed to access it via my host IP which means anyone in the same network could access it too.
In other words:
❯ curl http://192.168.200.141:32491/
{"hello":"world"}
Would work for anyone in my local network.
@cglacet : Ok. Now it works for me too.
@The-Crocop : Thanks a bunch . The solution provided works.
Please mind that sometimes, in restricted local networks certain ports of localhost machine can be deliberately blocked from opening. Just in case if others face similar issue, I would like to share this solution.
service_name=web # This is what you need to replace with your own service
service_port=$(minikube service $service_name --url | cut -d':' -f3)
ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -L \*:<available_open_port_to_listen>:0.0.0.0:${service_port}
Finally,
❯ curl http://host_machine_ip:available_open_port_to_listen/
{"hello":"world"}
@arviCV My setup is like this:
Minikube running multiple services
Dev setup which need access to services running in Minikube
With @cglacet solution, I can access my services running from Machine 1 or Machine 2 using the IP address (Local address) of Machine 1.
I think I found a tool (Skaffold) that I use as a replacement for manual port forwarding (and many other things like hot reloading for example). I feel like it's the missing piece for me, I struggled finding a workflow for local development using kubernetes, but I think that this fits my needs.
I wonder how I missed that tool. Hope it will help others here.
Most helpful comment
for me it works if I bind to all interfaces like this:
ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -L \*:30000:0.0.0.0:30000