<p>I'm running kubernetes 1-21-0 on Centos7. I've set up a keycloak service to test my ingress controller and am able to access the keycloak on the host url with the keycloak port like <code>myurl.com:30872</code>. These are my running services:</p>
<pre><code>NAMESPACE       NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
default         keycloak                             NodePort    10.96.11.164    &lt;none&gt;        8080:30872/TCP               21h
default         kubernetes                           ClusterIP   10.96.0.1       &lt;none&gt;        443/TCP                      11d
ingress-nginx   ingress-nginx-controller             NodePort    10.102.201.24   &lt;none&gt;        80:31110/TCP,443:30566/TCP   9m45s
ingress-nginx   ingress-nginx-controller-admission   ClusterIP   10.107.90.207   &lt;none&gt;        80/TCP,443/TCP               9m45s
kube-system     kube-dns                             ClusterIP   10.96.0.10      &lt;none&gt;        53/UDP,53/TCP,9153/TCP       11d
</code></pre>
<p>I've deployed the following <a href="https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/baremetal/deploy.yaml" rel="nofollow noreferrer">nginx ingress controller</a>.</p>
<p>And added an HTTP webhook to the service:</p>
<pre><code># Source: ingress-nginx/templates/controller-service-webhook.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    helm.sh/chart: ingress-nginx-3.23.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.44.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller-admission
  namespace: ingress-nginx
spec:
  type: ClusterIP
  ports:
    - name: http-webhook
      port: 80
      targetPort: webhook
    - name: https-webhook
      port: 443
      targetPort: webhook
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller
</code></pre>
<p>With this ingress:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: keycloak
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
        - path: /keycloak
          pathType: Prefix
          backend:
            service:
              name: keycloak
              port: 
                number: 8080
</code></pre>
<p>Now when I attempt to connect to the keycloak service through the ingress I go to <code>myurl.com/keycloak</code> but it's unable to connect and trying to curl it from within my control node shows connection refused:</p>
<pre><code># curl -I http://127.0.0.1/keycloak
curl: (7) Failed connect to 127.0.0.1:80; Connection refused
</code></pre>
<p>Can someone see what I'm missing?</p>
<p><strong>Edit:</strong></p>
<p>I realized the ingress controller actually works, but I need to specify its port also to reach it like this:</p>
<pre><code>curl -I http://127.0.0.1:31110/keycloak
</code></pre>
<p>Which I'd like to avoid.</p>

<p>You have to specify <code>31110</code> port because your nginx ingress is set up with <code>NodePort</code> which means kubernetes listens to this port and all traffic that goes here is redirected to <code>nginx-ingress-controller</code> pod.</p>
<p>Depending on your setup and goals, this can be achieved differently.</p>
<p><strong>Option 1</strong> - for testing purposes only and without any changes in setup. Works only on a control plane where <code>nginx-ingress-controller</code> pod is running</p>
<p>it's possible to forward traffic from outside port 80 to <code>nginx-ingress-controller</code> pod directly port 80. You can run this command (in background):</p>
<pre><code>sudo kubectl port-forward ingress-nginx-controller-xxxxxxxx-yyyyy 80:80 -n ingress-nginx &amp;
</code></pre>
<p>Curl test shows that it's working:</p>
<pre><code>curl -I localhost/keycloak
Handling connection for 80
HTTP/1.1 200 OK
Date: Wed, 16 Jun 2021 13:19:23 GMT
</code></pre>
<p>Curl can be run on different instance, in this case command will look this way without specifying any ports:</p>
<pre><code>curl -I public_ip/keycloak
</code></pre>
<p><strong>Option 2</strong> - this one is a bit more difficult, however provides better results.</p>
<p>It's possible to expose pods outside of the cluster. Feature is called <code>hostPort</code> - it allows to expose a single container port on the host IP. To have this work on different worker nodes, <code>ingress-nginx-controller</code> should be deployed as <code>DaemonSet</code>.</p>
<p>Below parts in <code>values.yaml</code> for ingress-nginx helm chart that I corrected:</p>
<p>hostPort -&gt; enabled -&gt; <strong>true</strong></p>
<pre><code>  ## Use host ports 80 and 443
  ## Disabled by default
  ##
  hostPort:
    enabled: true
    ports:
      http: 80
      https: 443
</code></pre>
<p>kind -&gt; <strong>DaemonSet</strong></p>
<pre><code>  ## DaemonSet or Deployment
  ##
  kind: DaemonSet
</code></pre>
<p>Then install ingress-nginx-controller from this chart.
What it does is by default <code>ingress-nginx-controller</code> pods will listen to traffic on 80 and 443 port.
Which confirms with simple test:</p>
<pre><code>curl -I localhost/keycloak
HTTP/1.1 200 OK
Date: Wed, 16 Jun 2021 13:31:25 GMT
</code></pre>
<p><strong>Option 3</strong> - may be considered as well if ingress-nginx is installed with LoadBalancer type.</p>
<p>Use <code>metallb</code> - software loadbalancer specifically designed for bare metal clusters. <a href="https://metallb.universe.tf/installation/#installation-by-manifest" rel="nofollow noreferrer">How to install metallb</a> and <a href="https://metallb.universe.tf/configuration/" rel="nofollow noreferrer">configure</a></p>
<p>Once it's done and ingress-nginx is deployed, ingress-nginx will get External-IP:</p>
<p>kubectl get svc --all-namespaces</p>
<pre><code>NAMESPACE       NAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx   ingress-nginx-controller             LoadBalancer   10.102.135.146   192.168.1.240   80:32400/TCP,443:32206/TCP   43s
</code></pre>
<p>Testing this again with <code>curl</code>:</p>
<pre><code>curl -I 192.168.1.240/keycloak
HTTP/1.1 200 OK
Date: Wed, 16 Jun 2021 13:55:34 GMT
</code></pre>
<p>More information about topics above:</p>
<ul>
<li><a href="https://alesnosek.com/blog/2017/02/14/accessing-kubernetes-pods-from-outside-of-the-cluster/" rel="nofollow noreferrer">hostPorts and hostNetwork</a></li>
<li><a href="https://metallb.universe.tf/" rel="nofollow noreferrer">Metallb project</a></li>
</ul>
