<p>I'm trying kubernetes and making some progress, but I'm running into an issue with ingress when trying to make my hello world app publicly available.</p>
<p><strong>SUCCESS WITH DEPLOYMENT AND SERVICE</strong></p>
<p>I created a simple <code>hello world</code> type of nodejs app and pushed the image to my docker hub <code>johnlai2004/swarm2</code>.  I successfully created a deployment and service with this yaml file:</p>
<p><code>nodejs.yaml</code></p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs-hello
  labels:
    app: nodejs-hello
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nodejs-hello
  template:
    metadata:
      labels:
        app: nodejs-hello
    spec:
      containers:
      - name: nodejs-hello
        image: johnlai2004/swarm2
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: nodejs-hello-service
spec:
  selector:
    app: nodejs-hello
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 3000
      targetPort: 3000
      nodePort: 30000
</code></pre>
<p>I uploaded these files to a VPS with a new installation of ubuntu 20.04, minikube, kubectl and docker.</p>
<p>I ran the following commands and got the results I wanted:</p>
<pre><code>minikube start --driver=docker
kubectl apply -f nodejs.yaml
minikube service nodejs-hello-service
|-----------|----------------------|-------------|---------------------------|
| NAMESPACE |         NAME         | TARGET PORT |            URL            |
|-----------|----------------------|-------------|---------------------------|
| default   | nodejs-hello-service |        3000 | http://192.168.49.2:30000 |
|-----------|----------------------|-------------|---------------------------|

</code></pre>
<p>When I do a <code>wget http://192.168.49.2:30000</code>, I get an <code>index.html</code> file that says <code>hello from nodejs-hello-556dc868-6lrdz at 12/19/2021, 10:29:56 PM</code>.  This is perfect.</p>
<p><strong>FAILURE WITH INGRESS</strong></p>
<p>Next, I want to use ingress so that I can see the page at <code>http://website.example.com</code>  (replace <code>website.example.com</code> with the actual domain that points to my server). I put this file on my server:</p>
<p><code>nodejs-ingress.yaml</code></p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nodejs-ingress
  namespace: default
  annotations:
    kubernetes.io/ingress.class: &quot;nginx&quot;
spec:
  rules:
    - host: website.example.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: nodejs-hello-service
              port:
                number: 3000
</code></pre>
<p>And I ran the commands</p>
<pre><code>minikube addons enable ingress
kubectl apply -f nodejs-ingress.yaml
kubectl get ingress
NAME             CLASS    HOSTS                   ADDRESS     PORTS   AGE
nodejs-ingress   &lt;none&gt;   website.example.com     localhost   80      15m

</code></pre>
<p>But when I visit <code>http://website.example.com</code> with my browser, the browser says it can't connect.  Using <code>wget http://website.example.com</code> gave the same connection issue.</p>
<p>Can someone point out what I may have done wrong?</p>
<hr />
<p><strong>UPDATE</strong></p>
<p>I ran these commands because I think it shows I didn't install ingress-controller in the right name space?</p>
<pre><code>kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create--1-tqsrp     0/1     Completed   0          4h25m
ingress-nginx-admission-patch--1-sth26      0/1     Completed   0          4h25m
ingress-nginx-controller-5f66978484-tmx72   1/1     Running     0          4h25m

kubectl get pod -n default
NAME                          READY   STATUS    RESTARTS   AGE
nodejs-hello-556dc868-6lrdz   1/1     Running   0          40m
</code></pre>
<p>So does this mean my nodejs app is in a name space that doesn't have access to the ingress controller?</p>
<hr />
<p>UPDATE 2</p>
<p>I also tried following <a href="https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/" rel="nofollow noreferrer">this guide</a> step by step.
One difference I noticed was when I ran the command <code>kubectl get ingress</code>, <code>ADDRESS</code> says <code>localhost</code>.   But in the guide, it says it is supposed to be <code>172.17.0.15</code></p>
<p><a href="https://i.stack.imgur.com/IsjYW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/IsjYW.png" alt="enter image description here" /></a></p>
<p>Does this difference matter?  I'm hosting things in a cloud vps called linode.com.   Does that change the way I do things?</p>

