Debian.pro

Блог для пользователей и администраторов Debian


Debian, KVM, финальные статьи. Настраиваем сеть для KVM. KVM и 2/3+ подсети на одном сервере.

UPDATE: Данную статью можно считать устаревшей для Debian Wheezy и выше. Несмотря на то, что всё описанное здесь в wheezy заработает, я рекомендую использовать более новую статью — «Настройка сети на dom0-машине в debian/ubuntu для KVM, updated.»

Мы уже имеем созданные при помощи LVM логические томы, на которых будем размещать виртуальные машины.

То есть мы подготовили hdd для работы с kvm. Теперь было бы логичным сконфигурировать сеть.
Условия.
1 сетевая карта — eth0.
4 IP адреса из подсети /24 (255.255.255.0) — xx.yy.69.3, xx.yy.69.30, xx.yy.69.31, xx.yy.69.32
Собственную подсеть /28 (255.255.255.240) — xx.yy.135.129-xx.yy.135.142 (.143 — broadcast)
Собственную подсеть /29 (255.255.255.248) — xx.yy.252.153-xx.yy.252.158 (.159 — broadcast)

*здесь и далее «потратить IP» означает использовать IP адрес на хосте (то есть на физическом сервере).
Наша задача — пустить виртуалки в сеть так, чтобы они не догадывались о том, что впереди них есть наш шлюзег, потратив* для сервера только один IP адрес из каждой подсети. Вообще — в конце статьи я покажу файл /etc/network/interfaces, который позволит потратить вообще один IP адрес на все 3 сети. Просто я не тестировал его в «боевых» условиях и не могу ручаться, что та схема ничему не вредит =)
Тем не менее решение вида «потратить 1 IP на всё» есть. Если вы его протестируете — я буду благодарен.
Есть ещё один положительный момент. Если в одной из подсетей вам не нужны виртуалки с одним IP (для примера — всем виртуалкам вы даете IP адреса из /28, и только некоторым из них — добавляете второй IP из /29, то нам не нужно тратить IP адрес из подсети /29. То есть нам не нужно поднимать на хосте виртуальный интерфейс и присуждать ему IP адрес из /29 для того, чтобы виртуалки могли использовать как шлюз).
Уф. Я даже устал уже писать теорию и рассуждения. Надеюсь, вам всё будет понятно из самой статьи. Если будет непонятно — пишите в комментариях или мне на почту, я допишу.

Приступим.
Для начала настроим eth0. Обычно за вас это сделают инженеры ДЦ или саппорт хостера… Но вдруг вы это делаете на домашнем сервере =)
Вы должны самостоятельно выполнить квест. При помощи файла /etc/network/interfaces настроить подключение к сети. Через этот файл вы должны настроить только eth0 (а у нас одна сетевуха, напоминаю). Всё остальное мы будем настраивать/поднимать командами. И скриптом, который напишем в конце.

Подняли eth0. Сервер в сети. Сервер в сети после ребута. Сервер в сети и не отваливается. Ура.

А теперь готовим сеть для KVM.
Поставим нужный для настройки сети пакет:
debian-kvm-net:~# aptitude install bridge-utils
Включим возможности ядра по маршрутизации пакетов:
debian-kvm-net:~# echo 1 > /proc/sys/net/ipv4/ip_forward
Создадим и активируем сетевой мост (br0), к которому в дальнейшем будем цеплять виртуальные интерфейсы сетевых карт:
debian-kvm-net:~# brctl addbr br0 && ifconfig br0 up
Нужен ли вам второй сетевой мост? Он нужен только в том случае, если нам нужно изолировать виртуальные машины друг от друга. Создаете br1 и виртуалку, которую нужно изолировать, аттачите к br1. Они никогда не увидят друг друга по сети. Пока я не придумал, как их соединить. Скорее всего, как то можно. Но мне то их как раз изолировать нужно было ;Р.

Создадим виртуальные сетевые интерфейсы для каждой подсети. IP адреса этих интерфейсов мы будем указывать в качестве шлюза в виртуальных машинах.
eth0 с IP адресом xx.yy.69.3 у вас уже есть. Ну или с .30. Или какой вы там выбрали IP адрес основным для сервера.
Создадим для остальных двух подсетей:
debian-kvm-net:~# ifconfig eth0:1 xx.yy.135.129 netmask 255.255.255.240 up
debian-kvm-net:~# ifconfig eth0:2 xx.yy.252.153 netmask 255.255.255.252 up

