dockerubuntukubernetescicdminikube

Can't access a Minikube's NodePort service from outside


I'm new to Kubernetes and I'm in the process of deploying my Docker containers to a Minikube server.

I've installed Minikube on Docker running on a Linux server with the local IP address 10.0.0.92. When I check the Minikube's IP, it returns 192.168.49.2.

I'm following the "Deploy to Kubernetes" guide on the Docker website.

Here are my deployment and service configurations:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-name
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-name
  template:
    metadata:
      labels:
        app: app-name
    spec:
      containers:
        - name: app-name
          image: docker-hub-username/app-name:latest
          ports:
          - containerPort: 9600
---
apiVersion: v1
kind: Service
metadata:
  name: app-name
  namespace: default
spec:
  type: NodePort
  selector:
    app: app-name
  ports:
    - port: 9600
      targetPort: 9600
      nodePort: 30001

After applying the deployment file, I noticed that the pod is running on a different IP, specifically 10.244.0.18.

I checked the pod's logs, and here is what I found:

warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when the container is destroyed. For more information, visit https://aka.ms/aspnet/dataprotectionwarning
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {0078a8d7-d992-4dfd-bd00-f5b1a8595f49} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://[::]:8080
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app

However, when I check the service information on my server, I see this:

NAME                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
app-name                  NodePort    10.103.221.235   <none>        9600:30001/TCP   3h5m

And when I run the command kubectl describe svc app-name, this is the output:

Name:                     app-name 
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=app-name 
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.103.221.235
IPs:                      10.103.221.235
Port:                     <unset>  9600/TCP
TargetPort:               9600/TCP
NodePort:                 <unset>  30001/TCP
Endpoints:                10.244.0.18:9600
Session Affinity:         None
External Traffic Policy:  Cluster
Internal Traffic Policy:  Cluster
Events:                   <none>

Lastly, when I run the command minikube service api-intranet-gateway --url, it returns http://192.168.49.2:30001

According to the "Deploy to Kubernetes" guide, I was instructed to access my app at http://localhost:30001. However, I am unable to access it either from the localhost or via the service URL http://192.168.49.2:30001.

Could you please guide me on how to resolve this issue? Also, could you show me how to set up port forwarding so that it listens on port 9600 on my localhost (10.0.0.92)? I would really appreciate your help.


Solution

  • The instructions on https://docs.docker.com/ apply principally to the Kubernetes embedded in Docker's proprietary Desktop offering. If you're using other developer Kubernetes setups (Minikube, Kind, k3d) then the URLs you'll need to access things like NodePort services will be different.

    In general in Kubernetes, a NodePort-type Service is accessible via the same TCP port number on every node in the cluster. There might be dozens or hundreds of nodes, and they aren't specifically listed in the kubectl describe output.

    To access the service you need

    1. Any node's IP address; and
    2. The specific NodePort port.

    For Minikube, the official way to get an accessible URL is with

    minikube service api-intranet-gateway --url
    

    You can see that URL is made up of the minikube ip address – the address of the Node, as reachable from the host – and the kubectl describe service assigned NodePort port number. This path is also mentioned in the documentation.

    Minikube usually runs in a container or a VM. Because of this, a Minikube service will almost never be accessible as localhost.