<p>I have a api-service with type 'ClusterIp' which is working fine and is accessible on the node with clusterip. I want to access it externally . It's a baremetal installation with kubeadm . I cannot use Loadbalancer or Nodeport. </p>

<p>If I use nginx-ingress that too I will use as 'ClusterIP' so how to get the service externally accessible in either api service or nginx-ingress case . </p>

<pre><code>NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
api                    ClusterIP   10.97.48.17      &lt;none&gt;        80/TCP           41s
ingress-nginx          ClusterIP   10.107.76.178    &lt;none&gt;        80/TCP           3h49m
</code></pre>

<p>Changes to solve the issue:</p>

<ol>
<li>nginx configuration on node</li>
</ol>

<p>in /etc/nginx/sites-available </p>

<pre><code> upstream backend {
       server node1:8001;
       server node2:8001;
       server node3:8001;
        }
    server_name _;

    location / {
            proxy_pass http://backend;
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            try_files $uri $uri/ =404;
    }
</code></pre>

<ol start="2">
<li>Ran my two services as DaemonSet</li>
</ol>

<p><code>ClusterIP</code> services are accesible only within the cluster.</p>

<p>For bare metal clusters, you can use any of the following approaches to make a service available externally. Suggestions are from most recommended to least recommended order:</p>

<ol>
<li><p>Use <strong><code>metallb</code></strong> to implement <strong>LoadBalancer</strong> service type support - <a href="https://metallb.universe.tf/" rel="nofollow noreferrer">https://metallb.universe.tf/</a>. You will need a pool of IP addresses for metallb to handout. It also supports IP sharing mode where you can use same IP for multiple LoadBalancer services.</p></li>
<li><p>Use <strong>NodePort</strong> service. You can access your service from any node IP:node_port address. NodePort service selects random port in node port range by default. You can choose a custom port in node port range using <code>spec.ports.nodePort</code> field in the service specification.</p>

<p><em>Disadvantage:</em> The node port range by default is 30000-32767. So you cannot bind to any custom port that you want like 8080. Although you can change the node port range with <code>--service-node-port-range</code> flag of kube-api-server, it is not recommended to use it with low port ranges. </p></li>
<li><p>Use <strong>hostPort</strong> to bind a port on the node. </p>

<p><em>Disadvantage:</em> You don't have fixed IP address because you don't know which node your pod gets scheduled to unless you use <code>nodeAffinity</code>. You can make your pod a daemonset if you want it to be accessible from all nodes on the given port. </p></li>
</ol>

<p>If you are dealing with HTTP traffic, another option is installing an <code>IngressController</code> like nginx or Traefik and use <code>Ingress</code> resource. As part of their installation, they use one of the approaches mentioned above to make themselves available externally.</p>
