11
votes
  1. node.js express server bound to port 8080
server.listen(8080, () => {
  logger.log({
    level: 'info',
    message: 'Listening on port ' + port
  })
})
  1. Docker image with node.js code + npm modules with port 8080 exposed
FROM node:10-alpine

...

# Expose port
EXPOSE 8080
  1. Kubernetes deployment of Docker image with containerPort 8080 configured
apiVersion: apps/v1

kind: Deployment

metadata:
  name: deployment

spec:
  selector:
    matchLabels:
      app: deployment

  replicas: 2

  template:
    metadata:
      labels:
        app: deployment

    spec:
      containers:
      - name: job-id-20
        image: redacted/redacted
        command: ["node", "backend/services.js"]

        ports:
        - name: http-port
          containerPort: 8080

      imagePullSecrets:
      - name: docker-hub-credentials

      dnsConfig:
        options:
          - name: ndots
            value: "0"
  1. Kubernetes service with matching selector to app with targetPort of 8080 and type LoadBalancer
apiVersion: v1

kind: Service

metadata:
  name: service

spec:
  ports:
    - protocol: TCP
      targetPort: 8080
      port: 8080

  selector:
    app: deployment

  type: LoadBalancer
  1. Verify load balancer has external IP (I scrubbed it)
$ kubectl --kubeconfig="k8s-1-13-4-do-0-nyc1-1552761372568-kubeconfig.yaml" get service/service
NAME      TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
service   LoadBalancer   10.245.239.60   1x4.2x9.1x8.x2   8080:30626/TCP   113s
  1. curl fails with empty response
$ curl --verbose http://1x4.2x9.1x8.x2:8080/
*   Trying 1x4.2x9.1x8.x2...
* TCP_NODELAY set
* Connected to 1x4.2x9.1x8.x2 (1x4.2x9.1x8.x2) port 8080 (#0)
> GET / HTTP/1.1
> Host: 1x4.2x9.1x8.x2:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
* Empty reply from server
* Connection #0 to host 1x4.2x9.1x8.x2 left intact
curl: (52) Empty reply from server

I'd expect the traffic to route through to the service to one of the pods/replicas in the deployment. What am I doing wrong?

1
I’m assuming the pod is not failing, node.js code is not returning an error? What happens if you change the service to a NodePort and try curling the node ip & port? - dijksterhuis
If you use docker run to run the same image outside of Kubernetes, is it reachable? - David Maze
To debug further, k describe svc service see endpoints are attached. Next step, k exec deployment/deployment-somepodhash sh to check whether http://localhost:8080 is working or not. If none of them are working then it is a network setup issue. Final step, do iptables -t nat -L KUBE-SERVICES to figure out services attached. - Barath
Are u able to curl from inside the POD ? - Dinesh Balasubramanian
did you solve this problem ? actually i am also facing the same problem. - Tabish

1 Answers

-1
votes

Check any error while creating image ,check if pods were successfully deployed after deployment i.e. they should be in running state and check for service too. if these are conditions are correct than I hardly see any error in you steps. Here is a simple example for nodejs application deployment .

index.js

var http = require('http');

var server = http.createServer(function(request, response) {

    response.writeHead(200, {"Content-Type": "text/plain"});
    response.end("Hello World!");

});

var port = 80;
server.listen(port);

console.log("Server running at http://localhost:%d", port);

Docker File:

FROM node:0.10.40
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY ./nodejs-docs-hello-world ./
RUN npm install
CMD ["node", "index.js"]

web-deployement:

apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    name: web
  name: web-controller
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: web
    spec:
      containers:
      - image: imagename
        name: web
        ports:
        - containerPort: 80
          name: http-server

web-service:

apiVersion: v1
kind: Service
metadata:
  name: web
  labels:
    name: web
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: web