<ol>
<li>node.js express server bound to port 8080</li>
</ol>

<pre><code>server.listen(8080, () =&gt; {
  logger.log({
    level: 'info',
    message: 'Listening on port ' + port
  })
})
</code></pre>

<ol start="2">
<li>Docker image with node.js code + npm modules with port 8080 exposed</li>
</ol>

<pre><code>FROM node:10-alpine

...

# Expose port
EXPOSE 8080
</code></pre>

<ol start="3">
<li>Kubernetes deployment of Docker image with containerPort 8080 configured</li>
</ol>

<pre><code>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"
</code></pre>

<ol start="4">
<li>Kubernetes service with matching selector to app with targetPort of 8080 and type LoadBalancer</li>
</ol>

<pre><code>apiVersion: v1

kind: Service

metadata:
  name: service

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

  selector:
    app: deployment

  type: LoadBalancer
</code></pre>

<ol start="5">
<li>Verify load balancer has external IP (I scrubbed it)</li>
</ol>

<pre><code>$ 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
</code></pre>

<ol start="6">
<li>curl fails with empty response</li>
</ol>

<pre><code>$ 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)
&gt; GET / HTTP/1.1
&gt; Host: 1x4.2x9.1x8.x2:8080
&gt; User-Agent: curl/7.54.0
&gt; Accept: */*
&gt; 
* Empty reply from server
* Connection #0 to host 1x4.2x9.1x8.x2 left intact
curl: (52) Empty reply from server
</code></pre>

<p>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?</p>

<p>There are some potential sources of errors here.</p>
<p>First potential problem is that your Docker image does not work as expected.  You can try this: Use <code>nginx:latest</code> as your image and try if this works. If this works the Kubernetes parts are working correctly and you can do further investigation on your Docker image.</p>
<p>Your code snippet does not contain any code that outputs some data as far as I can see.</p>
<p>You can experiment with your image by using the <code>docker run</code> command as indicated in the comments above.</p>
<p>If it still does not work with the Nginx image then you have to further investigate the Kubernetes side.</p>
<p>Although a LoadBalancer is a standard Kubernetes service type, its implementation is different for different cloud providers and on-premise installations.</p>
<p>You must consult your Kubernetes or cloud provider's documentation on how to find out if the LoadBalancer is configured correctly.</p>
<p>To see if the service can reach the pods you can use the command <code>kubectl get endpoints</code>.</p>
<p>To do some more debugging you can use the <code>kubectl port-forward</code> command to create a tunnel to either one of the pods or to the service and try the curl command on the established tunnel.</p>
<p>Also you can use the <code>kubectl logs</code> command to see any log output of your pods.</p>
