MetalLB
Why?
Kubernetes does not offer an implementation of network load balancers (Services of type LoadBalancer) for bare-metal clusters. The implementations of network load balancers that Kubernetes does ship with are all glue code that calls out to various IaaS platforms (GCP, AWS, Azure…). If you’re not running on a supported IaaS platform (GCP, AWS, Azure…), LoadBalancers will remain in the “pending” state indefinitely when created.
Bare-metal cluster operators are left with two lesser tools to bring user traffic into their clusters, “NodePort” and “externalIPs” services. Both of these options have significant downsides for production use, which makes bare-metal clusters second-class citizens in the Kubernetes ecosystem.
MetalLB aims to redress this imbalance by offering a network load balancer implementation that integrates with standard network equipment, so that external services on bare-metal clusters also “just work” as much as possible.
we simulate a LoadBalancer using MetalLB https://metallb.universe.tf/
Allow firewall: run on everynode
$ sudo firewall-cmd --add-port=7946/tcp --permanent
$ sudo firewall-cmd --add-port=7472/tcp --permanent
$ sudo firewall-cmd --add-port=8080/tcp --permanent
$ sudo firewall-cmd --add-icmp-block-inversion
$ sudo firewall-cmd --add-service=dhcp --permanent
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-ports
- Speaker: Port 7946 (TCP) for communication and service management.
- Controller: Port 8080 (TCP) for managing IP allocation.
Preparation
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system
Installation Metallb by manifest
To install MetalLB, apply the manifest:
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.8/config/manifests/metallb-native.yaml
https://github.com/metallb/metallb/
In the context of Kubernetes, a manifest is a YAML or JSON file that defines the desired state of a resource in the cluster. It describes the configuration and specifications of various Kubernetes objects, such as Pods, Services, Deployments, ConfigMaps, and more.
This command will create the necessary components for MetalLB, including the controller and speaker deployments.
Verify the Installation:
$ kubectl get pods -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-77676c78d9-wzwwm 1/1 Running 0 39m
speaker-7q7kw 1/1 Running 0 39m
speaker-7t6hm 1/1 Running 0 39m
speaker-gccwq 1/1 Running 0 39m
speaker-wbwrh 1/1 Running 0 39m
- 4 node will have 4
speaker-<speake-pod-name>
$ kubectl logs -n metallb-system <controller-pod-name>
$ kubectl logs -n metallb-system <speake-pod-name>
example:
kubectl logs -n metallb-system controller-77676c78d9-wzwwm
kubectl logs -n metallb-system speaker-7q7kw
show pods and log:
get event
$ kubectl get events -n metallb-system
Describe pod:
$ kubectl describe pods -n metallb-system
Configure MatalLB
MetalLB needs a configuration to know which IP addresses it can use. You can create a ConfigMap to specify a pool of IP addresses. Here’s an example:
Create a file named metallb-config.yaml with the following content:
cat <<EOF | tee metallb-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.1.200-192.168.1.210
EOF
apply configmap
$ kubectl apply -f metallb-config.yaml
$ kubectl get pods -A
verify config map
$ kubectl get configmap config -n metallb-system -o yaml
descripe
$ kubectl describe configmap config -n metallb-system
output to yml:
- if needed to delete please run command delete
kubectl delete configmaps config -n metallb-system
show how to log event:
Create Deployment
cat <<EOF | tee nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hello-deployment
namespace: my-namespace # Replace with your namespace if necessary
spec:
replicas: 3
selector:
matchLabels:
app: nginx-hello
template:
metadata:
labels:
app: nginx-hello
spec:
containers:
- name: nginx-hello
image: nginxdemos/nginx-hello:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-hello-service
namespace: my-namespace # Replace with your namespace if necessary
spec:
selector:
app: nginx-hello
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
EOF
Apply menifest:
$ kubectl apply -f nginx-deployment.yaml
$ kubectl get pods -A
$ kubectl get pods -n my-namespace
$ kubectl get svc -n my-namespace
External IPs:
The kubectl describe svc and kubectl get svc commands will display the external IP of a Service.
$ kubectl describe svc nginx-hello-service -n my-namespace
Summary kube command
kubectl get nodes -o wide
kubectl get all --all-namespaces
kubectl get all # namespace defalut
kubectl get all -n metallb-system # namespace metallb-system
kubectl describe configmap config -n metallb-system # configmap
kubectl describe configmap -n kube-system kube-proxy
kubectl describe pods -n metallb-system
Delete
$ kubectl delete -f https://raw.githubusercontent.com/metallb/metallb/v0.14.8/config/manifests/metallb-native.yaml
$ kubectl delete -f nginx-deployment.yaml && kubectl delete -f metallb-config.yaml
Delete resource
$ kubectl get deployments -A
$ kubectl delete deployments nginx-hello-deployment -n my-namespace
$ kubectl delete pod -n metallb-system --all
$ kubectl delete services -n my-namespace --all
Restart Metallb component
$ kubectl rollout restart daemonset speaker -n metallb-system
$ kubectl rollout restart deployment controller -n metallb-system
Check Metallb log
$ kubectl logs -n metallb-system daemonset/speaker
$ kubectl logs -n metallb-system deployment/controller
cat <<EOF | tee ipaddresspool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: ip-pool
namespace: metallb-system
spec:
addresses:
- 192.168.1.100-192.168.1.120
EOF