Photo by Matthieu Beaumont
Kubernetes on bare-metal is when your cluster runs on servers rather than virtual machines. This approach might not be the best but it offers a cheap alternative as well as increasing performance. In cloud-based Kubernetes clusters, cloud vendors expose services with Load Balancers, but those are unavailable in a bare-metal environment.
Don’t panic! You can still expose your services using a virtualized environment that offers the same user experience as cloud-based load balancers. The one that we are going to use today is called OpenELB and is an open source load balancer implementation for bare-metal Kubernetes clusters.
You only need to install OpenELB once and it will take care of the rest or almost. The only requirement is that your Kubernetes version is 1.15+.
I’m going to show you how to install OpenELB using kubectl, but you can also do it with Helm3 if you’d like. Also you can find links to the documentation at the bottom of this guide.
kubectl apply -f https://raw.githubusercontent.com/openelb/openelb/master/deploy/openelb.yaml
watch kubectl get po -n openelb-system
If you wish to delete OpenELB you just need to run:
kubectl delete -f https://raw.githubusercontent.com/openelb/openelb/master/deploy/openelb.yaml
If you want to check its deletion you can check your namespaces and if it’s not there then OpenELB has been deleted successfully:
kubectl get ns
At this point you need to choose in which mode you want OpenELB to run and if you don’t know where to start, then you'll probably want to use Layer 2 as there is no configuration required. If you are not sure which one to choose, below you can find a list of pros and cons I created.
A BGP is a gateway protocol that allows the internet to exchange routing information between Anonymous Systems (AS) via peering.
If you don’t care about High Availability etc… and you just want to learn how to use Kubernetes and have a private cluster to experiment with, your choice is Layer 2.
If you want to manage your own cluster for your applications and services, use the BGP mode.
And If your router doesn't support the BGP mode, but you still want to have high availability for your services and you’re not afraid of potential issues you might have, then your last choice is the VIP mode.
If you are running a cluster as a personal project and/or to learn how to use Kubernetes, my suggestion is to avoid VIP and Layer 2 modes and use BGP. If your router doesn’t support it don’t worry, because you can install a virtual router using BIRD.
When you don’t have a router or one that supports BGP, you can use BIRD. It allows you to create a virtual router supporting BGP.
sudo add-apt-repository ppa:cz.nic-labs/bird
sudo apt-get update
sudo apt-get install bird
sudo systemctl enable bird
sudo vim /etc/bird/bird.conf
router id 192.168.0.5;
protocol kernel {
scan time 60;
import none;
export all;
merge paths on;
}
protocol device {
scan time 60;
}
protocol bgp neighbor1 {
local as 50001;
neighbor 192.168.0.2 port 17900 as 50000;
source address 192.168.0.5;
import all;
export all;
enable route refresh off;
add paths on;
}
sudo systemctl restart bird
sudo systemctl status bird
Next, we are going to create the 3 objects that will make BGP possible:
The commands that follows consist in:
sudo vim bgp-conf.yaml
apiVersion: network.kubesphere.io/v1alpha2
kind: BgpConf
metadata:
name: default
spec:
as: 50000
listenPort: 17900
routerId: 192.168.0.2
kubectl apply -f bgp-conf.yaml
sudo vim bgp-peer.yaml
apiVersion: network.kubesphere.io/v1alpha2
kind: BgpPeer
metadata:
name: bgp-peer
spec:
conf:
peerAs: 50001
neighborAddress: 192.168.0.5
kubectl apply -f bgp-peer.yaml
sudo vim bgp-eip.yaml
apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:
name: bgp-eip
spec:
address: 172.22.0.2-172.22.0.10
kubectl apply -f bgp-eip.yaml
Now you can create your Deployment and Service yaml files by using the below configurations and applying.
apiVersion: apps/v1
kind: Deployment
metadata:
name: <name of the deployment>
spec:
replicas: 2
selector:
matchLabels:
app: <name of the app>
template:
metadata:
labels:
app: <name of the app>
spec:
containers:
- image: <username/image>
name: <image>
ports:
- containerPort: 8080
kind: Service
apiVersion: v1
metadata:
name: <service>
annotations:
lb.kubesphere.io/v1alpha1: openelb
protocol.openelb.kubesphere.io/v1alpha1: bgp
eip.openelb.kubesphere.io/v1alpha2: bgp-eip
spec:
selector:
app: <yourapp>
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 8080
externalTrafficPolicy: Cluster
Once you’ve done that, you can see if your LoadBalancer is running correctly by checking its External-IP:
kubectl get svc
That’s how you set up a LoadBalancer for your bare-metal cluster. Obviously you won’t use the virtual router for a Production environment, but it’s useful when you want to run your private Kubernetes.