<p>I'm unable to wrap my head around the concepts of interconnectivity among <code>DNS</code>, <code>Ingress controller</code>, <code>MetalLb</code> and <code>Kubeproxy</code>.</p>
<p>I know what these resources/tools/services are for and get the concepts of them individually but unable to form a picture of them working in tandem.</p>
<p>For example, in a bare metal setup, a client accesses my site - <code>https://mytestsite.com</code>, still having doubts , how effectively it lands to the right pod and where the above mentioned services/resources/tools comes into picture &amp; at what stage ?
Ex. How DNS talks to my MetalLB, if the client accesses my MetalLB hosting my application and how LB inturn speaks to IngressController and finally where does Kube-proxy comes into play here.</p>
<p>I went thru the K8s official documentation and few others as well but still kind of stumped here. Following article is really good but I'm unable to stitch the pieces together.
<a href="https://www.disasterproject.com/kubernetes-with-external-dns/" rel="nofollow noreferrer">https://www.disasterproject.com/kubernetes-with-external-dns/</a></p>
<p>Kindly redirect me to the correct forum, if it is not the right place, thanks.</p>

<p>The ingress-controller creates a <code>service</code> of type <code>LoadBalancer</code> that serves as the entry point into the cluster. In a public cloud environment, a loadbalancer like ELB on AWS would create the counter part and set the <code>externalIP</code> of that service to it's ip. It is like a service of type <code>NodePort</code> but it also has an <code>ExternalIP</code>, which corresponds to the actual ip of the counterpart, a load balancer like ELB on aws.</p>
<p>In a bare metal environment, no external load balancer will be created, so the external ip would stay in <code>&lt;Pending&gt;</code> state forever. Here for example the service of the istio ingress controller:</p>
<pre class="lang-bash prettyprint-override"><code>$ kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)
istio-ingressgateway   LoadBalancer   192.12.129.119   &lt;Pending&gt;   [...],80:32123/TCP,443:30994/TCP,[...]
</code></pre>
<p>In that state you would need to call <code>http://&lt;node-ip&gt;:32123</code> to reach the <code>http</code> port <code>80</code> of the ingress controller service, which would be then forwarded to your pod (more on that in a bit).</p>
<p>When you're using metallb, it will update the service with an external ip so you can call <code>http://&lt;ip&gt;</code> instead. Metallb will also announce that ip, e.g. via BGP, so other know where to send traffic to, when someone would call the ip.</p>
<p>I havn't used external DNS and only scanned the article but I guess that you can use that to also have a dns record to be created so someone can call your service by it's domain, not only by it's ip. So you can call <code>http://example.com</code> instead.</p>
<p>This is basically why you run metallb and how it interacts with your ingress controller. The ingress controller creates an entry point into the cluster and metallb configures it and attracts traffic.</p>
<p>Until now the call to <code>http://example.com</code> can reach your cluster, but it needs to also reach the actual application, running in a pod inside the cluster. That's <code>kube-proxy</code>'s job.</p>
<p>You read a lot about <code>service</code> of different types and all this kind of stuff, but in the end it all boils down to iptables rules. <code>kube-proxy</code> will create a bunch of those rules, that form a chain.</p>
<p>SSH into any kubernetes worker, run <code>iptables-save | less</code> command and search for the <code>external ip</code> configured on your ingress-controller's service by metallb. You'll find a chain with the destination of you external ip, that basically leads from the external IP over the service ip with a load balancer configuration to a pod ip.</p>
<p>In the end the whole chain would look something like this:</p>
<pre><code>http://example.com  
  -&gt; http://&lt;some-ip&gt; (domain translated to ip)
    -&gt; http://&lt;node-ip&gt;:&lt;node-port&gt; (ingress-controller service)
---
      -&gt; http://&lt;cluster-internal-ip&gt;:&lt;some-port&gt; (service of your application)
        -&gt; http://&lt;other-cluster-internal-ip&gt;:&lt;some-port&gt; (ip of one of n pods)
</code></pre>
<p>where the <code>---</code> line shows the switch from cluster external to cluster internal traffic. The <code>cluster-internal-ip</code> will be from the configured <code>service-cdir</code> and the <code>other-cluster-internal-ip</code> will be from the configured <code>pod-cidr</code>.</p>
<p>Note that there are different ways to configure cluster internal traffic routing, how to run <code>kube-proxy</code> and some parts might even be a bit simplified, but this should give you a good enough understanding of the overall concept.</p>
<p>Also see <a href="https://stackoverflow.com/a/71753345/10020419">this answer</a> on the question 'What is a Kubernetes LoadBalancer On-Prem', that might provide additional input.</p>
