Aaron
Aaron

Reputation: 3399

Why Can't I Access My Kubernetes Cluster Using the minikube IP?

I have some questions regarding my minikube cluster, specifically why there needs to be a tunnel, what the tunnel means actually, and where the port numbers come from.

Background

I'm obviously a total kubernetes beginner...and don't have a ton of networking experience.

Ok. I have the following docker image which I pushed to docker hub. It's a hello express app that just prints out "Hello world" at the / route.

DockerFile:

FROM node:lts-slim
RUN mkdir /code
COPY package*.json server.js /code/
WORKDIR /code
RUN npm install
EXPOSE 3000 
CMD ["node", "server.js"]

I have the following pod spec:

web-pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
spec:
  containers:
    - name: web
      image: kahunacohen/hello-kube:latest
      ports:
      - containerPort: 3000

The following service:

web-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: NodePort
  selector:
    app: web-pod
  ports:
    - port: 8080
      targetPort: 3000
      protocol: TCP
      name: http

And the following deployment:

web-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-pod
      service: web-service
  template:
    metadata:
      labels:
        app: web-pod
        service: web-service
    spec:
      containers:
      - name: web
        image: kahunacohen/hello-kube:latest
        ports:
        - containerPort: 3000
          protocol: TCP

All the objects are up and running and look good after I create them with kubectl.

I do this:

$ kubectl get services                                                                            
NAME          TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes    ClusterIP   10.96.0.1      <none>        443/TCP          7h5m
web-service   NodePort    10.104.15.61   <none>        8080:32177/TCP   25m
  1. Then, as per a book I'm reading if I do:
$ curl $(minikube ip):8080 # or :32177, # or :3000

I get no response.

I found when I do this, however I can access the app by going to http://127.0.0.1:52650/:

$ minikube service web-service
|-----------|-------------|-------------|---------------------------|
| NAMESPACE |    NAME     | TARGET PORT |            URL            |
|-----------|-------------|-------------|---------------------------|
| default   | web-service | http/8080   | http://192.168.49.2:32177 |
|-----------|-------------|-------------|---------------------------|
šŸƒ  Starting tunnel for service web-service.
|-----------|-------------|-------------|------------------------|
| NAMESPACE |    NAME     | TARGET PORT |          URL           |
|-----------|-------------|-------------|------------------------|
| default   | web-service |             | http://127.0.0.1:52472 |
|-----------|-------------|-------------|------------------------|

Questions

  1. what this "tunnel" is and why we need it?
  2. what the targetPort is for (8080)?
  3. What this line means when I do kubectl get services:
web-service   NodePort 10.104.15.61   <none>        8080:32177/TCP   25m

Specifically, what is that port mapping means and where 32177 comes from?

  1. Is there some kind of problem with simply mapping the internal port to the same port number externally, e.g. 3000:3000? If so, do we specifically have to provide this mapping?

Upvotes: 3

Views: 6924

Answers (1)

moonkotte
moonkotte

Reputation: 4181

Let me answer on all your questions.

0 - There's no need to create pods separately (unless it's something to test), this should be done by creating deployments (or statefulsets, depends on the app and needs) which will create a replicaset which will be responsible for keeping right amount of pods in operational conditions. (you can get familiar with deployments in kubernetes.


1 - Tunnel is used to expose the service from inside of VM where minikube is running to the host machine's network. Works with LoadBalancer service type. Please refer to access applications in minikube.

1.1 - Reason why the application is not accessible on the localhost:NodePort is NodePort is exposed within VM where minikube is running, not on your local machine.

You can find minikube VM's IP by running minikube IP and then curl %GIVEN_IP:NodePort. You should get a response from your app.


2 - targetPort indicates the service with which port connection should be established. Please refer to define the service.

In minikube it may be confusing since it's pointed to the service port, not to the targetPort which is define within the service. I think idea was to indicate on which port service is accessible within the cluster.


3 - As for this question, there are headers presented, you can treat them literally. For instance:

$ kubectl get svc -o wide
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE    SELECTOR
web-service   NodePort    10.106.206.158   <none>        80:30001/TCP   21m    app=web-pod

NodePort comes from your web-service.yaml for service object. Type is explicitly specified and therefore NodePort is allocated. If you don't specify type of service, it will be created as ClusterIP type and will be accessible only within kubernetes cluster. Please refer to Publishing Services (ServiceTypes).

When service is created with ClusterIP type, there won't be a NodePort in output. E.g.

$ kubectl get svc
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
web-service   ClusterIP   10.106.206.158   <none>        80/TCP    23m

External-IP will pop up when LoadBalancer service type is used. Additionally for minikube address will appear once you run minikube tunnel in a different shell. After your service will be accessible on your host machine by External-IP + service port.


4 - There are not issues with such mapping. Moreover this is a default behaviour for kubernetes:

Note: A Service can map any incoming port to a targetPort. By default and for convenience, the targetPort is set to the same value as the port field.

Please refer to define a service


Edit:

Depending on the driver of minikube (usually this is a virtual box or docker - can be checked on linux VM in .minikube/profiles/minikube/config.json), minikube can have different port forwarding. E.g. I have a minikube based on docker driver and I can see some mappings:

$ docker ps -a
CONTAINER ID   IMAGE                                 COMMAND                  CREATED      STATUS      PORTS                                                                                                                                  NAMES
ebcbc898b557   gcr.io/k8s-minikube/kicbase:v0.0.23   "/usr/local/bin/entrā€¦"   5 days ago   Up 5 days   127.0.0.1:49157->22/tcp, 127.0.0.1:49156->2376/tcp, 127.0.0.1:49155->5000/tcp, 127.0.0.1:49154->8443/tcp, 127.0.0.1:49153->32443/tcp   minikube

For instance 22 for ssh to ssh into minikube VM. This may be an answer why you got response from http://127.0.0.1:52650/

Upvotes: 5

Related Questions