I've set up a minikube cluster on an Azure's Ubuntu instance that exposes an external service on the IP: 192.168.49.2:30000
curl 192.168.49.2:30000
returns the desired output.
How can I access this service using a browser on my local machine using the azure host public IP address ?
OK, I see that docker driver by default uses 192.168.49.2
IP address:
azureuser@minikube:~$ minikube service web --url
http://192.168.49.2:31527
so most probably you've used this one. Although the further explanation is based on virtualbox example it can be fully applied also in this case, with the only difference that minikube runs as an isolated docker container and not as a VM. But if you run docker ps
on your Azure VM instance you'll see only one container, named minikube
:
azureuser@minikube:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
af68ab219c6c gcr.io/k8s-minikube/kicbase:v0.0.14 "/usr/local/bin/entr…" 53 minutes ago Up 53 minutes 127.0.0.1:32771->22/tcp, 127.0.0.1:32770->2376/tcp, 127.0.0.1:32769->5000/tcp, 127.0.0.1:32768->8443/tcp minikube
Only after running:
azureuser@minikube:~$ minikube ssh
and then:
docker@minikube:~$ docker ps
you'll see both the container running by your app Pod
as well as kubernetes control plane components. The list is quite long so I won't put it here.
But it shows that your kubernetes cluster is in practice isolated in a very similar way from your Azure VM host as in case when it runs in a nested VM. The key point here is that minikube cluster's network is isolated from host VM network and NodePort
Service is accessible only on the external IP of a VM or minikube
docker container, not exposing any port on any of host VM network interfaces.
I've reproduced your case, assuming that you started your minikube with virtualbox driver, so please correct me if my assumption was wrong. You could've started it this way:
minikube start --driver=virtualbox
or simply:
minikube start
If you've installed VirtualBox on your minikube vm, it will be also automatically detected and virtualbox
driver will be used.
OK, so let's pause for a moment at this point and take a closer look what such approach implies.
Your minikube runs inside your Azure VM but it doesn't run directly on it. Nested virtualization is used and your minikube kubernetes cluster actually runs on a vm inside another vm.
So if you've exposed your Deployment
using NodePort
service, it makes it available on the external IP address of minikube vm (which is nested vm). But this IP is external only from the perspective of this vm.
Let's ssh into our Azure VM and run:
azureuser@minikube:~$ minikube service web --url
http://192.168.99.100:31955
Your service name and address will be different but I'm showing it just to illustrate the idea.
Then run:
azureuser@minikube:~$ ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 10.0.0.4/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
3: vboxnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 192.168.99.1/24 brd 192.168.99.255 scope global vboxnet0
valid_lft forever preferred_lft forever
As you can see 192.168.99.100
is reachable via vboxnet0
network interface as it's part of 192.168.99.0/24
network, used by virtualbox vm.
Therefore there are no means for it to be reachable without using additional port forwarding, not only on the external IP of the Azure VM but on any of its internal network interfaces. NodePort
service exposes the Deployment
only on the external IP of the nested VirtualBox VM (or other hypervisor), which is reachable from Azure VM host but it's not exposed on any of it's network interfaces so it cannot be reached from outside either.
Did I just say port forwarding ? Fortunately kubectl
makes it fairly easy task. If you haven't installed it so far on your Azure VM, please do it as minikube kubectl
may not work. You can use for it the following command:
kubectl port-forward --address 0.0.0.0 service/<service-name> 8080:8080
which will forward the traffic destined to any of Azure VM addresses (also the public one) to your Service
, which in this case doesn't even have to be of NodePort
type, ClusterIP
will also work.
Caveat: To be able to bind to a well known port such as 80
you need to run this command as root
. If you use registered ports, starting from 1024
such as 8080
you don't need root access. So after running:
root@minikube:~# kubectl port-forward --address 0.0.0.0 service/web 80:8080
You should be able to access your app without any problems by using the external IP address of your Azure VM.