NodePort type service not accessible outside cluster

12/8/2021

I am trying to setup a local cluster using minikube in a Windows machine. Following some tutorials in kubernetes.io, I got the following manifest for the cluster:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-nginx-deployment
  labels:
   app: external-nginx
spec: 
  selector: 
    matchLabels: 
      app: external-nginx
  replicas: 2 
  template: 
    metadata: 
      labels:
        app: external-nginx
    spec: 
      containers: 
      - name: external-nginx
        image: nginx 
        ports: 
        - containerPort: 80 
---
apiVersion: v1
kind: Service 
metadata: 
  name: expose-nginx 
  labels: 
   service: expose-nginx
spec: 
  type: NodePort 
  selector: 
    app: external-nginx 
  ports: 
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 32000

If I got things right, this should create a pod with a nginx instance and expose it to the host machine at port 32000. However, when I run curl http://$(minikube ip):32000, I get a connection refused error.

I ran bash inside the service expose-nginx via kubectl exec svc/expose-nginx -it bash and from there I was able to access the external-nginx pods normally, which lead me to believe it is not a problem within the cluster.

I also tried to change the type of the service to LoadBalancer and enable the minikube tunnel, but got the same result.

Is there something I am missing?

-- Luís Gabriel de Andrade
docker-for-windows
kubernetes
minikube

1 Answer

12/16/2021

Almost always by default minikube uses docker driver for the minikube VM creation. In the host system it looks like a big docker container for the VM in which other kubernetes components are run as containers as well. Based on tests NodePort for services often doesn't work as it's supposed to like accessing the service exposed via NodePort should work on minikube_IP:NodePort address.

Solutions are:

  • for local testing use kubectl port-forward to expose service to the local machine (which OP did)

  • use minikube service command which will expose the service to the host machine. Works in a very similar way as kubectl port-forward.

  • instead of docker driver use proper virtual machine which will get its own IP address (VirtualBox or hyperv drivers - depends on the system). Reference.

  • (Not related to minikube) Use built-in feature kubernetes in Docker Desktop for Windows. I've already tested it and service type should be LoadBalancer - it will be exposed to the host machine on localhost.

-- moonkotte
Source: StackOverflow