BhagyaKolitha Jayalath
BhagyaKolitha Jayalath

Reputation: 103

Kubernetes NodePort is not accessible outside. Connection refused

I am trying to learn Kubernetes.

I am trying to do this using Minikube and here is what I did:

1.) Write a simple server using Node

2.) Write a Dockerfile for that particular Node server

3.) Create a Kubernetes deployment

4.) Create a service (of type ClusterIP)

5.) Create a service (of type NodePort) to expose the container so I can access from outside (browser, curl)

But when I try to connect to the NodePort with the format of <NodePort>:<port> and `:, it gives an error:

Failed to connect to 192.168.39.192 port 80: Connection refused

These are the files I created as steps mentioned above (1-5).

1.) server.js - Here only I have mentioned server.js, relevent package.json exists and they work as expected when I run the server locally (without deploying it in Docker), I mention this in case readers might ask whether my server works correctly.

'use strict';

const express = require('express');

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
  res.send('Hello world\n');
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

2.) Dockerfile

FROM node:10

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "npm", "start" ]

3.) deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-web-app
spec:
  replicas: 2
  selector:
    matchLabels:
      name: node-web-app
  template:
    metadata:
      labels:
        # you can specify any labels you want here
        name: node-web-app
    spec:
      containers:
      - name: node-web-app
        # image must be the same as you built before (name:tag)
        image: banuka/node-web-app
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        imagePullPolicy: Never
      terminationGracePeriodSeconds: 60

4.) clusterip.yaml

kind: Service
apiVersion: v1
metadata:
  labels:
    # these labels can be anything
    name: node-web-app-clusterip
  name: node-web-app-clusterip
spec:
  selector:
    app: node-web-app
  ports:
    - protocol: TCP
      port: 80
      # target is the port exposed by your containers (in our example 8080)
      targetPort: 8080

5.) NodePort.yaml

kind: Service
apiVersion: v1
metadata:
  labels:
    name: node-server-nodeport
  name: node-server-nodeport
spec:
  # this will make the service a NodePort service
  type: NodePort
  selector:
    app: node-app-web
  ports:
    - protocol: TCP
      # new -> this will be the port used to reach it from outside
      # if not specified, a random port will be used from a specific range (default: 30000-32767)
      nodePort: 32555
      port: 80
      targetPort: 8080

And when I try to curl from outside or use my web browser it gives following error:

curl: (7) Failed to connect to 192.168.39.192 port 32555: Connection refused

PS: pods and containers are also working as expected.

Upvotes: 0

Views: 6379

Answers (4)

texasdave
texasdave

Reputation: 716

Adding ways to check the label and add the label. Labelling pods is what fixed it for me.

kubectl get pods --show-labels -n mynamespace
 
 
 
kubectl label pod nginx-66bccddb68-8tjpk -n mynamespace app=webserver

Upvotes: 0

E Kwong
E Kwong

Reputation: 31

The Service's selector must match the Pod's label.

In your NodePort.yaml selector is app: node-app-web , while in deployment.yaml label is node-web-app.

Upvotes: 1

GFB
GFB

Reputation: 345

I had same problem always when I write wrong selectors to NodePort service spec

Upvotes: 3

Thomas
Thomas

Reputation: 12009

There are several possible reasons for this. First: Are you using your local IP or the IP where the minikube VM is running? To verify use minikube ip. Second: The NodePort service wants to use pods with label app: node-app-web, but your pods only have the label name: node-web-app Just to make sure the port that you assume is used, check with minikube service list that the requested port was allocated. Check your firewall settings as well.

Upvotes: 3

Related Questions