<p>I have already setup a service in a k3s cluster using:</p>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: myservice
  namespace: mynamespace
  labels:
    app: myapp
spec:
  type: LoadBalancer
  selector:
    app: myapp
  ports:
  - port: 9012 
    targetPort: 9011 
    protocol: TCP
</code></pre>
<blockquote>
<p>kubectl get svc -n mynamespace</p>
</blockquote>
<pre><code>NAME            TYPE           CLUSTER-IP      EXTERNAL-IP                                PORT(S)          AGE
minio           ClusterIP      None            &lt;none&gt;                                     9011/TCP         42m
minio-service   LoadBalancer   10.32.178.112   192.168.40.74,192.168.40.88,192.168.40.170   9012:32296/TCP   42m
</code></pre>
<blockquote>
<p>kubectl describe svc myservice -n mynamespace</p>
</blockquote>
<pre><code>Name:                     myservice
Namespace:                mynamespace
Labels:                   app=myapp
Annotations:              &lt;none&gt;
Selector:                 app=myapp
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.32.178.112
IPs:                      10.32.178.112
LoadBalancer Ingress:     192.168.40.74, 192.168.40.88, 192.168.40.170
Port:                     &lt;unset&gt;  9012/TCP
TargetPort:               9011/TCP
NodePort:                 &lt;unset&gt;  32296/TCP
Endpoints:                10.42.10.43:9011,10.42.10.44:9011
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   &lt;none&gt;
</code></pre>
<p>I assume from the above that I sould be able to access the minIO console from:
<a href="http://192.168.40.74:9012" rel="nofollow noreferrer">http://192.168.40.74:9012</a> but it is not possible.</p>
<p>Error message:</p>
<blockquote>
<p>curl: (7) Failed to connect to 192.168.40.74 port 9012: Connection
timed out</p>
</blockquote>
<p>Furthemore, If I execute</p>
<blockquote>
<p>kubectl get node -o wide -n mynamespace</p>
</blockquote>
<pre><code>NAME           STATUS   ROLES                  AGE     VERSION        INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION       CONTAINER-RUNTIME
antonis-dell   Ready    control-plane,master   6d      v1.21.2+k3s1   192.168.40.74    &lt;none&gt;        Ubuntu 18.04.1 LTS               4.15.0-147-generic   containerd://1.4.4-k3s2
knodeb         Ready    worker                 5d23h   v1.21.2+k3s1   192.168.40.88   &lt;none&gt;        Raspbian GNU/Linux 10 (buster)   5.4.51-v7l+          containerd://1.4.4-k3s2
knodea         Ready    worker                 5d23h   v1.21.2+k3s1   192.168.40.170   &lt;none&gt;        Raspbian GNU/Linux 10 (buster)   5.10.17-v7l+         containerd://1.4.4-k3s2
</code></pre>
<p>As it is shown above the INTERNAL-IPs of nodes are the same as the EXTERNAL-IPs of Load Balancer. Am I doing something wrong here?</p>