Теперь нам нужно отроутить IP адреса для виртуалок на br0. Для примера отроутим несколько:
debian-kvm-net:~# route add -host xx.yy.69.30 dev br0
debian-kvm-net:~# route add -host xx.yy.69.31 dev br0
debian-kvm-net:~# route add -host xx.yy.135.130 dev br0
debian-kvm-net:~# route add -host xx.yy.135.131 dev br0
debian-kvm-net:~# route add -host xx.yy.252.154 dev br0
debian-kvm-net:~# route add -host xx.yy.252.155 dev br0

Остальные сами отроутите. Только не пишите маршруты для тех IP, которые будут у нас шлюзами. Почему я не прописываю route add -net ? Я предпочитаю не отключать виртуалки, когда за них кто то не заплатит, а просто удалять нужный маршрут — тогда на них выключается сеть. Проблем меньше, если пользователь всё же заплатит. А то ныть начинают «ну вооооот, ребуууут был». Если вы желаете сразу все IP отроутить разом, то у man route есть секция -net про которую вы очень будете рады сами почитать.

Вот. Сеть готова. Нам осталось узнать настройки сети для виртуалок.
Для подсети /24 :
IP адрес — один из IP адресов xx.yy.69.{30-32}
netmask — 255.255.255.0
gateway — IP адрес eth0 (xx.yy.69.3)

Для подсети /28 :
IP адрес — один из IP адресов xx.yy.135.{130-142} (для него должен быть создан маршрут (route add))
netmask — 255.255.255.240
gateway — IP адрес eth0:1 (xx.yy.135.129)

Для подсети /29 :
IP адрес — один из IP адресов xx.yy.252.{153-158} (для него должен быть создан маршрут (route add))
netmask — 255.255.255.252
gateway — IP адрес eth0:2 (xx.yy.252.153)

Тэкс. Теперь… Почему я не писал всё это в конфиги. Напишете неправильно конфиг — будет много геморроя после ребута =)) Захотите переделать схему (ну там на openvz перейти или по другому мануалу всё переделать) — надо будет лазить по всем конфигам и вспоминать что писали. А я просто сделаю reboot.
Писать всё это при каждой загрузке — глупо. Создадим скриптик:
debian-kvm-net:~# touch /usr/bin/startup.sh && chmod +x /usr/bin/startup.sh
Его содержимое в соответствии с мануалом выше будет таким:
#!/bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
brctl addbr br0
ifconfig br0 up
ifconfig eth0:1 xx.yy.135.129 netmask 255.255.255.240 up
ifconfig eth0:2 xx.yy.252.153 netmask 255.255.255.252 up
route add -host xx.yy.69.30 dev br0
route add -host xx.yy.69.31 dev br0
route add -host xx.yy.135.130 dev br0
route add -host xx.yy.135.131 dev br0
route add -host xx.yy.252.154 dev br0
route add -host xx.yy.252.155 dev br0

И в /etc/rc.local дописываем строку
startup.sh
перед exit0
Или не дописываем. А просто после ребута выполняем команду startup.sh
Я не дописываю. В лом.

А теперь обещанная вкусность.
Вот так должен выглядеть файл /etc/network/interfaces у виртуальной машины, если мы желаем дать ей IP адрес xx.yy.135.142, но использовать для неё шлюзом IP адрес интерфейса eth0 (в нашем случае — xx.yy.69.3). Это позволит не создавать нам eth0:1 и eth0:2 и тратить на них IP адреса.
vds01:~# cat /etc/network/interfaces

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
# IP адрес из второй подсети
address xx.yy.135.142
# IP адрес интерфейса eth0 самого сервера
gateway xx.yy.69.3
# странная маска подсети с 255 на конце
netmask 255.255.255.255
# очень важная строчка. совпадает с gateway
pointopoint xx.yy.69.3

В чём проблема с таким конфигом? А вы его не создадите ни из одного инсталлятора (ну ок, кроме гентушного и подобных). И установка по сети будет возможна только с LiveCD. С полноценного LiveCD. А это не всегда удобно. Вообще — должно работать. Но я не тестировал.

В каком то буржуйском мануале (о май гад, сколько же их было… и сколько из них были «битыми») я вычитал 3 вот таких команды:
vds01:~# echo 1 > /proc/sys/net/ipv4/conf/default/proxy_arp
vds01:~# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
vds01:~# echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

