<p>I'm working on a project in which I need to deploy a simple NodeJs application using Kubernetes, Helm and Azure Kubernetes Service.</p>

<p>Here's What I have tried:</p>

<p><strong>My <code>Dockerfile</code>:</strong></p>

<pre><code>FROM node:8

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 32000
CMD [ "npm", "start" ]
</code></pre>

<p><strong>Here's my <code>mychart/values.yaml</code>:</strong></p>

<pre><code>replicaCount: 1

image:
  # registry: docker.io
  repository: registry-1.docker.io/arycloud/docker-web-app
  tag: 0.3
  pullPolicy: IfNotPresent

nameOverride: ""
fullnameOverride: ""

service:
  name: http
  type: LoadBalancer
  port: 32000
  internalPort: 32000

ingress:
  enabled: false
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  paths: []
  hosts:
    - name: mychart.local
      path: /
  tls: []

resources: {}

nodeSelector: {}

tolerations: []

affinity: {}
</code></pre>

<p><strong>And my node <code>server.js</code>:</strong></p>

<pre><code>'use strict';

const express = require('express');

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

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

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

<blockquote>
  <p><strong>Update:</strong> Template files:</p>
</blockquote>

<p><strong>From <code>templates/deployment.yaml</code>:</strong></p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ include "mychart.name" . }}
    helm.sh/chart: {{ include "mychart.chart" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "mychart.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ include "mychart.name" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 32000
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: 32000
          readinessProbe:
            httpGet:
              path: /
              port: 32000
            initialDelaySeconds: 3
            periodSeconds: 3
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
    {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
    {{- end }}
    {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
    {{- end }}
</code></pre>

<p><strong>From <code>templates/service.yaml</code>:</strong></p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  name: {{ include "mychart.fullname" . }}
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
  labels:
    app.kubernetes.io/name: {{ include "mychart.name" . }}
    helm.sh/chart: {{ include "mychart.chart" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: {{ include "mychart.name" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
</code></pre>

<blockquote>
  <p><strong>Update: a screenshot of external IP:</strong>
  <a href="https://i.stack.imgur.com/j1hrz.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/j1hrz.jpg" alt="enter image description here"></a>
  Here's the output of `kubectl get svc node-release-mychart -oyaml:</p>
</blockquote>

<pre><code>apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
  creationTimestamp: "2019-01-26T11:28:27Z"
  labels:
    app.kubernetes.io/instance: node-release
    app.kubernetes.io/managed-by: Tiller
    app.kubernetes.io/name: mychart
    helm.sh/chart: mychart-0.1.0
  name: node-release-mychart
  namespace: default
  resourceVersion: "127367"
  selfLink: /api/v1/namespaces/default/services/node-release-mychart
  uid: 8031f3b6-215d-11e9-bb89-462a1bcec690
spec:
  clusterIP: 10.0.223.27
  externalTrafficPolicy: Cluster
  ports:
  - name: http
    nodePort: 32402
    port: 32000
    protocol: TCP
    targetPort: 32000
  selector:
    app.kubernetes.io/instance: node-release
    app.kubernetes.io/name: mychart
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 10.240.0.7
</code></pre>

<p>I have created a cluster on AKS then run the <code>get-credentials</code> command from my mac os terminal and it works fine, then I have tagged and pushed my docker image to <code>dockerhub</code> and the docker container is also working fine, after that I have created a helm chart and update the <code>values.yaml</code> accordingly and run the <code>helm install</code> command, it install my application to <code>aks</code> and the service provide an <code>external IP</code>, in the kubernetes dashboard the <code>pods</code> are in <code>running</code> state but when I try to access my application via <code>Etxernal_IP:80</code> it doesn't load my application.</p>

Abdul Rehman
<p>Your problem comes from the fact you've added the annotation to use internal load balancer (so not exposed publicly, only available inside vnet). To fix that remove this part from the service definition:</p>

<pre><code>annotations:
  service.beta.kubernetes.io/azure-load-balancer-internal: "true"
</code></pre>
