Автор статьи: Рустем Галиев

IBM Senior DevOps Engineer & Integration Architect. Официальный DevOps ментор и коуч в IBM

Привет, Хабр! Сегодня мы узнаем, как использовать MetalLB в качестве балансировщика нагрузки, который будет выдавать внешние IP-адреса, которые для сервисов Kubernetes настроены на тип LoadBalancer.

Понимание балансировки нагрузки MetalLB

Балансировка нагрузки — это метод, с помощью которого входящий сетевой трафик направляется на заданный сервер из массива из нескольких серверов. Трафик направляется в соответствии с сервером, который лучше всего подходит для обработки запроса. Балансировщик нагрузки используется для обеспечения равномерного потока трафика в масштабе.

MetalLB — это продукт для балансировки нагрузки, который обычно используется для кластеров Kubernetes, размещенных на компьютерах без операционной системы. Тем не менее, MetalLB хорошо работает, чтобы обеспечить возможности балансировки нагрузки для Kubernetes в Docker (KinD).

Первым делом устанавливаем утилиту sipcalc

Утилита sipcalc, как описано в руководстве, это:

«калькулятор IP-подсети, состоящий из двух частей. Консольная версия на основе простого текста и веб-аналог (cgi) ... Sipcalc в своей простейшей форме принимает IP-адрес и маску подсети в командной строке и выводит информацию о подсети. Sipcalc поддерживает адреса IPv4 и IPv6».

Здесь вы будете использовать sipcalc для определения диапазона IP-адресов, которые MetalLB будет использовать в качестве пула, из которого будут назначаться внешние IP-адреса.

Шаг 1. Убедимся, что кластер Kubernetes запущен и работает. Выполните следующую команду:

kubectl get node -o wide

NAME                 STATUS   ROLES    AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                                     KERNEL-VERSION      CONTAINER-RUNTIME
kind-control-plane   Ready    master   2m59s   v1.19.1   172.19.0.3    <none>        Ubuntu Groovy Gorilla (development branch)   4.4.0-185-generic   containerd://1.4.0
kind-worker          Ready    <none>   2m23s   v1.19.1   172.19.0.2    <none>        Ubuntu Groovy Gorilla (development branch)   4.4.0-185-generic   containerd://1.4.0
kind-worker2         Ready    <none>   2m23s   v1.19.1   172.19.0.4    <none>        Ubuntu Groovy Gorilla (development branch)   4.4.0-185-gener


Шаг 2: Установим sipcalc.

sudo apt install sipcalc -y

Установка MetalLB

Теперь мы установим балансировщик нагрузки MetalLB.

Шаг 1: Устанавливаем необходимое пространство имен Kubernetes.

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

Шаг 2: Устанавливаем MetalLB.

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

Шаг 3: Устанавливаем необходимый секрет Kubernetes.

kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"

Определение диапазона IP-адресов

Целью этого шага является определение диапазона IP-адресов, которые будут служить пулом, из которого MetalLB будет использовать внешний IP-адрес.

Шаг 1: Мы узнаем IP-адреса, используемые нодами в кластере Kubernetes.

kubectl get nodes -o wide

Вы получите результат, аналогичный следующему:

NAME                 STATUS   ROLES    AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                                     KERNEL-VERSION      CONTAINER-RUNTIME
kind-control-plane   Ready    master   11m   v1.19.1   172.19.0.2    <none>        Ubuntu Groovy Gorilla (development branch)   4.4.0-193-generic   containerd://1.4.0
kind-worker          Ready    <none>   11m   v1.19.1   172.19.0.4    <none>        Ubuntu Groovy Gorilla (development branch)   4.4.0-193-generic   containerd://1.4.0
kind-worker2         Ready    <none>   11m   v1.19.1   172.19.0.3    <none>        Ubuntu Groovy Gorilla (development branch)   4.4.0-193-generic   containerd://1.4.0


Шаг 2: Находим CIDR бридж в кластере.

Бесклассовая адресация (англ. Classless Inter-Domain Routing, англ. CIDR) — метод IP-адресации, позволяющий гибко управлять пространством IP-адресов, не используя жёсткие рамки классовой адресации.

ip a s
Вы должны получить что-то по типу:

...
4: br-956cdadd3d33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:8b:33:c3:fb brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.1/16 brd 172.19.255.255 scope global br-956cdadd3d33
       valid_lft forever preferred_lft forever
    inet6 fc00:f853:ccd:e793::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::42:8bff:fe33:c3fb/64 scope link
       valid_lft forever preferred_lft forever
    inet6 fe80::1/64 scope link
       valid_lft forever preferred_lft forever
…

Шаг 3: Мы используем инструмент sipcalc, чтобы найти диапазон IP-адресов, которые может использовать MetalLB.

