<p>I try to expose my server IP by using Ingress.</p>
<p>The server is an Express.js app. It listens at http://localhost:5000 locally when without docker.</p>
<p>Here are my Kubernetes config files:</p>
<p><strong>server-deployment.yaml</strong></p>
<pre><code>apiVersion: v1
apiVersion: apps/v1
kind: Deployment
metadata:
  name: server-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: server
  template:
    metadata:
      labels:
        component: server
    spec:
      containers:
        - name: server
          image: hongbomiao/hongbomiao-server:latest
          ports:
            - containerPort: 5000
          env:
            - name: NODE_ENV
              value: development
</code></pre>
<p><strong>server-cluster-ip-service.yaml</strong></p>
<pre><code>kind: Service
metadata:
  name: server-cluster-ip-service
spec:
  type: ClusterIP
  selector:
    component: server
  ports:
    - port: 5000
      targetPort: 5000
</code></pre>
<p><strong>ingress-service.yaml</strong></p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: server-cluster-ip-service
                port:
                  number: 5000
</code></pre>
<p>I got my minikube IP by</p>
<pre><code>➜ minikube ip
192.168.64.12
</code></pre>
<p>When I open 192.168.64.12 in my browser, I got <strong>502 Bad Gateway</strong>.</p>
<p>I got some debug idea after reading <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/exposing-apps#kubectl-apply" rel="nofollow noreferrer">https://cloud.google.com/kubernetes-engine/docs/how-to/exposing-apps#kubectl-apply</a>. Here is what I have tried:</p>
<pre><code>➜ kubectl get service
NAME                        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
kubernetes                  ClusterIP   10.96.0.1      &lt;none&gt;        443/TCP    5h34m
server-cluster-ip-service   ClusterIP   10.102.5.161   &lt;none&gt;        5000/TCP   4h39m

➜ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
server-deployment-bc6777445-pj59f   1/1     Running   0          4h39m

➜ kubectl exec -it server-deployment-bc6777445-pj59f -- sh
/app # apk add --no-cache curl
...
/app # curl 10.102.5.161:5000
curl: (28) Failed to connect to 10.102.5.161 port 5000: Operation timed out
</code></pre>
<p>It seems my deployment pod has issue connecting ClusterIP service now. Any help will be nice!</p>

<p>It turns out the issue is caused by my VPN.</p>
<p>I didn't change anything for the Kubernetes config in my question.</p>
<p>Also, letting the Express.js server explicitly listen at <code>0.0.0.0</code> is not necessary neither.</p>
<p>(Note @David Maze's comment under the question about <code>0.0.0.0</code> is still valuable)</p>
<pre><code>const app = express()
  .use(bodyParser.json())
  .use(express.static(path.join(__dirname, '../dist')))

app.listen(5000); // This just works. No need explicitly change to app.listen(5000, '0.0.0.0');
</code></pre>
<p>At the time of writing, I was in China. To get rid of the VPN while still using Kubenetes / minikube, I found a way and posted it at GitHub <a href="https://github.com/kubernetes/minikube/issues/5020#issuecomment-739334195" rel="nofollow noreferrer">here</a>.</p>
<p>After turning off the VPN with this workaround solution, everything just works.</p>
<p>Copy my solution using minikube in China here:</p>
<hr />
<h3>Step 1 - Download the Aliyun version minikube</h3>
<pre class="lang-sh prettyprint-override"><code>curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.14.2/minikube-darwin-amd64 &amp;&amp; chmod +x minikube &amp;&amp; sudo mv minikube /usr/local/bin/
</code></pre>
<p><strong>Note</strong>: You can find if there is a new version to replace <code>v1.14.2</code> in the command above at <a href="https://github.com/AliyunContainerService/minikube/wiki#%E5%AE%89%E8%A3%85minikube" rel="nofollow noreferrer">https://github.com/AliyunContainerService/minikube/wiki#%E5%AE%89%E8%A3%85minikube</a></p>
<h3>Step 2 - Start the minikube</h3>
<pre class="lang-sh prettyprint-override"><code>minikube start --image-mirror-country cn \
 --driver=hyperkit \
 --iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.15.0.iso \
 --registry-mirror=https://xxxxxxxx.mirror.aliyuncs.com
</code></pre>
<p><strong>Note 1</strong>: You can find latest minikube version at <a href="https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md" rel="nofollow noreferrer">https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md</a>, then replace <code>v1.15.0</code> in the command above to newer version.</p>
<p>However, Aliyun's minikube version is a little behind. To verify if a new version exists, you can replace the version in the URL of  <a href="https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.15.0.iso" rel="nofollow noreferrer">https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.15.0.iso</a> to different new versions, such as <code>v1.15.1</code>, and then open it in the browser.</p>
<p><strong>Note 2</strong>: For the <code>xxxxxxxx</code> in the command above, you can find yours at
<a href="https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors" rel="nofollow noreferrer">https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors</a>
(Need register an Aliyun account first)</p>
<p><strong>Note 3</strong>: You can pass more parameters to this Aliyun version <code>minikube start</code>, check at <a href="https://github.com/AliyunContainerService/minikube/wiki#%E5%90%AF%E5%8A%A8" rel="nofollow noreferrer">https://github.com/AliyunContainerService/minikube/wiki#%E5%90%AF%E5%8A%A8</a></p>
<p>In my case, I am using the <code>driver</code> hyperkit on macOS, and Aliyun's <code>iso-url</code>, <code>registry-mirror</code> to speed up.</p>