<h2 id="k3s-cluster-initial-configuration">K3S cluster initial configuration</h2>
<p>To reproduce the environment I created a two node <code>k3s</code> cluster following next steps:</p>
<ol>
<li><p>Install k3s control-plane on required host:</p>
<pre><code>curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC='--write-kubeconfig-mode=644' sh -
</code></pre>
</li>
<li><p>Verify it works:</p>
<pre><code>k8s kubectl get nodes -o wide
</code></pre>
</li>
<li><p>To add a worker node, this command should be run on a worker node:</p>
<pre><code>curl -sfL https://get.k3s.io | K3S_URL=https://control-plane:6443 K3S_TOKEN=mynodetoken sh -
</code></pre>
</li>
</ol>
<p>Where <code>K3S_URL</code> is a control-plane URL (with IP or DNS)</p>
<p><code>K3S_TOKEN</code> can be got by:</p>
<pre><code>sudo cat /var/lib/rancher/k3s/server/node-token
</code></pre>
<p>You should have a running cluster:</p>
<pre><code>$ k3s kubectl get nodes -o wide
NAME           STATUS   ROLES                  AGE   VERSION        INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION   CONTAINER-RUNTIME
k3s-cluster    Ready    control-plane,master   27m   v1.21.2+k3s1   10.186.0.17   &lt;none&gt;        Ubuntu 18.04.5 LTS   5.4.0-1046-gcp   containerd://1.4.4-k3s2
k3s-worker-1   Ready    &lt;none&gt;                 18m   v1.21.2+k3s1   10.186.0.18   &lt;none&gt;        Ubuntu 18.04.5 LTS   5.4.0-1046-gcp   containerd://1.4.4-k3s2
</code></pre>
<h2 id="reproduction-and-testing">Reproduction and testing</h2>
<p>I created a simple deployment based on <code>nginx</code> image by:</p>
<pre><code>$ k3s kubectl create deploy nginx --image=nginx
</code></pre>
<p>And exposed it:</p>
<pre><code>$ k3s kubectl expose deploy nginx --type=LoadBalancer --port=8080 --target-port=80
</code></pre>
<p>This means that <code>nginx</code> container in pod is listening to port <code>80</code> and <code>service</code> is accessible on port <code>8080</code> within the cluster:</p>
<pre><code>$ k3s kubectl get svc -o wide
NAME         TYPE           CLUSTER-IP    EXTERNAL-IP               PORT(S)          AGE   SELECTOR
kubernetes   ClusterIP      10.43.0.1     &lt;none&gt;                    443/TCP          29m   &lt;none&gt;
nginx        LoadBalancer   10.43.169.6   10.186.0.17,10.186.0.18   8080:31762/TCP   25m   app=nginx
</code></pre>
<p>Service is accessible on both IPs or <code>localhost</code> AND port <code>8080</code> or <code>NodePort</code> as well.</p>
<p><strong>+</strong> taking into account the error you get <code>curl: (7) Failed to connect to 192.168.40.74 port 9012: Connection timed out</code> means that service is configured, but it doesn't respond properly (it's not 404 from ingress or <code>connection refused</code>).</p>
<h2 id="answer-on-second-question-loadbalancer">Answer on second question - Loadbalancer</h2>
<p>From <a href="https://rancher.com/docs/k3s/latest/en/networking/#how-the-service-lb-works" rel="noreferrer">rancher k3s official documentation about LoadBalancer</a>, <a href="https://github.com/k3s-io/klipper-lb" rel="noreferrer">Klipper Load Balancer</a> is used. From their github repo:</p>
<blockquote>
<p>This is the runtime image for the integrated service load balancer in
klipper. This works by using a host port for each service load
balancer and setting up iptables to forward the request to the cluster
IP.</p>
</blockquote>
<p>From <a href="https://rancher.com/docs/k3s/latest/en/networking/#how-the-service-lb-works" rel="noreferrer">how the service loadbalancer works</a>:</p>
<blockquote>
<p>K3s creates a controller that creates a Pod for the service load
balancer, which is a Kubernetes object of kind Service.</p>
<p>For each service load balancer, a DaemonSet is created. The DaemonSet
creates a pod with the svc prefix on each node.</p>
<p>The Service LB controller listens for other Kubernetes Services. After
it finds a Service, it creates a proxy Pod for the service using a
DaemonSet on all of the nodes. This Pod becomes a proxy to the other
Service, so that for example, requests coming to port 8000 on a node
could be routed to your workload on port 8888.</p>
<p>If the Service LB runs on a node that has an external IP, it uses the
external IP.</p>
</blockquote>
<p>In other words yes, this is expected that loadbalancer has the same IP addresses as  hosts' <code>internal-IP</code>s. Every service with loadbalancer type in k3s cluster will have its own <code>daemonSet</code> on each node to serve direct traffic to the initial service.</p>
<p>E.g. I created the second deployment <code>nginx-two</code> and exposed it on port <code>8090</code>, you can see that there are two pods from two different deployments AND four pods which act as a loadbalancer (please pay attention to names - <code>svclb</code> at the beginning):</p>
<pre><code>$ k3s kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP           NODE           NOMINATED NODE   READINESS GATES
nginx-6799fc88d8-7m4v4       1/1     Running   0          47m   10.42.0.9    k3s-cluster    &lt;none&gt;           &lt;none&gt;
svclb-nginx-jc4rz            1/1     Running   0          45m   10.42.0.10   k3s-cluster    &lt;none&gt;           &lt;none&gt;
svclb-nginx-qqmvk            1/1     Running   0          39m   10.42.1.3    k3s-worker-1   &lt;none&gt;           &lt;none&gt;
nginx-two-6fb6885597-8bv2w   1/1     Running   0          38s   10.42.1.4    k3s-worker-1   &lt;none&gt;           &lt;none&gt;
svclb-nginx-two-rm594        1/1     Running   0          2s    10.42.0.11   k3s-cluster    &lt;none&gt;           &lt;none&gt;
svclb-nginx-two-hbdc7        1/1     Running   0          2s    10.42.1.5    k3s-worker-1   &lt;none&gt;           &lt;none&gt;
</code></pre>
<p>Both services have the same <code>EXTERNAL-IP</code>s:</p>
<pre><code>$ k3s kubectl get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP               PORT(S)          AGE
nginx        LoadBalancer   10.43.169.6    10.186.0.17,10.186.0.18   8080:31762/TCP   50m
nginx-two    LoadBalancer   10.43.118.82   10.186.0.17,10.186.0.18   8090:31780/TCP   4m44s
</code></pre>
