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 это будет полезно. Да и нагрузка от роутинга должна быть поменьше (хотя чего нам её снижать, когда у нас мега процы).
Вот и всё. Теперь мы можем переходить к статье о том, какую аппаратную конфигурацию лучше использовать и как проверить, подходит ли наша конфигурация.
Отличная статья по настройке сети. Применил конфигурацию с одним ip на несколько подсетей.
Посмотрим на сколько стабильно будет.
То есть у тебя pointopoint gateway’ing заработал?
Есть сервер с одним белым ip. На нём квм. как сделать чтобы на каждой виртуалке висело по несколько сайтов? мне говорили сделать нат и поставить nginix на аппаратную ноду
@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;
}
Сейчас попробую ))
Сейчас конфиг такой:
######
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
можно ли поднять так ifconfig br0:1 192.168.0.1 netmask 255.255.255.0 up ?
Да, можно, только с натом там уже сами потом думайте)
Спасибо! всё отлично заработало!
Не понятны ни исходные условия, ни что автор хотел в результате добиться. Где этот ваш «шлюзег»? Почему нельзя было обойтись обычным виртуальным мостом с ip-адресом и присоединить к ним tap-ы виртуальных сетевых интерфейсов «дочерних» систем?
На мой взгляд, для лучшего понимания происходящего автору имеет смысл на время отказаться от libvirt и virsh, а освоится с kvm и qemu-monitor.
Исходные условия — развернуть виртуализацию в произвольно взятом ДЦ. В том числе и таком, где приняты варварские меры вида бана за несовпадение IP и мака.
За идею про qemu-momitor спасибо, но я жду кое-какие патчики, которые позволят уйти от обвязок.
Виртуальным мостом с IP адресом нельзя обойтись из-за кучи клевых багов, которые не позволяют использовать такую схему в чужом ДЦ. Да и баг с недоступностью таких серверов друг для друга доставляет.
Не сильно прояснило ситуацию с исходными условиями ;) Может стоит картинками сопроводить. Будет наглядней.
Куча клёвых багов это же всегда интересно. Правда, опять же, непонятно откуда они тут могут грозить.
Автоhe большое спасибо за блог!
По теме:
Выше в комментах поднимался вопрос, а что делать если 1 ip у серва, вы посоветовали на хосте стаавить nginx. А что делать если, на серве с одним ip должны быть установлены полностью автономные (для клиентов) VDS-ки?
Автору большое спасибо за блог!
По теме:
Выше в комментах поднимался вопрос, что делать если 1 ip у серва, вы посоветовали на хосте ставить nginx. Такой вариант больше подходит для своего серва и для своих виртуалок, можно сказать для лучшей изоляции. А что делать если, на серве с одним ip должны быть установлены полностью автономные (для клиентов) VDS-ки? Причем серв у Хетзнеров.
Что значит полностью автономные? Магии не бывает, 80й порт — он один такой. Для ssh пробрасывайте порты через rinetd.
А т.е. это технически по-другому никак? Только через proxy_redirect веб-серва на хосте. Правильно ли я понял?
Сделал всё по мануалу (создал мост, создал интерфейс 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
В нашем тесном мирке принято использовать 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
Как-то так.
Проблема «захвата» соседнего IP так и осталась не решенной, т.к. все ВМ подключены к одному бриджу. Быть может было бы корректней цеплять виртуалке отдельное tap устройство?
С бриджами нет (и не может быть) никаких проблем (ну кроме известного бага с тем, что на br0 мак адрес отличается от eth0, который в данном случае никак не проявляется). С tap устройствами могут быть различные проблемы.
Да и отказываться нужно от любой виртуализации сети. Openvz вон на бриджах выжимает 800 мбит и не чихает. На vnet-ах же оно умирает на 500-600.
Здравствуйте!
Помогите решить вот такую задачу:
Есть Proxmox 2.0 на базе Debian6.
На нем висит десяток виртуальных машин, IP из внутренней подсети (роли не играет). Данный сервер на базе Debian-а должен выступать в роли шлюза. Но в конечном итоге они (вирт. машины) должны соединятся каждый к своему proxy-серверу (которые находятся за пределами локальной сети. К тому же, на этих proxy-серверах есть авторизация.
Буду искренне рад любой помощи!
И где тут задача? NAT никто не отменял. Transparent squid — тоже. Если со сквидом на каждой машине не желаете мучаться — поднимаете на хосте нужное количество transparent и вперед.
Сам 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-у я еще не брался.
Подскажите где и что надо поправить?
Может укажите где можно почитать? Только начинаю с этим делом разбираться.
Все бывает в первый раз :)
Вам с выражением про NAT повторить =) ?
Да нет, наверное. Поищу на Вашем сайте тогда про NAT.
И на этом спасибо!