A lot of solutions rely on the fact that Kubernetes has
LoadBalancer type services. And why not, it's a fantastic way to indirectly get a load balancing solution in place in front of the applications. And of course, there are other nice building blocks that rely on existence of these load balancers such as external-dns and others. Unfortunately, not all environments are such that there is something to be configured as a load balancer for a service. The environment could be on-premise and/or have network setup in a way that MetalLB cannot be setup. Or you might be running just a small test setup locally and do not wish to build any heavy solutions for it.
To help with these kind of cases we're happy to unveil our newest open source component to the land of Kubernetes. Say hello to Akrobateo, a universal load balancer service implementation. Akrobateo can work in any environment which makes it suitable for many use cases. And it's super light-weight too. It is implemented as an operator that reacts when it sees
type: LoadBalancer services in the cluster.
Akrobateo draws heavy inspiration from K3S servicelb controller: https://github.com/rancher/k3s/blob/master/pkg/servicelb/controller.go. As K3S controller is fully and tightly integrated into K3S, with good reasons, we thought we'd separate the concept into generic operator usable in any Kubernetes cluster.
To deploy Akrobateo, just use the pre-made deployment manifests to deploy the operator. It'll setup the operator itself and all the needed RBAC rules for it to operate properly.
Let's dig in how Akrobateo works by setting up an example service. As a typical case, you have a
Deployment for which you need to create a load balancer in front. For our example deployment we'll use a typical
echoserver based example:
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: echoserver spec: replicas: 1 template: metadata: labels: app: echoserver spec: containers: - image: gcr.io/google_containers/echoserver:1.0 imagePullPolicy: Always name: echoserver ports: - containerPort: 8080
Then to create the needed
Service in front of it we'll use a simple
LoadBalancer type service:
apiVersion: v1 kind: Service metadata: name: echoserver spec: type: LoadBalancer ports: - name: echo port: 8080 targetPort: 8080 protocol: TCP selector: app: echoserver
There's nothing atypical in this, make sure you use proper selector labels to match the pods in the service and also remember to configure the service port(s) properly to match what the application is listening on.
Once Akrobateo sees a service like this it'll start its operations.
Step one of Akrobateo in action is an automatic creation of a
DaemonSet to deploy an actual load balancer for the service on each node. The pods in the
DaemonSet will do the actual load balancing using the trusted workhorse of the entire internet, iptables. The neat "trick" here is that even as the service is of type
LoadBalancer it will still get the cluster IP assigned for service. So the actual balancer pod will "route" the traffic from a host port to the services cluster IP on a specific port. Simple eh? :)
The second part of Akrobateo in action is the fact that once the balancer pods become active, Akrobateo will sync the node's addresses as the external addresses in the service details. So you should see something like this:
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echoserver LoadBalancer 22.214.171.124 126.96.36.199,188.8.131.52,184.108.40.206,220.127.116.11,18.104.22.168 8080:31278/TCP 34m kubernetes ClusterIP 22.214.171.124 <none> 443/TCP 5d3h
Naturally, hitting any of the reported LB addresses on the configured port should get you directed into the application:
$ curl 126.96.36.199:8080 CLIENT VALUES: client_address=('172.31.5.104', 58861) (172.31.5.104) command=GET path=/ real path=/ query= request_version=HTTP/1.1 SERVER VALUES: server_version=BaseHTTP/0.6 sys_version=Python/3.5.0 protocol_version=HTTP/1.0 HEADERS RECEIVED: Accept=*/* Host=188.8.131.52:9090 User-Agent=curl/7.57.0
The third part of Akrobateo in action is when you actually go and delete the given service. Akrobateo will automatically react and remove the created daemonset. No traces are left behind. :)
Please give Akrobateo a test run if you have a suitable use case in your hands. Remember that this is the first public release so there might be still some rough edges. And as always, we'd be delighted to hear what you think of it and if you've hit into any troubles. So create issues, give stars and open PR's on the GitHub repo.
About Kontena Inc.
Kontena Inc. is specialized in creating the most developer friendly solutions for running containers. Kontena's products are built on open source technology developed and maintained by Kontena. Kontena was founded in 2015 and has offices in Helsinki, Finland and New York, USA. More information: www.kontena.io.