<p>I see that kubernetes can use <code>ClusterIP</code> and <code>NodePort</code> and <code>LoadBalancing</code>. For loadbalancing it requires cloud.
If I <strong>do not</strong> have cloud provider <strong>how can I loadbalance traffic between nodes?!</strong>
 I know that HAProxy can loadbalance
but I think this cloud loadbalancer is different from simple HAProxy </p>

<p>and I want to know what is different between HAProxy and IngressController such as HAProxy and Nginx</p>

<p>I want a loadbalancer to loadbalance traffic between my worker nodes.
A service loadbalance traffic between pods.I think ingress controller is layer 7 loadbalancer.
I want loadbalancing between my nodes</p>

<blockquote>
<p>I see that kubernetes can use ClusterIP and NodePort and LoadBalancing. For loadbalancing it requires cloud. If I do not have cloud provider how can I loadbalance traffic between nodes?!</p>
</blockquote>
<p>The easiest way, as you probably know, would be to set the <code>Service</code> to type <a href="https://kubernetes.io/docs/concepts/services-networking/service/#nodeport" rel="noreferrer"><code>NodePort</code></a>, this signals to <a href="https://kubernetes.io/docs/concepts/overview/components/#kube-proxy" rel="noreferrer"><code>kube-proxy</code></a> to listen to a random port in the default range of <code>30000-32767</code> on <strong>every</strong> node. Under the hood this random port will be mapped (port-forwarded) to the <code>Service</code> port.</p>
<p>You can now send traffic, let's say to the random port of <code>30001</code>, to <strong>any</strong> of the nodes and you'll be load balanced internally between the Pods. If you now spin up a e.g. VM in the same network as the nodes or in a network that could reach the nodes and setup load balancing across <code>node-{a,b,c}:30001</code>.</p>
<p>You could, <strong>although not recommeneded</strong> because of many good reasons, basically just send traffic to one of the nodes (<code>node-a:30001</code>) in a multi node cluster and the traffic would still be load balanced internally. This is possible due to the fact that all instances of <code>kube-proxy</code> knows where all the Pods (or <code>Endpoints</code> in the context of a <code>Service</code>) are located at any given time.</p>
<p>Note that the <code>kube-proxy</code> and <code>iptables</code> (may vary!) is the components that implements the <code>Service</code> object in all cases  besides when the type is <code>LoadBalancer</code>. <code>LoadBalancer</code> requests will be dispatched to either the built-in or external cloud controller manager.</p>
<p>The <code>Ingress</code> object exists to add L7 logic in-front of one or more <code>Service</code>'s, but as you've seen the <code>Ingress</code> is worthless if there's no Ingress Controller implementing it. HAProxy and Nginx Ingress controllers would more or less do the same thing for you but not solving your problem short-term. Yes, you'll have load balancing but not in the way you might think.</p>
<p>If you do not have any form of (private/public) cloud with k8s integration backing your k8s cluster up the Nginx and HAProxy Ingress controllers would only be another <code>Service</code> running in your cluster. You would of course be able to do smart things like proxying, URL routing, hostname matching etc.</p>
<p>One of the questions to answer if you're in a non-cloud provider environment (e.g. bare metal only) is: How do i get an IP-address in the <code>EXTERNAL-IP</code> field of a <code>Service</code> of type <code>LoadBalancer</code>? <em>Note that i'm assuming the output of the <code>kubectl get service</code> command.</em> One good answer is, as already stated in the comments here: <a href="https://metallb.universe.tf/#why" rel="noreferrer">MetalLB</a>.</p>
<p>MetalLB will give you automation in regards to configuring the external IP(s) of your <code>Service</code> of type <code>LoadBalancer</code>. But you could also configure the <a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#service-v1-core" rel="noreferrer"><code>externalIPs</code></a> field of the <code>Service</code> object manually and set it to an IP address that would make sense in your environment. Thanks @danielrubambura for pointing this out!</p>
<p>Also see <a href="https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#bare-metal-considerations" rel="noreferrer">this</a> page over at the official Nginx controller documentation that could shed some light on how and why to use MetalLB in some circumstances.</p>
<p>I'm leaving the comparison between Nginx and HAProxy controllers since i don't think that is important in this case. In the end they'll give you Nginx or HAProxy Pods configured as you want through the <code>Ingress</code> object, with e.g. routing to different <code>Service</code>'s based on the <code>Host</code> header in the incoming requests.</p>
<p>Hopefully this clears things up a bit!</p>