sipcalc 172.19.0.1/16

Где

172.19.0.1/16 — это CIDR, обнаруженный с помощью ip as s.

-[ipv4 : 172.19.0.1/16] - 0

[CIDR]
Host address            - 172.19.0.1
Host address (decimal)  - 2886926337
Host address (hex)      - AC130001
Network address         - 172.19.0.0
Network mask            - 255.255.0.0
Network mask (bits)     - 16
Network mask (hex)      - FFFF0000
Broadcast address       - 172.19.255.255
Cisco wildcard          - 0.0.255.255
Addresses in network    - 65536
Network range           - 172.19.0.0 - 172.19.255.255
Usable range            - 172.19.0.1 - 172.19.255.254

Создание ConfigMap 

Мы назначаем Kubernetes ConfigMap кластеру Kubernetes.

Нам потребуется создать специальный Kubernetes ConfigMap, потому что балансировщик нагрузки MetalLB использует ConfigMap в качестве механизма поиска. MetalLB проверит ConfigMap, чтобы найти диапазон IP-адресов, которые он может использовать для реализации балансировки нагрузки между балансировщиком нагрузки и составляющими службами. Часть данных конфигурации в ConfigMap, которая интересует MetalLB, называется data.config.addresses.

Шаг 1: Мы пишем файл metallb-config.yaml

nano metallb-config.yaml

Шаг 2: Добавляем следующий конфиг:

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

172.19.255.1-172.19.255.250 — это IP-адреса, определенные на шагах выше.

Обратите внимание, что Вам потребуется ввести диапазон IP-адресов, уникальный для вашего инстанса.

Шаг 3: Сохраняем содержимое и выходим.

Ctrl+O, Ctrl+X

Шаг 4: Мы применяем ConfigMap к кластеру Kubernetes.

kubectl apply -f metallb-config.yaml

Установка приложения Kubernetes

Мы устанавливаем набор веб-серверов nginx в качестве деплоймента Kubernetes, представленного ранее установленным балансировщиком нагрузки MetalLB.

Шаг 1: Создадим деплоймент Kubernetes с 3  репликами.

kubectl create deploy nginx --replicas=3 --image nginx

Шаг 2: Создаем сервис типа LoadBalancer и привязываем его к подам.

kubectl expose deploy nginx --port 80 --type LoadBalancer

Шаг 3: Мы проверяем, что поды были созданы.

kubectl get service

NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1      <none>         443/TCP        12m3s
nginx        LoadBalancer   10.96.203.31   172.19.255.1   80:32168/TCP   14s

Обратите внимание, что служба с именем nginx имеет внешний IP-адрес; в данном случае 172.19.255.1.

Доступ к приложению Kubernetes

Цель состоит в том, чтобы протестировать демонстрационное приложение, работающее в кластере KinD, с помощью его URL-адреса с балансировкой нагрузки.

Мы получим доступ к приложению с помощью curl.

Помните. Для привязки внешнего IP-адреса к базовому развертыванию требуется некоторое время.

Шаг 1: Получаем внешний IP-адрес.

kubectl get services

NAME         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1      <none>         443/TCP        18m
nginx        LoadBalancer   10.96.203.31   172.19.255.1   80:32168/TCP   6m44s

Обратите внимание, что служба с именем nginx имеет внешний IP-адрес; в данном случае 172.19.255.1.

Шаг 2: Вызываем сервис на основе внешнего IP-адреса, присвоенного балансировщиком нагрузки, в данном случае:

curl 172.19.255.1

На выходе вы получите домашнюю страницу nginx в формате HTML, как показано ниже:

Поздравляем! Вы установили балансировщик нагрузки MetalLB в кластер KinD!

В заключение хочу порекомендовать вам бесплатный урок, на котором мои коллеги из OTUS пошагово покажут как написать распределенное и отказоустойчивое in-memory хранилище данных, используя фреймворк Tarantool Cartridge.

Комментарии (2)


  1. dsoastro
    03.02.2023 18:41

    Неплохо бы указать что ноды - это контейнеры, подсоединенные к бриджу на хосте, а external ip находится в приватной сети И извне таким образом до вашего LB не достучаться. И зачем sipcalc,чтобы считать адреса в /16 сети? И зачем metallb для назначения адреса, который можно и так назначить одной командой руками?

    Не уверен, что эта конфа будет работать пока руками не прописать ip адрес от метал лб на каком-нибудь интерфейсе хоста. Проверю на досуге


  1. dsoastro
    03.02.2023 20:12
    +1

    Не ставится по инструкции на свежий кластер kinD. Версия metallb 0.9.4, на которую ссылаются в статье, вышла в октябре 2020. Зачем давать невоспроизводимые сейчас инструкции?