John
<p>The behaviour you have is expected. Let me explain why. Going point through point, and at the end I will present my tips.</p>
<p>First I think it's worth to present minikube architecture. I'm assuming you have installed minikube using default driver <code>docker</code> as you have address <code>192.168.49.2</code> which is standard for <a href="https://minikube.sigs.k8s.io/docs/drivers/docker/" rel="nofollow noreferrer"><code>docker</code> driver</a>.</p>
<p>The layers are:</p>
<ul>
<li>your VM with Ubuntu 20.04</li>
<li>Kubernetes cluster setup by minikube which is docker container with address <code>192.168.49.2</code> on the VM</li>
</ul>
<p>So... you can not just run <code>curl</code> on the VM using a <code>localhost</code> address to connect to the service. <a href="https://en.wikipedia.org/wiki/Localhost" rel="nofollow noreferrer">The <code>localhost</code> is referring to the device that you are making curl request (so your VM)</a>, not the docker container. That's why you need to use the <code>192.168.49.2</code> address.</p>
<p>You can type <code>docker ps -a</code>, and you will see the container which is an actual Kubernetes cluster. You can exec into it using <code>docker exec</code> command and then run <code>curl</code> command with the localhost address:</p>
<pre><code>user@example-ubuntu-minikube-template-1:~$ curl -H &quot;Host: hello-world.info&quot; localhost
curl: (7) Failed to connect to localhost port 80: Connection refused
user@example-ubuntu-minikube-template-1:~$ docker ps -a
CONTAINER ID   IMAGE                                 COMMAND                  CREATED      STATUS      PORTS                                                                                                                                  NAMES
1a4ba3895990   gcr.io/k8s-minikube/kicbase:v0.0.28   &quot;/usr/local/bin/entr…&quot;   4 days ago   Up 4 days   127.0.0.1:49157-&gt;22/tcp, 127.0.0.1:49156-&gt;2376/tcp, 127.0.0.1:49155-&gt;5000/tcp, 127.0.0.1:49154-&gt;8443/tcp, 127.0.0.1:49153-&gt;32443/tcp   minikube
user@example-ubuntu-minikube-template-1:~$ docker exec -it 1a sh
# curl -H &quot;Host: hello-world.info&quot; localhost
Hello, world!
Version: 1.0.0
Hostname: web-79d88c97d6-nl4c7
</code></pre>
<p>Keep in mind that you can access this container only from the VM that is hosting this container. Without any further configuration it's you can't just access it from the other VMs. It is possible, but not recommended.</p>
<p>Good explanation in the <a href="https://minikube.sigs.k8s.io/docs/faq/" rel="nofollow noreferrer">minikube FAQ</a>:</p>
<blockquote>
<p>How can I access a minikube cluster from a remote network?<a href="https://minikube.sigs.k8s.io/docs/faq/#how-can-i-access-a-minikube-cluster-from-a-remote-network" rel="nofollow noreferrer"></a></p>
</blockquote>
<blockquote>
<p>minikube’s primary goal is to quickly set up local Kubernetes clusters, and therefore we strongly discourage using minikube in production or for listening to remote traffic. By design, minikube is meant to only listen on the local network.</p>
</blockquote>
<blockquote>
<p>However, it is possible to configure minikube to listen on a remote network. This will open your network to the outside world and is not recommended. If you are not fully aware of the security implications, please avoid using this.</p>
</blockquote>
<blockquote>
<p>For the docker and podman driver, use  <code>--listen-address</code>  flag:</p>
<pre><code>minikube start --listen-address=0.0.0.0
</code></pre>
</blockquote>
<p>So I'd avoid it. I will present a better possible solution at the end of the answer.</p>
<p>You asked:</p>
<blockquote>
<p>But when I visit  <code>http://website.example.com</code>  with my browser, the browser says it can't connect. Using  <code>wget http://website.example.com</code>  gave the same connection issue.</p>
</blockquote>
<blockquote>
<p>Can someone point out what I may have done wrong?</p>
</blockquote>
<p>Your computer does not know what it is <code>website.example.com</code>. It's not aware that this name is used by your Ingress. If your computer does not find this name in <a href="https://en.wikipedia.org/wiki/Hosts_(file)" rel="nofollow noreferrer">hosts file</a> it will start looking for this over the Internet.</p>
<p>So you have some possible solutions:</p>
<ul>
<li>use <code>curl -H 'HOST: website.example.com' http://192.168.49.2:80</code> - it will work only on the VM where is minikube</li>
<li><a href="https://linuxize.com/post/how-to-edit-your-hosts-file/" rel="nofollow noreferrer">add host to the hosts file</a> - something like <code>192.168.49.2 website.example.com</code> - it will work only on the VM where is minikube</li>
<li>Setup a bare-metal cluster (more details in the sum up section) and point the domain address to the VM address.  In GCP and AWS you can do it using  <a href="https://cloud.google.com/dns" rel="nofollow noreferrer">Google Cloud DNS</a> or <a href="https://aws.amazon.com/route53/" rel="nofollow noreferrer">Amazon Route 53</a>. On linode cloud maybe <a href="https://www.linode.com/docs/guides/dns-manager/" rel="nofollow noreferrer">this one - DNS Manager</a> ?</li>
</ul>
<p><strong>EDIT:</strong>
You wrote that you have a domain pointed to the server, so please just check the sum up section of my answer.</p>
<p>Also you asked:</p>
<blockquote>
<p>I ran these commands because I think it shows I didn't install ingress-controller in the right name space?</p>
</blockquote>
<blockquote>
<p>So does this mean my nodejs app is in a name space that doesn't have access to the ingress controller?</p>
</blockquote>
<p><a href="https://kubernetes.github.io/ingress-nginx/deploy/#quick-start" rel="nofollow noreferrer">It's absolutely normal</a>:</p>
<blockquote>
<p>It will install the controller in the <code>ingress-nginx</code> namespace, creating that namespace if it doesn't already exist.</p>
</blockquote>
<p>Also:</p>
<blockquote>
<p>I also tried following this guide step by step:  <a href="https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/" rel="nofollow noreferrer">https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/</a></p>
</blockquote>
<blockquote>
<p>One difference I noticed was when I ran the command  <code>kubectl get ingress</code>,  <code>ADDRESS</code>  says  <code>localhost</code>. But in the guide, it says it is supposed to be  <code>172.17.0.15</code></p>
</blockquote>
<blockquote>
<p>Does this difference matter? I'm hosting things in a cloud vps called linode.com. Does that change the way I do things?</p>
</blockquote>
<p>It's also normal and expected when using minikube with a docker driver.</p>
<p>To sum up / other tips:</p>
<ul>
<li>Minkube is fine for local testing; you can easily access apps and services using from the host - check <a href="https://minikube.sigs.k8s.io/docs/handbook/accessing/" rel="nofollow noreferrer">Accessing apps</a>.</li>
<li>However, for exposing it outside the network you should consider using solutions like <a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/" rel="nofollow noreferrer">kubeadm</a> or <a href="https://github.com/kubernetes-sigs/kubespray" rel="nofollow noreferrer">kubespray</a> for cluster setup + <a href="https://metallb.universe.tf/" rel="nofollow noreferrer">MetalLB</a> for LoadBalancer solution. Check &quot;<a href="https://kubernetes.github.io/ingress-nginx/deploy/baremetal/" rel="nofollow noreferrer">Bare-metal considerations</a>&quot; and <a href="https://stackoverflow.com/questions/61583350/exposing-a-kubernetes-service-on-a-bare-metal-cluster-over-the-external-network">Exposing a Kubernetes service on a bare-metal cluster over the external network architecture</a></li>
<li>If you are planning to use your service with ingress, don't use LoadBalancer type. It's ok to use ClusterIP.</li>
</ul>