Якобы, они делают что-то хорошее. Нет, ну для xen’a то это супер. А вот я ограничивать клиентов в возможностях не люблю. Для обычных же VDS это будет полезно. Да и нагрузка от роутинга должна быть поменьше (хотя чего нам её снижать, когда у нас мега процы).

Вот и всё. Теперь мы можем переходить к статье о том, какую аппаратную конфигурацию лучше использовать и как проверить, подходит ли наша конфигурация.


Комментарии (25):

  1. Отличная статья по настройке сети. Применил конфигурацию с одним ip на несколько подсетей.
    Посмотрим на сколько стабильно будет.

  2. То есть у тебя pointopoint gateway’ing заработал?

  3. Есть сервер с одним белым ip. На нём квм. как сделать чтобы на каждой виртуалке висело по несколько сайтов? мне говорили сделать нат и поставить nginix на аппаратную ноду

  4. @Neznae4ko
    Делай всё так же, как написано в статье. Только на хосте сделай:
    ifconfig eth0:1 192.168.0.1 netmask 255.255.255.0 up
    http://debian.pro/249 — как здесь написано, подними NAT для интерфейса eth0:1 (и eth0, на всякий случай).
    Виртуалки создавай с IP адресами вида 192.168.0.x.

    Ну и на хосте поднимай nginx, ему в конфиг для каждого сайта пиши что-то вроде:
    location / {
    proxy_pass http://192.168.0.2;
    proxy_redirect http://debian.pro/ /;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    }

  5. Сейчас попробую ))

  6. Сейчас конфиг такой:
    ######
    auto lo
    iface lo inet loopback

    auto eth2
    iface eth2 inet manual
    auto br0
    #iface br0 inet dhcp
    iface br0 inet static
    address 195.xxx.yy.218
    netmask 255.255.255.252
    network 195.206.yy.216
    broadcast 195.xxx.58.255
    gateway 195.xxx.yy.217
    bridge_ports eth2
    bridge_fd 9
    bridge_hello 2
    bridge_maxage 12
    bridge_stp off
    ######
    Мост делали чтобы повешать на него виртуалки, но оказалось, что других айпишников нам не светит. Вобщем, eth0:1 и мост страшно трогать. Вдруг не поднимется потом ssh.

    Помимо Этого в системе есть ещё два подозрительныз интерфейса.

    virbr0 Link encap:Ethernet HWaddr 66:b5:2e:f1:69:8f
    inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    TX packets:30 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:0 (0.0 B) TX bytes:4172 (4.1 KB)

    vnet0 Link encap:Ethernet HWaddr fe:54:00:ba:87:54
    inet6 addr: fe80::fc54:ff:feba:8754/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:453 errors:0 dropped:0 overruns:0 frame:0
    TX packets:868 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:500
    RX bytes:38334 (38.3 KB) TX bytes:57360 (57.3 KB)

    В виртуалке я поднимал сеть 192.168.122.2 Bcast:192.168.122.255 Mask:255.255.255.0 , но он не видет 192.168.122.1

  7. можно ли поднять так ifconfig br0:1 192.168.0.1 netmask 255.255.255.0 up ?

  8. inkvizitor68sl :

    Да, можно, только с натом там уже сами потом думайте)

  9. Спасибо! всё отлично заработало!

  10. Кирилл :

    Не понятны ни исходные условия, ни что автор хотел в результате добиться. Где этот ваш «шлюзег»? Почему нельзя было обойтись обычным виртуальным мостом с ip-адресом и присоединить к ним tap-ы виртуальных сетевых интерфейсов «дочерних» систем?
    На мой взгляд, для лучшего понимания происходящего автору имеет смысл на время отказаться от libvirt и virsh, а освоится с kvm и qemu-monitor.

  11. Исходные условия — развернуть виртуализацию в произвольно взятом ДЦ. В том числе и таком, где приняты варварские меры вида бана за несовпадение IP и мака.

    За идею про qemu-momitor спасибо, но я жду кое-какие патчики, которые позволят уйти от обвязок.

    Виртуальным мостом с IP адресом нельзя обойтись из-за кучи клевых багов, которые не позволяют использовать такую схему в чужом ДЦ. Да и баг с недоступностью таких серверов друг для друга доставляет.

  12. Кирилл :

    Не сильно прояснило ситуацию с исходными условиями ;) Может стоит картинками сопроводить. Будет наглядней.
    Куча клёвых багов это же всегда интересно. Правда, опять же, непонятно откуда они тут могут грозить.

  13. Олег :

    Автоhe большое спасибо за блог!
    По теме:
    Выше в комментах поднимался вопрос, а что делать если 1 ip у серва, вы посоветовали на хосте стаавить nginx. А что делать если, на серве с одним ip должны быть установлены полностью автономные (для клиентов) VDS-ки?

  14. Олег :

    Автору большое спасибо за блог!
    По теме:
    Выше в комментах поднимался вопрос, что делать если 1 ip у серва, вы посоветовали на хосте ставить nginx. Такой вариант больше подходит для своего серва и для своих виртуалок, можно сказать для лучшей изоляции. А что делать если, на серве с одним ip должны быть установлены полностью автономные (для клиентов) VDS-ки? Причем серв у Хетзнеров.

  15. Что значит полностью автономные? Магии не бывает, 80й порт — он один такой. Для ssh пробрасывайте порты через rinetd.

  16. Олег :

    А т.е. это технически по-другому никак? Только через proxy_redirect веб-серва на хосте. Правильно ли я понял?

  17. Андрей :

    Сделал всё по мануалу (создал мост, создал интерфейс eth0:1). Получается, что для каждой подсети будет выделен интерфейс eth0:n в качестве шлюза. Тогда подскажите, каким образом запустить гостевую систему? Я так понимаю, надо указывать для неё адаптер eth0:n ?

    Обычно запускаю вот так:
    kvm -m 512 /var/virt/debian_3.0.4_orig.img -net nic,macaddr=00:11:22:33:44:55 -net tap -daemonize -vnc :1

  18. В нашем тесном мирке принято использовать virt-install и virsh.
    virt-install —connect qemu:///system -n vm1 -r 512 —vcpus=2 —disk path=/dev/vg0/vm1 -c ~/debian-amd64-netinst.iso —vnc —noautoconsole —os-type linux —os-variant debianLenny —accelerate —network=bridge:br0 —hvm
    Как-то так.

  19. Boris :

    Проблема «захвата» соседнего IP так и осталась не решенной, т.к. все ВМ подключены к одному бриджу. Быть может было бы корректней цеплять виртуалке отдельное tap устройство?

  20. С бриджами нет (и не может быть) никаких проблем (ну кроме известного бага с тем, что на br0 мак адрес отличается от eth0, который в данном случае никак не проявляется). С tap устройствами могут быть различные проблемы.
    Да и отказываться нужно от любой виртуализации сети. Openvz вон на бриджах выжимает 800 мбит и не чихает. На vnet-ах же оно умирает на 500-600.

  21. hotey :

    Здравствуйте!
    Помогите решить вот такую задачу:
    Есть Proxmox 2.0 на базе Debian6.
    На нем висит десяток виртуальных машин, IP из внутренней подсети (роли не играет). Данный сервер на базе Debian-а должен выступать в роли шлюза. Но в конечном итоге они (вирт. машины) должны соединятся каждый к своему proxy-серверу (которые находятся за пределами локальной сети. К тому же, на этих proxy-серверах есть авторизация.
    Буду искренне рад любой помощи!

  22. И где тут задача? NAT никто не отменял. Transparent squid — тоже. Если со сквидом на каждой машине не желаете мучаться — поднимаете на хосте нужное количество transparent и вперед.

  23. hotey :

    Сам Proxmox создает виртуальный интерфейс vmbr0. Шлюз для него — *.*.*.185.
    Я цепляю ему еще ifconfig wmbr0:1 192.168.1.1 netmask 255.255.255.0 up.
    Виртуалка с IP — 192.168.1.2 видит свой шлюз (192.168.1.1), и даже IP-proxmox-server *.*.*.190.
    Но до шлюза *.*.*.185 достучатся не может.
    По этому и к squid-у я еще не брался.
    Подскажите где и что надо поправить?
    Может укажите где можно почитать? Только начинаю с этим делом разбираться.
    Все бывает в первый раз :)

  24. Вам с выражением про NAT повторить =) ?

  25. hotey :

    Да нет, наверное. Поищу на Вашем сайте тогда про NAT.
    И на этом спасибо!

Написать комментарий