Балансировка с помощью MetalLB в Bare Metall инсталляции Kubernetes для Ingress Nginx

Статья-инструкция по настройке MetalLB в связке с Ingress Nginx в кластере Kubernetes.

Зачем это нужно?

Классическое развертывание Ingress Nginx контроллера (далее Ingress) в Bare Metall инсталляции (на мой взгляд) выглядит так:

  1. Добавляем ноду с белым IP (или делаем DNAT на IP ноды) в кластер Kubernetes.
  2. Устанавливаем на эту ноду Ingress, указываем нужный IP как ExternalIP, ставим taint на запрет любых других подов.
  3. (Опционально) Добавляем cert manager.

Это делается легко, быстро и хорошо работает. До тех пор пока нода с Ingress не упадет по какой-либо причине (а такое бывает).

Если бы у нас было бы облако, мы бы автоматом при инсталляции Ingress (например, с помощью Helm chart) получили бы ExternalIP типа LoadBalancer и такой проблемы бы не было.

Здесь нам на помощью приходит MetalLB.

Установка и настройка MetalLB

Установка крайне проста, сделайте по гайду на официальной сайте.

https://metallb.universe.tf/installation

Я развернул MetalLB на 3-х нодах которые выполняют роль Ingress и только. Сейчас мне нечего балансировать на других узлах.

Теперь нужно создать пул адресов который будет предоставлять MetalLB. Во всех гайдах предлагают взять большую подсеть /24 под балансировку. В моём случае возьму всего 2 IP адреса, что бы потом сделать 2 DNAT на роутере и поднять две инсталляции Ingress. Эти адреса не должен быть на что-то назначены или быть в DHCP пуле. Просто берите адреса которые нигде не используются, ими будет управлять MetalLB.

Создам вот такой манифест metallb-pool.yaml (в любом текстовом редакторе)

Применю его с помощью kubectl

На этом настройка MetalLB закончена.

Установка и настройка Ingress Nginx

Установка Ingress Nginx (далее Ingress) тоже довольно проста.

Я разворачиваю с помощью Helm Chart, указывая правильные tollerations, affinity и настройки самого Ingress.

Сначала получаю все значения которые есть в Helm Chart.

Очищаю всё лишнее и оставляю самый минимум.

В моём случае важно указать tolerations и affinity, что бы поды поднимались на правильных узлах. Так же ставлю replicaCount в размере 3

Что обязательно надо сделать в любой инсталляции с MetalLB это выставить externalTrafficPolicy как Local.

С помощью ingressClassResource.name вы можете задать имя ingress class что бы дальше указывать его в объекте Ingress вашего http ресурса.

Теперь я могу поднять Ingress.

Сделаю первую инсталляцию.

Обратите внимание что я меняю ingress class name.

И вторую инсталляцию.

В итогу инсталляция должна выглядеть следующим образом

Как видно, Service Ingress’а получил ExternalIP типа LoadBalancer. MetalLB работает.

Можно сделать curl по 192.168.19.230 и получить ответ от веб-сервера.

И даже если я погашу 2 ноды с ролью Ingress, веб-сервер все равно будет отвечать, что и требуется от балансировщика. Можно навешивать любые http приложения на веб-сервер.