Start a Conversation

Unsolved

30 Posts

756

October 23rd, 2022 00:00

EKS Anywhere, and MetalLB Load Balancer services

EKS Anywhere, and MetalLB Load Balancer services

This article is part of the EKS Anywhere series EKS Anywhere., extending the Hybrid cloud momentum

This article has been updated for v0.13.0+ due to depreciation of ConfigInLine method of creating IP address pools for MetalLB.

Kubernetes core and/or EKS Anywhere equally does not provide for any Load Balancers. Here in the choices are left to the end adopter of deploying a relevant load-balancer that can help access the spread of of deployed applications via the pods

dellambarhassani_0-1666508849962.png

Generally speaking., in public clouds, the default integrations with the load-balancer service extensions are an out-of-box solution. However, in an on-premises scenario, you would need a hardware, or a software defined load-balancer that can be integrated with your Kubernetes cluster.

This could be a limiting factor both in terms of cost as well as availability and integration of such solutions from leading vendors.

In that context, the MetalLB open-source project is one of the preferred choices for alternative Load balancer services that does not depend on any external load-balancers. While the project aimed at bare-metal clusters (hence the name)., however it can be used with any kind of cluster (bare-metal or virtualized).

MetalLB is one of the most popular on-premises replacements for the LoadBalancer cloud integrations. The whole solution runs inside a particular Kubernetes cluster where these services are needed. MetalLB is a native Kubernetes load balancing solution for bare-metal Kubernetes clusters. Detailed information about MetalLB can be found here

The main component is an in-cluster Kubernetes controller which watches LB service resources, and based on the configuration supplied in a ConfigMap, allocates and writes back IP addresses from a dedicated pool for new services. It maintains a leader node for each service, and depending on the working mode, advertises it via BGP or ARP (sending out unsolicited ARP packets in case of failovers).

The main difference from the user’s point of view between the two is that the ARP solution requires each node to be in a single L2 network (subnet), while BGP requires dynamic routing configuration on the upstream router.

Let’s apply this solution in the context of EKS Anywhere and practically view it’s benefit and usage.

Note: We will use the Layer 2 mode of MetalLB implementation for this scenario

Pre-requisite:

A working EKS Anywhere cluster either standalone or with a dedicated management cluster. It does not matter which model you use to deploy the cluster., at the end of the day we need a working EKS Anywhere cluster.

Note: As per the cluster creation process you should have ear-marked a set of static IP addresses (for control plane and for load balancer services). We will need those static IP addresses in this configuration

In my case the range of IP addresses used as static are 172.24.165.21 to 172.24.165.25 (yours could/will be different)

Step-1 Install MetalLB via the helm chart

Assuming our cluster name is testworkload01
source eks-anywhere/cluster-ops/switch-cluster.sh
clusterName: testworkload01
Once the above is done, the kubeconfig and context is set for the admin user targeting testworkload01 EKS Anywhere cluster
helm upgrade --install --wait --timeout 15m   --namespace metallb-system --create-namespace   --repo https://metallb.github.io/metallb metallb metallb
Release "metallb" does not exist. Installing it now.
W0711 06:55:51.507363   23991 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W0711 06:55:51.510195   23991 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W0711 06:55:51.606228   23991 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W0711 06:55:51.607914   23991 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
NAME: metallb
LAST DEPLOYED: Mon Jul 11 06:55:48 2022
NAMESPACE: metallb-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
MetalLB is now running in the cluster.
Now you can configure it via its CRs. Please refer to the metallb official docs
on how to use the CRs.
Next we will use the Custom Resources to create the IP address pools and advertise them
cat <

Step-2 Deploy sample application and quick observations

Sample files for the load-balancer testing using a hello-world deployment are already placed inside of $HOME/eks-anywhere/hello-world sub-directory of the EKS-A administrative machine

kubectl apply -f hello-world-deployment.yaml
Once the pods are in running state
kubectl apply -f hello-world-service.yaml

The below logs indicate a sample execution and observation for the above commands in my scenario

cd /home/ubuntu/eks-anywhere/hello-world

kubectl apply -f hello-world-deployment.yaml
deployment.apps/hello-world created

kubectl get pods
NAME                           READY   STATUS    RESTARTS   AGE
hello-world-6df5659cb7-7hwxl   1/1     Running   0          88s
hello-world-6df5659cb7-gdzr7   1/1     Running   0          88s

kubectl create -f hello-world-service.yaml
service/hello-world created

kubectl get svc
NAME          TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
hello-world   LoadBalancer   10.104.206.5   172.24.165.21   80:31965/TCP   5s
kubernetes    ClusterIP      10.96.0.1                443/TCP        120m

kubectl describe svc hello-world
Name:                     hello-world
Namespace:                default
Labels:                   
Annotations:              
Selector:                 app=hello-world
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.104.206.5
IPs:                      10.104.206.5
LoadBalancer Ingress:     172.24.165.21
Port:                       80/TCP
TargetPort:               80/TCP
NodePort:                   31965/TCP
Endpoints:                
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason       Age    From                Message
  ----    ------       ----   ----                -------
  Normal  IPAllocated  2m22s  metallb-controller  Assigned IP ["172.24.165.21"]

