Вопрос или проблема
Добрый день, я столкнулся с проблемой, что не могу подключить 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. Вот как это сделать:
-
Откройте файл службы k3s:
sudo nano /etc/systemd/system/k3s.service
-
Найдите строку, начинающуюся с
ExecStart=
, и добавьте--disable servicelb
перед другими ключами. Убедитесь, что вы не забыли добавить пробелы. Например:ExecStart=/usr/local/bin/k3s \ server \ '--server' \ '...' \ '--disable' \ 'servicelb' \ '--disable' \ 'traefik' \ '...' \ 'node-role.kubernetes.io/master=true:NoSchedule' \
-
Сохраните изменения и перезапустите службу 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, а также поискать решения в сообществе, так как проблемы могут варьироваться в зависимости от конфигурации вашего кластера.