Metal LB with Nginx Ingress Controller on Bare Metal Kubernetes

Exposing your services in a manged Kubernetes service such as EKS, AKS or GKE is much simpler as once you deploy a Kubernetes service with a type load balancer, it would deploy the relative cloud native load balancer for you.

When it comes to Kubernetes clusters which are deployed on bare metal, this option is not available. If you need to expose your services and nodePort is not an option, you could use Metal LB to expose your services. Metal LB would deploy a virtual load balancer which would allow you to expose your services.

First you would need to deploy the Metal LB control plane in your cluster.

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml

The following Metal LB configmap would need to be deployed in order to configure the IP addresses used for Metal LB.

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.27.7.17-192.27.7.19

Please note that the addresses should be within the sub net of your Kubernetes cluster.

Deploy Nginx ingress controller using helm.

helm install ingress-nginx ingress-nginx \    
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace

The IP address would be allocated to the Nginx load balancer service.

kubectl get svc -n ingress-nginx

NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.43.150.251   192.27.7.17   80:31480/TCP,443:30573/TCP   60s
ingress-nginx-controller-admission   ClusterIP      10.43.44.30     <none>        443/TCP                      60s

The main configurations regarding Metal LB and the Nginx Ingress Controller are now done. You could use an ingress with a sample service and deploy to test the above scenario.