Load Balancers
Metallb
Kubernetes is wonderful for orchestrating your workloads, but out of the box exposing those workloads to the outside world isn't currently elegant. There are 2 ways to expose the workloads. Load balancers and ingress controllers. On this page, we will discuss one load balancer solution. Metallb is a Kubernetes load balancer solution. It runs in 2 modes layer 2 and layer 3. For the use in this cluster, we will be running it in layer 3 mode. It uses layer 3 to advertise routes to upstream BGP routers. In our case, we will be peering to the OpenWRT core router we discussed on another page.
Metallb is configured using a Kubernetes config map.
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
peers:
- peer-address: 192.168.200.1
peer-asn: 64501
my-asn: 64500
address-pools:
- name: default
protocol: bgp
addresses:
- 192.168.197.0/24
This is the config map I'm using for metallb in this demo cluster. Notice the different ASN numbers, this means that metallb and the router are speaking eBGP. The address space that's being used by metallb to advertise is 192.168.197.0/24. 64500 and 64501 are in the ARIN assigned numbers range for private ASN numbers which is perfectly legal in this situation where these (also private) routes will never be advertised outside this network.
Quagga/Zebra
Quagga/Zebra has a configuration that looks Cisco "IOSish"
router bgp 64501
bgp router-id 192.168.198.254
neighbor 192.168.201.11 remote-as 64500
neighbor 192.168.201.12 remote-as 64500
Since I have 3 nodes in my Kubernetes cluster, but one is a master node configured with fewer resources than the service/worker nodes and the master node will never be running any workloads with services to be exposed, I only peer with the 2 service nodes in the cluster.
show bgp summary
IPv4 Unicast Summary:
---------------------
BGP router identifier 192.168.198.254, local AS number 64501
RIB entries 2, using 216 bytes of memory
Peers 2, using 14 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
192.168.201.11 4 64500 10158 10157 0 0 0 3d12h38m 1
192.168.201.12 4 64500 10158 10157 0 0 0 3d12h38m 2
show ip route bgp
cr1.cluster.sysnetinc.com# show ip route bgpCodes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, P - PIM, A - Babel,
> - selected route, * - FIB route B>* 192.168.197.0/32 [20/0] via 192.168.201.11, br-LAN201, 3d13h00m
B>* 192.168.197.1/32 [20/0] via 192.168.201.12, br-LAN201, 3d13h00m
B>* 192.168.197.254/32 [20/0] via 192.168.201.12, br-LAN201, 00:00:12
Kubernetes Manifests
The manifests that created 2 of these load balancers are below.
apiVersion: v1The above manifest creates a load balancer service named "test-service". It requests the automatic assignment of an "external" IP address. It also maps the service port on the deployment from tcp/8000 to the external port tcp/80 on the assigned load balancer. Finally, it requests that metallb advertises the assigned address directly from the service node using the "spec.externalTrafficPolicy: Local" key.
kind: Service
metadata:
name: test-service
spec:
selector:
app: test-deployment
type: LoadBalancer
externalTrafficPolicy: Local
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8000
apiVersion: v1The above manifest creates a load balancer service named "test-service-3". It exposes the same deployment as "test-service" however it exposes it on a different external port and address. This manifest requests that an explicit IP address be assigned to it using the "spec.loadBalancerIP: 192.168.197.254" key.
kind: Service
metadata:
name: test-service-3
spec:
selector:
app: test-deployment
type: LoadBalancer
externalTrafficPolicy: Local
loadBalancerIP: 192.168.197.254
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8000
Kubernetes Services
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47d
nginx LoadBalancer 10.101.210.28 192.168.197.0 80:30894/TCP 12d
test-service LoadBalancer 10.101.128.104 192.168.197.1 80:30384/TCP 7d4h
test-service-1 NodePort 10.97.204.46 <none> 80:30614/TCP 5d13h
test-service-3 LoadBalancer 10.101.244.47 192.168.197.254 8080:32336/TCP 6m14s
The above table is from the cluster being used in these examples. Notice that only the LoadBalancer type services actually have an external IP listed. The "nginx" and "test-service" load balancers were automatically assigned the IP addresses in use. So far, it appears that metallb just works through the pool linearly for auto assignments. "test-service-3" has an address explicitly assigned via the manifest shown above.
No comments:
Post a Comment