k8s: пересылка из publi c VIP в кластер IP с помощью iptables - PullRequest
1 голос
/ 06 февраля 2020

Я пытаюсь глубоко понять, как работает пересылка от публично выставленных VIP-пользователей уровня 2 балансировщика нагрузки к IP-адресам кластеров служб. Я прочитал общий обзор того, как MetalLB делает это , и я попытался скопировать его вручную, установив keepalived / ucarp VIP и правила iptables. Я должен что-то упустить, однако это не работает; -]

Шаги, которые я предпринял:

  1. создал кластер с kubeadm состоящий из мастера + 3 узла, работающих под управлением k8s-1.17.2 + calico-3.12 на виртуальных машинах libvirt / KVM на одном компьютере. все виртуальные машины находятся в 192.168.122.0/24 виртуальной сети.

  2. создал простое развертывание с двумя модулями и выставил его как сервис NodePort с externalTrafficPolicy, установленным на cluster:
    $ kubectl get svc dump-request NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dump-request NodePort 10.100.234.120 <none> 80:32292/TCP 65s
    Я подтвердил что я могу связаться с ним с хост-машины по IP-адресу каждого узла на порту 32292.

  3. создал VIP с ucarp на всех 3 узлах:
    ucarp -i ens3 -s 192.168.122.21 -k 21 -a 192.168.122.71 -v 71 -x 71 -p dump -z -n -u /usr/local/sbin/vip-up.sh -d /usr/local/sbin/vip-down.sh (пример из knode1)
    Я подтвердил, что могу пинговать 192.168.122.71 VIP. Я даже мог sh пройти через него к виртуальной машине, которая в настоящее время удерживала VIP.
    Теперь, если бы kube-proxy находился в режиме iptables, я мог бы также получить доступ к сервису через его узел-порт через VIP в http://192.168.122.71:32292. Однако, к моему удивлению, в режиме ipvs это всегда приводило к тайм-ауту соединения.

  4. добавило правило iptables на каждом узле для пакетов, входящих на 192.168.122.71, для пересылки на IP-адрес службы * 10.100.234.120:
    iptables -t nat -A PREROUTING -d 192.168.122.71 -j DNAT --to-destination 10.100.234.120
    (позже я также попытался сузить правило только до соответствующего порта, но это никак не изменило результаты:
    iptables -t nat -A PREROUTING -d 192.168.122.71 -p tcp --dport 80 -j DNAT --to-destination 10.100.234.120:80)

Результаты:

в режиме iptables все запросы к http://192.168.122.71:80/ привели к тайм-ауту соединения.

в режиме ipvs он работал частично:
, если 192.168.122.71 VIP удерживался узлом, на котором был установлен модуль, то около 50% запросов выполнялись успешно, и они были всегда подаются местными стручками. приложение также получало реальный удаленный IP-адрес хост-машины (192.168.122.1). остальные 50% (по-видимому, отправленные в модуль на другом пыльнике) истекли.
если VIP удерживался узлом без модулей, тогда все запросы истекали.

Я также проверил, влияет ли это на результаты в любом случае, чтобы правило всегда сохранялось на всех узлах, а не на том, чтобы оно оставалось только на узле, содержащем VIP и удаляющем его при освобождении VIP: результаты были одинаковыми в обоих случаях.

Кто-нибудь знает, почему это не работает и как это исправить? Я буду признателен за помощь в этом:)

1 Ответ

1 голос
/ 07 февраля 2020

также необходимо добавить правило MASQUERADE, чтобы соответственно изменить источник. например:
iptables -t nat -A POSTROUTING -j MASQUERADE

протестировано с ipvs

...