На Centos 7.4 я настраиваю рой, в котором я хочу запустить несколько маршрутизаторов, все доступные на порте 80/443 .
Цель состоит в том, чтобы разместить несколько сред (тестовых / промежуточных ...) в одном рое, все симметрично.
Я использую Docker 17.12.0-ce и Traefik v1.4.6 в качестве маршрутизатора.
Основная идея состоит в том, чтобы иметь виртуальный IP-адрес для каждой среды и публиковать порты Traefik только на этом адресе. Это невозможно с Docker Swarm, поэтому мне приходится прибегать к тому, чтобы экземпляры Traefik прослушивали порты 81/82 и т. Д. И каким-то образом переносили трафик с VIP: 80 на: 81 /: 82.
Виртуальные IP-адреса для всех сред через менеджеры роя обрабатываются Keepalived.
Соответствующая конфигурация службы докеров для Traefik:
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 80,
"PublishedPort": 81,
"PublishMode": "ingress"
},
# netstat -anp|grep 81
tcp6 7 0 :::81 :::* LISTEN 4578/dockerd
firewalld настроен на разрешение трафика на порты 80, 81, 82 и т. Д.
Доступ к серверным службам, предоставляемым Traefik, непосредственно через порт 81 на VIP работает.
Другой трафик не прошел, и время ожидания запроса на стороне клиента в конечном итоге истекло.
ipvsadm зарегистрировал соединение как активное.
Если я настрою HAProxy для прослушивания VIP: 80 и проксирования запросов через HTTP на 127.0.0.1:81, все будет работать, но я бы хотел избежать этого, поскольку он требует, чтобы все данные проходили через HAProxy, тратя впустую ресурсы даром и требуют локальной настройки.
У меня нет идей, и я не знаю, как дальше устранять неполадки.
ИЗМЕНИТЬ для уточнения. Мой вопрос:
Можно ли перенаправить трафик с VIP: 80 на: 81 /: 82 и т. Д. Без использования HAProxy или другого процесса, который просто перекачивал бы данные на настоящий маршрутизатор (Traefik)?
Во-первых, вы можете использовать несколько IP-адресов на хост, если у вас есть возможность добавлять IP-адреса в реальной сети. Этот действительно работает в Swarm под Linux. См. macvlan docs и поиск в Google для "macvlan swarm".
2-й, вы используете оверлей и входную сеть роя, верно?
3-й, большинство людей просто помещают Traefik (или мой fav ] http://proxy.dockerflow.com ) для прослушивания 80/443 и перенаправления на соответствующую службу / стек в Swarm на основе заголовка хоста. Как спросил Флорин, почему вы не пробуете это?
Нам нужно было опубликовать отдельные сервисы docker swarm на одних и тех же портах, но на разных конкретных IP-адресах. Вот как мы это сделали.
Docker добавляет правила в цепочку DOCKER-INGRESS таблицы nat для каждого опубликованного порта. Добавляемые правила не зависят от IP, поэтому обычно любой опубликованный порт будет доступен для всех IP-адресов хоста. Вот пример правила, которое Docker добавит для службы, опубликованной на порту 80:
iptables -t nat -A DOCKER-INGRESS -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.18.0.2 :80
(Вы можете просмотреть их, запустив iptables-save -t nat | grep DOCKER-INGRESS
).
Наше решение состоит в том, чтобы публиковать наши сервисы на разных портах и использовать скрипт, который перехватывает команды iptables dockerd, чтобы переписать их, чтобы они соответствовали правильной паре IP-адреса и общедоступного порта.
Например:
Затем мы соответствующим образом настраиваем наш скрипт:
# cat /usr/local/sbin/iptables
#!/bin/bash
REGEX_INGRESS="^(.*DOCKER-INGRESS -p tcp) (--dport [0-9]+) (-j DNAT --to-destination .*)"
IPTABLES=/usr/sbin/iptables
SRV_1_IP=1.2.3.4
SRV_2_IP=1.2.3.5
ipt() {
echo "EXECUTING: $@" >>/tmp/iptables.log
$IPTABLES "$@"
}
if [[ "$*" =~ $REGEX_INGRESS ]]; then
START=${BASH_REMATCH[1]}
PORT=${BASH_REMATCH[2]}
END=${BASH_REMATCH[3]}
echo "REQUESTED: $@" >>/tmp/iptables.log
case "$PORT" in
'--dport 1080') ipt $START --dport 80 -d $SRV_1_IP $END; exit $?; ;;
'--dport 2080') ipt $START --dport 80 -d $SRV_2_IP $END; exit $?; ;;
*) ipt "$@"; exit $?; ;;
esac
fi
echo "PASSING-THROUGH: $@" >>/tmp/iptables.log
$IPTABLES "$@"
NB Сценарий должен быть установлен в PATH dockerd перед командой iptables вашего дистрибутива. В Debian Buster iptables устанавливается в /usr/sbin/iptables
, а PATH dockerd имеет /usr/local/sbin
перед /usr/sbin
, поэтому имеет смысл установить скрипт в /usr/local/sbin/iptables
. (Вы можете проверить PATH dockerd, запустив cat /proc/$(pgrep dockerd)/environ | tr '\0' '\012' | grep ^PATH
).
Теперь при запуске этих docker-сервисов правила iptables будут переписаны следующим образом:
iptables -t nat -A DOCKER-INGRESS -d 1.2.3.4/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.18.0.2:1080
iptables -t nat -A DOCKER-INGRESS -d 1.2.3.5/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.18.0.2:2080
В результате запросы на http://1.2.3.4/ идут к сервису №1, а запросы на http://1.2.3.5/ идут к сервису №2.
Сценарий можно настроить и расширить в соответствии с вашими потребностями. Он должен быть установлен на всех узлах, на которые вы будете направлять запросы, и настроен на общедоступные IP-адреса этого узла.