kubectl logs metallb-controller-69bbb4669c-zwlb8 -n metallb-system
{"branch":"HEAD","caller":"level.go:63","commit":"v0.12.1","goversion":"gc / go1.16.14 / amd64","level":"info","msg":"MetalLB controller starting version 0.12.1 (commit v0.12.1, branch HEAD)","ts":"2022-05-09T05:25:40.010545729Z","version":"0.12.1"}
{"caller":"level.go:63","level":"info","msg":"secret succesfully created","op":"CreateMlSecret","ts":"2022-05-09T05:25:40.035930967Z"}
{"caller":"level.go:63","configmap":"metallb-system/metallb","event":"configLoaded","level":"info","msg":"config (re)loaded","ts":"2022-05-09T05:25:40.136808958Z"}
{"caller":"level.go:63","event":"stateSynced","level":"info","msg":"controller synced, can allocate IPs now","ts":"2022-05-09T05:25:40.137910533Z"}
{"caller":"level.go:63","event":"ipAllocated","ip":["172.24.165.21"],"level":"info","msg":"IP address assigned by controller","service":"default/hello-world","ts":"2022-05-09T06:50:06.082923965Z"}
{"caller":"level.go:63","event":"serviceUpdated","level":"info","msg":"updated service object","service":"default/hello-world","ts":"2022-05-09T06:50:06.094906055Z"}

>>>> As you can see from the output, the metalLB controller interacts with the kubernetes service component to allocate the IP to the exposed load-balancer service for hello-world" <<<<

As one can see from the above output, the service name hello-world gets an IP address of 172.24.165.21. This is due to the fact that my static IP ranges 172.21.165.21 to 172.24.165.25

In addition, one can also see from the service description how the MetalLB controller interacts with the Kubernetes control plane to assign the IP address and update the hello-world service.

Step-4 Observe MetalLB constructs

We can use the below gist to issue commands and observe the namespace, pods created after installing MetalLB. You can notice that the above installation creates one controller as a Deployment type pod and another 4 pods via a DaemonSet.

All these pods run in a dedicated namespace called metallb-system

kubectl get namespace
NAME                                STATUS   AGE
capi-kubeadm-bootstrap-system       Active   49m
capi-kubeadm-control-plane-system   Active   49m
capi-system                         Active   49m
capv-system                         Active   49m
cert-manager                        Active   50m
default                             Active   52m
eksa-system                         Active   48m
etcdadm-bootstrap-provider-system   Active   49m
etcdadm-controller-system           Active   49m
kube-node-lease                     Active   52m
kube-public                         Active   52m
kube-system                         Active   52m
metallb-system                      Active   17m <<<<<<<<<<<<<<<<<<<

kubectl get deployments -n metallb-system
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
metallb-controller   1/1     1            1           26m


kubectl get daemonset -n metallb-system
NAME              DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
metallb-speaker   4         4         4       4            4           kubernetes.io/os=linux   27m


As you can see a new namespace called metallb-system has been created. Let's observe the pods in this namespace that form the operational context for metalLB.

As you can see below, one pod reflecting the controller component via a deployment and another 4 pods that form a part of the DaemonSet as seen above

kubectl get pods -n metallb-system
NAME                                  READY   STATUS    RESTARTS   AGE
metallb-controller-69bbb4669c-zwlb8   1/1     Running   0          17m
metallb-speaker-pfhdb                 1/1     Running   0          17m
metallb-speaker-qxbp7                 1/1     Running   0          17m
metallb-speaker-wsbls                 1/1     Running   0          17m
metallb-speaker-zxc6q                 1/1     Running   0          17m


An example log of the controller pod

kubectl logs metallb-controller-69bbb4669c-zwlb8 -n metallb-system
{"branch":"HEAD","caller":"level.go:63","commit":"v0.12.1","goversion":"gc / go1.16.14 / amd64","level":"info","msg":"MetalLB controller starting version 0.12.1 (commit v0.12.1, branch HEAD)","ts":"2022-05-09T05:25:40.010545729Z","version":"0.12.1"}
{"caller":"level.go:63","level":"info","msg":"secret succesfully created","op":"CreateMlSecret","ts":"2022-05-09T05:25:40.035930967Z"}
{"caller":"level.go:63","configmap":"metallb-system/metallb","event":"configLoaded","level":"info","msg":"config (re)loaded","ts":"2022-05-09T05:25:40.136808958Z"}
{"caller":"level.go:63","event":"stateSynced","level":"info","msg":"controller synced, can allocate IPs now","ts":"2022-05-09T05:25:40.137910533Z"}

The configuration map created as a part of the installation

kubectl get configmap -n metallb-system
NAME               DATA   AGE
kube-root-ca.crt   1      34m
metallb            1      34m

RBAC created as a part of the MetalLB installation

kubectl get serviceaccount -n metallb-system
NAME                 SECRETS   AGE
default              1         35m
metallb-controller   1         35m
metallb-speaker      1         35m

kubectl get role -n metallb-system
NAME                     CREATED AT
metallb-config-watcher   2022-05-09T05:25:23Z
metallb-controller       2022-05-09T05:25:23Z
metallb-pod-lister       2022-05-09T05:25:23Z

kubectl get rolebinding -n metallb-system
NAME                     ROLE                          AGE
metallb-config-watcher   Role/metallb-config-watcher   36m
metallb-controller       Role/metallb-controller       36m
metallb-pod-lister       Role/metallb-pod-lister       36m

We can easily observe the simplicity with which we can induce a software defined load balancer in a Kubernetes setup. That’s it for now. Hope you found the article insightful and easy to get started with deploying MetalLB on EKS Anywhere clusters
cheers

Ambar Hassani

#iwork4dell

 

 

No Responses!

Top