Docker swarm проблемы с сетью macvlan

Цель


Запустите один контейнер haproxy в рое со статическим IP-адресом в моей локальной сети, который будет воссоздан в случае сбоя узла. По сути, это было бы похоже на VIP, указывающий на haproxy, но не требующий внешнего балансировщика нагрузки за пределами роя.


Что работает - локальный macvlan

Пример: создание сетей macvlan на двух узлах, запуск контейнера на узле1, остановка контейнера, затем запуск контейнера на узле2. Контейнер haproxy создается с тем же статическим IP-адресом и доступен в локальной сети.

Что не работает - роем маквлан

Пример: установка области сети macvlan на swarm, затем развертывание стека. Контейнер не виден в сети.


Файлы, используемые в примере

докер-compose.yml:

version: "3.2"
networks:
  vlan0:
    external: true
services:
  haproxy:
    image: haproxy:2.3.2-alpine
    container_name: haproxy
    volumes:
      - ./data:/usr/local/etc/haproxy:ro
    environment:
      - TZ=America/Los_Angeles
    restart: always
    networks:
      vlan0:
        ipv4_address: 192.168.0.201

localnet.sh (скрипт для остановки стека/удаления сети/воссоздания сети как локальной/запуска локального контейнера):

#!/bin/bash
docker service rm haproxy_haproxy
docker-compose down
docker network rm vlan0
docker network create -o parent=eth0 --subnet 192.168.0.0/24 --gateway 192.168.0.1 --driver macvlan --scope local vlan0
docker-compose up

swarmnet.sh (скрипт для удаления контейнера и сети/воссоздания сети как роя/запуска как стека роя):

#!/bin/bash
docker service rm haproxy_haproxy
docker-compose down
docker network rm vlan0
docker network create -o parent=eth0 --subnet 192.168.0.0/24 --gateway 192.168.0.1 --driver macvlan --scope swarm vlan0
docker stack deploy -c docker-compose.yml haproxy

Можно ли запустить один контейнер со статическим IP-адресом macvlan в режиме роя?

Любая помощь приветствуется.

Обновлено: мне удалось заставить работать адреса macvlan, но рой докеров не подчиняется полю ipv4_address для статического контейнера. Я понимаю причину этого (реплики и т. д. не идут по одному и тому же IP-адресу), но в этом сценарии этого не произойдет, поскольку это один контейнер. Я нашел здесь обсуждение этой проблемы: https://forums.docker.com/t/docker-swarm-1-13-static-ips-for-containers/28060/

похоже, это возможно. пожалуйста, проверьте эти чернила collabnix.com/docker-17-06-swarm-mode-now-with-macvlan-suppo‌​rt

Vivek Bani 10.12.2020 18:46

Я посмотрел на это, но рой не подчиняется моему полю ipv4_address в файле docker-compose, поэтому контейнер динамический, а не статичный.

R. StackUser 10.12.2020 19:57
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
2
2
2 316
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я понял, как привязать один статический IP-адрес (с большой оговоркой ниже).

Метод

Для этого создайте сеть только для конфигурации на каждом хосте с одним диапазоном IP-адресов (32-битная маска). Я создал здесь скрипт для автоматической генерации команд.

    #!/bin/bash 
    echo 
    echo VIP swarm command generator
    echo 
    defint=$(ip route get 8.8.8.8 | head -n1 | awk '{print $5}')
    hostip=$(ip addr show dev $defint | grep "inet" | awk 'NR==1{print $2}' | cut -d'/' -f 1)
    hostsub=$(ip route | grep "src $hostip" | awk '{print $1}')
    hostgate=$(ip route show | grep default | awk '{print $3}')
    read -p "Subnet (default "$hostsub"): " sub
    sub=${sub:=$hostsub}
    read -p 'Gateway (default '$hostgate'): ' gate
    gate=${gate:=$hostgate}
    read -p 'Vip address: ' ip
    last=`echo $ip | cut -d . -f 4`
    begin=`echo $ip | cut -d"." -f1-3`
    read -p 'Ethernet interface (default '$defint'): ' eth
    eth=${eth:=$defint}
    read -p 'Docker Network Name: (default vip-'$last'): ' name
    name=${name: = "vip-"$last}
    echo -e "Build the network on each node, \033[0;33mmake sure the physical parent interface (parent=) is set properly on each node if different)\033[0m:"
    echo -e "        \033[44mdocker network create --config-only --subnet $sub --gateway $gate --ip-range $ip/32 -o parent=$eth $name\033[0m"
    echo
    echo "Then create the swarm network from any manager node:"
    echo -e "        \033[44mdocker network create -d macvlan --scope swarm --config-from $name swarm-$name\033[0m"

Пример вывода:


VIP swarm command generator

Subnet (default 192.168.0.0/24):
Gateway (default 192.168.0.1):
Vip address: 192.168.0.201
Ethernet interface (default eth0):
Docker Network Name: (default vip-201):
Build the network on each node, make sure the physical parent interface (parent=) is set properly on each node if different):
        docker network create --config-only --subnet 192.168.0.0/24 --gateway 192.168.0.1 --ip-range 192.168.0.201/32 -o parent=eth0 vip-201

Then create the swarm network from any manager node:
        docker network create -d macvlan --scope swarm --config-from vip-201 swarm-vip-201

Итак, на каждом узле я строю конфиг сети

docker network create --config-only --subnet 192.168.0.0/24 --gateway 192.168.0.1 --ip-range 192.168.0.201/32 -o parent=eth0 vip-201

Затем я создаю интерфейс роя

docker network create -d macvlan --scope swarm --config-from vip-201 swarm-vip-201

И в соответствующий файл docker-compose.yaml добавьте соответствующие строки:

networks:
  swarm-vip-201:
    external: true
services:
  haproxy:
    ...
    networks:
      swarm-vip-201:

Полученные результаты

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

Предостережение (ошибка Swarm macvlan?)

Docker swarm будет выдавать ошибки при попытке привязать несколько macvlan к одному и тому же родительскому интерфейсу, как показано ниже:

"network NETNAME is already using parent interface eth0"

Описано здесь:

https://github.com/moby/libnetwork/issues/2384

https://github.com/moby/libnetwork/issues/1743

Заключение

Многообещающе, что на самом деле можно создать статический macvlan IP в рое, но пока не будет исправлена ​​ошибка с привязкой нескольких сетей к одному родительскому интерфейсу, это очень ограничено.

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

Другие вопросы по теме