Under development environment, you might want to debug or test some containers by adding Service with NodePort but you don’t know how to access it. Well, I will show you how to determine Kubernetes node IP address for this particular usecase.
You might also want to read my complete guide to setup Kubernetes for development.
Kubernetes Node IP Address
Let say we have a web service container, we want to expose and test it in web browser, this is what our template might look like:
apiVersion: v1
kind: Service
metadata:
name: web-service-local
spec:
type: NodePort
ports:
- port: 4000
targetPort: 8080
nodePort: 9000
selector:
app: backend
The backend web service container runs on port 8080 inside its pod, and we want it to be accessible on browser via nodePort: 9000
. The question here is, “what is the domain name or IP address should we type in browser to access?”
Let’s dig out some IP addresses that we can try out.
Start first with the web backend pod:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-backend 1/1 Running 0 31s 10.1.0.13 docker-desktop <none> <none>
Try to access it via browser with http://10.1.0.13:9000 , it doesn’t work. Why?
Well, the pod is isolated, and certainly you cannot access it directly. The only way to access it is to create a Service resource and forward the network connection. That explains why we have to create web-service-local
Service at the beginning.
Let see something about service then:
$ kubectl get service -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
web-service-local NodePort 10.108.148.158 <none> 4000:9000/TCP 4m30s app=backend
Ah ha, new IP address, try it out in browser http://10.108.148.158:9000 , and it’s not going to work again.
Alright, here is the correct IP address.
Because we are trying to expose it via NodePort
, implicitly, it means the node that pod is running on inside the cluster, so we should find the Node IP address and use it.
Let see some information about the nodes:
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
minikube Ready master 4h55m v1.17.3 192.168.64.4 <none> Buildroot 2019.02.9 4.19.94 docker://19.3.6
The IP address is 192.168.64.4 , this should be the same as IP address of the cluster managed by minikube
.
$ kubectl cluster-info
Kubernetes master is running at https://192.168.64.4:8443
KubeDNS is running at https://192.168.64.4:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
It can also be retrieved via this command:
$ minikube ip
192.168.64.4
If you type into browser the location: http://192.168.64.4:9000 , it should work fine now.
However, it is a little bit different if using docker-desktop
, which is setup by Docker for Mac or Docker for Windows (I think).
The result is a bit different, and here they are:
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
docker-desktop Ready master 46h v1.15.5 192.168.65.3 <none> Docker Desktop 4.19.76-linuxkit docker://19.3.5
$ kubectl cluster-info
Kubernetes master is running at https://kubernetes.docker.internal:6443
KubeDNS is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
$ cat /etc/hosts
# Added by Docker Desktop
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
They are not the same, right?
The thing is that Docker desktop version setup the cluster directly into your OS, not using any extra VM like minikube
. Therefore, what you need to do whenever you need to access your local node is to use the IP address configured inside /etc/hosts
to access your node.
That’s it! No more trouble finding the correct Kubernetes node IP address in development.