Почему я не могу установить MetalLB на k3s?

Вопрос или проблема

Добрый день, я столкнулся с проблемой, что не могу подключить MetalLB к K3S. У меня есть кластер с 3 мастерами и 3 рабочими узлами.

ИМЯ            СТАТУС   РОЛИ                       ВРЕМЯ    ВЕРСИЯ
master-node-1   Готов    контрольная-плоскость,etcd,мастер   4д2ч   v1.30.5+k3s1
master-node-2   Готов    контрольная-плоскость,etcd,мастер   4д1ч   v1.31.1+k3s1
master-node-3   Готов    контрольная-плоскость,etcd,мастер   4д1ч   v1.31.1+k3s1
worker-node-1   Готов    <нет>                      4д1ч   v1.31.1+k3s1
worker-node-2   Готов    <нет>                      4д     v1.31.1+k3s1
worker-node-3   Готов    <нет>                      4д     v1.31.1+k3s1

Сначала я пытался установить MetalLB таким образом:

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

Конфигурация:

# config.yml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.0.170-192.168.0.180

С этим подходом Load Balancer работал, но он был нестабильным, с 50% вероятностью невозможно было зайти на сайт. Затем я узнал, что это устаревший метод. Я попробовал новый:

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml

Конфигурация:

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: k3s-lb-pool
  namespace: metallb
spec:
  addresses:
  - 192.168.0.170-192.168.0.180
  autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: k3s-lb-pool
  namespace: metallb

Но я получаю ошибку:

Ошибка от сервера (InternalError): ошибка при создании "metalLB-config.yaml": Произошла внутренняя ошибка: не удалось вызвать вебхук "ipaddresspoolvalidationwebhook.metallb.io": не удалось вызвать вебхук: Post "https://metallb-webhook-service.metallb.svc:443/validate-metallb-io-v1beta1-ipaddresspool?timeout=10s": нет доступных конечных точек для службы "metallb-webhook-service"
Ошибка от сервера (InternalError): ошибка при создании "metalLB-config.yaml": Произошла внутренняя ошибка: не удалось вызвать вебхук "l2advertisementvalidationwebhook.metallb.io": не удалось вызвать вебхук: Post "https://metallb-webhook-service.metallb.svc:443/validate-metallb-io-v1beta1-l2advertisement?timeout=10s": нет доступных конечных точек для службы "metallb-webhook-service"

Но пространство имен все еще работает нормально:

root@master-node-1:~# kubectl get pod -n=metallb-system
ИМЯ                          Готов   СТАТУС    ПЕРЕЗАГРУЗЫ        ВРЕМЯ
controller-86f5578878-9ddsr   1/1     Запущен   2 (3м31с назад)   4м57с
speaker-5j47x                 1/1     Запущен   0               4м56с
speaker-6drpd                 1/1     Запущен   0               4м56с
speaker-ccpmq                 1/1     Запущен   0               4м56с
speaker-jfpch                 1/1     Запущен   1 (3м12с назад)   4м56с
speaker-mps8b                 1/1     Запущен   0               4м57с
speaker-t9lx2                 1/1     Запущен   0               4м56с

(Заранее извиняюсь, английский не является моим родным языком)

Добро пожаловать на ServerFault 👋

По умолчанию k3s уже включает LoadBalancer под названием ServiceLB (ранее называвшийся Klipper LoadBalacer). Я подозреваю, что оба работали одновременно, что известно, что вызывает проблемы: одна из них заключается в том, что ваши службы типа LoadBalancer могут быть доступны лишь изредка. Это связано с тем, что как ServiceLB, так и MetalLB по умолчанию используют L2 объявления.

Из-за этого вам нужно будет отключить ServiceLB, если вы хотите использовать MetalLB в сочетании с k3s (как описано в их документации). Если ваш кластер уже работает, вы можете добавить флаг --disable servicelb в файл единицы systemd, расположенный по адресу /etc/systemd/system/k3s.service, вот так:

...
ExecStart=/usr/local/bin/k3s \
server \
    '--server' \
    '...' \
    '--disable' \
    'servicelb' \
    '--disable' \ <-- Вы можете использовать несколько флагов отключения.
    'traefik' \
    '...' \
    'node-role.kubernetes.io/master=true:NoSchedule' \

Вторая проблема, которую вы описали, немного сложнее для меня. Я подозреваю, что вы не ждали достаточно долго перед тем, как попытаться создать IPAddressPool и L2Advertisement, но это лишь предположение, основанное на том факте, что у вашего metallb-webhook-service не кажется, что есть какие-либо конечные точки. Возможно, вы можете поделиться некоторыми логами пода контроллера MetalLB? Но я бы сначала попробовал отключить ServiceLB, а затем переустановить MetalLB.

Ответ или решение

Установка MetalLB на k3s может вызывать проблемы, поскольку по умолчанию в k3s уже встроен собственный балансировщик нагрузки — ServiceLB. Из-за этого могут возникать конфликты между двумя системами, которые обе используют L2-адресацию. Такое сосуществование может приводить к нестабильности и непредсказуемому поведению, например, к тому, что ваши сервисы типа LoadBalancer могут быть доступными только с 50% вероятностью.

Чтобы успешно установить MetalLB, необходимо сначала отключить ServiceLB. Вы можете сделать это, добавив параметр --disable servicelb в файл настроек службы k3s. Вот как это сделать:

  1. Откройте файл службы k3s:

    sudo nano /etc/systemd/system/k3s.service
  2. Найдите строку, начинающуюся с ExecStart=, и добавьте --disable servicelb перед другими ключами. Убедитесь, что вы не забыли добавить пробелы. Например:

    ExecStart=/usr/local/bin/k3s \
    server \
       '--server' \
       '...' \
       '--disable' \
       'servicelb' \
       '--disable' \
       'traefik' \
       '...' \
       'node-role.kubernetes.io/master=true:NoSchedule' \
  3. Сохраните изменения и перезапустите службу k3s:

    sudo systemctl daemon-reload
    sudo systemctl restart k3s

После этого, убедитесь, что ServiceLB отключен, выполнив команду:

kubectl get svc -A

Вы не должны увидеть сервисов типа LoadBalancer, созданных ServiceLB.

Теперь вы можете установить MetalLB. Убедитесь, что вы используете последнюю версию MetalLB, и следуйте инструкциям из официальной документации MetalLB:

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml

Затем создайте необходимые ресурсы (так как у вас уже есть корректный config), используя правил, которые уже упоминались.

Если после этого вы все равно получаете ошибку, связанную с metallb-webhook-service, это может означать, что MetalLB не полностью инициализировался до того, как вы попытались создать объекты IPAddressPool и L2Advertisement. Чтобы проверить состояние MetalLB, выполните команду:

kubectl get pods -n metallb-system

Убедитесь, что все поды работают корректно. Если имеются проблемы, проверьте логи контроллера MetalLB:

kubectl logs -n metallb-system deployment/controller

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

Не забудьте, что если у вас возникнут другие ошибки или нестабильности после внесенных изменений, стоит проверить документацию MetalLB и k3s, а также поискать решения в сообществе, так как проблемы могут варьироваться в зависимости от конфигурации вашего кластера.

Оцените материал
Добавить комментарий

Капча загружается...