<p>What is a Load Balancer?  </p>

<blockquote>
  <p>Load balancing improves the distribution of workloads across multiple
  computing resources, such as computers, a computer cluster, network
  links, central processing units, or disk drives</p>
</blockquote>

<h3>The NodePort</h3>

<p>NodePort is not load balancer. (I know that <code>kube-proxy</code> load balance the traffic among the pod once the traffic is inside the cluster) I mean, the end user hits <code>http://NODEIP:30111</code> (For example) URL to access the application. Even though the traffic is load balanced among the POD, users still hits a single node i.e. the "Node" which is K8s's minion but a real Load Balancer, right?</p>

<h3>The Ingress Service</h3>

<p>Here also same, imagine the ingress-controller is deployed and ingress-service too. The sub-domain that we specify in ingress-service should points to "a" node in K8s cluster, then ingress-controller load balance the traffic among the pods. Here also end users hitting single node which is K8s's minion but a real Load Balancer, right?</p>

<h3>Load Balancer From Cloud Provider(for example AWS ELB)</h3>

<p>I'm having a doubt, how cloud provider's LB does the load balancing? Are those really distribute the traffic to appropriate Node which PODS are deployed or just forwarding the traffic to master node or minion?</p>

<p>If above point is true. Where is the true load balancing the traffic among the pods/appropriate nodes.</p>

<p>Can I implement true load balancing in K8s? I asked a related <a href="https://stackoverflow.com/questions/51531312/how-to-access-k8ss-flannel-network-from-outside">question here</a></p>

<blockquote>
  <p>NodePort is not load balancer. </p>
</blockquote>

<p>You're right about this in one way, yes it's not designed to be a load balancer.</p>

<blockquote>
  <p>users still hits a single node i.e. the "Node" which is K8s's minion but a real Load Balancer, right?</p>
</blockquote>

<p>With NodePort, you <em>have</em> to hit a single node at any one time, but you have to remember that <code>kube-proxy</code> is running on ALL nodes. So you can hit the NodePort on any node in the cluster (even a node the workload isn't running on) and you'll still hit the endpoint you want to hit. This becomes important later.</p>

<blockquote>
  <p>The sub-domain that we specify in ingress-service should points to "a" node in K8s cluster</p>
</blockquote>

<p>No, this isn't how it works.</p>

<p>Your ingress controller needs to be exposed externally still. If you're using a cloud provider, a commonly used pattern is to expose your ingress controller with Service of <code>Type=LoadBalancer</code>. The LoadBalancing still happens with Services, but Ingress allows you to use that Service in a more user friendly way. Don't confuse ingress with loadbalancing.</p>

<blockquote>
  <p>I'm having a doubt how cloud provider LB does the load balancing? Are those really distribute the traffic to appropriate Node which PODS are deployed or just forwarding the traffic to master node or minion?</p>
</blockquote>

<p>If you look at a provisioned service in Kubernetes, you'll see why it makes sense.</p>

<p>Here's a Service of Type LoadBalancer:</p>

<pre><code>kubectl get svc nginx-ingress-controller -n kube-system                                                                    
NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP        PORT(S)                      AGE
nginx-ingress-controller   LoadBalancer   &lt;redacted&gt;   internal-a4c8...   80:32394/TCP,443:31281/TCP   147d
</code></pre>

<p>You can see I've deployed an ingress controller with type LoadBalancer. This has created an AWS ELB, but also notice, like <code>NodePort</code> it's mapped port 80 on the ingress controller pod to port <code>32394</code>.</p>

<p>So, let's look at the actual LoadBalancer in AWS:</p>

<pre><code>aws elb describe-load-balancers --load-balancer-names a4c80f4eb1d7c11e886d80652b702125

{
    "LoadBalancerDescriptions": [
        {
            "LoadBalancerName": "a4c80f4eb1d7c11e886d80652b702125",
            "DNSName": "internal-a4c8&lt;redacted&gt;",
            "CanonicalHostedZoneNameID": "&lt;redacted&gt;",
            "ListenerDescriptions": [
                {
                    "Listener": {
                        "Protocol": "TCP",
                        "LoadBalancerPort": 443,
                        "InstanceProtocol": "TCP",
                        "InstancePort": 31281
                    },
                    "PolicyNames": []
                },
                {
                    "Listener": {
                        "Protocol": "HTTP",
                        "LoadBalancerPort": 80,
                        "InstanceProtocol": "HTTP",
                        "InstancePort": 32394
                    },
                    "PolicyNames": []
                }
            ],
            "Policies": {
                "AppCookieStickinessPolicies": [],
                "LBCookieStickinessPolicies": [],
                "OtherPolicies": []
            },
            "BackendServerDescriptions": [],
            "AvailabilityZones": [
                "us-west-2a",
                "us-west-2b",
                "us-west-2c"
            ],
            "Subnets": [
                "&lt;redacted&gt;",
                "&lt;redacted&gt;",
                "&lt;redacted&gt;"
            ],
            "VPCId": "&lt;redacted&gt;",
            "Instances": [
                {
                    "InstanceId": "&lt;redacted&gt;"
                },
                {
                    "InstanceId": "&lt;redacted&gt;"
                },
                {
                    "InstanceId": "&lt;redacted&gt;"
                },
                {
                    "InstanceId": "&lt;redacted&gt;"
                },
                {
                    "InstanceId": "&lt;redacted&gt;"
                },
                {
                    "InstanceId": "&lt;redacted&gt;"
                },
                {
                    "InstanceId": "&lt;redacted&gt;"
                },
                {
                    "InstanceId": "&lt;redacted&gt;"
                }
            ],
            "HealthCheck": {
                "Target": "TCP:32394",
                "Interval": 10,
                "Timeout": 5,
                "UnhealthyThreshold": 6,
                "HealthyThreshold": 2
            },
            "SourceSecurityGroup": {
                "OwnerAlias": "337287630927",
                "GroupName": "k8s-elb-a4c80f4eb1d7c11e886d80652b702125"
            },
            "SecurityGroups": [
                "sg-8e0749f1"
            ],
            "CreatedTime": "2018-03-01T18:13:53.990Z",
            "Scheme": "internal"
        }
    ]
}
</code></pre>

<p>The most important things to note here are:</p>

<p>The LoadBalancer is mapping port 80 in ELB to the NodePort:</p>

<pre><code>{
                "Listener": {
                    "Protocol": "HTTP",
                    "LoadBalancerPort": 80,
                    "InstanceProtocol": "HTTP",
                    "InstancePort": 32394
                },
                "PolicyNames": []
 }
</code></pre>

<p>You'll also see that there are multiple target <code>Instances</code>, not one:</p>

<pre><code>aws elb describe-load-balancers --load-balancer-names a4c80f4eb1d7c11e886d80652b702125 | jq '.LoadBalancerDescriptions[].Instances | length'
8
</code></pre>

<p>And finally, if you look at the number of nodes in my cluster, you'll see it's actually <em>all</em> the nodes that have been added to the LoadBalancer:</p>

<pre><code>kubectl get nodes -l "node-role.kubernetes.io/node=" --no-headers=true | wc -l                                             
8
</code></pre>

<p>So, in summary - Kubernetes <em>does</em> implement true LoadBalancing with services (whether that be NodePort or LoadBalancer types) and the ingress just makes that service more accessible to the outside world</p>
