Rede em ponte KVM que não funciona

20

Acabei de instalar o KVM no meu servidor Ubuntu de acordo com este guia: link

Em seguida, preparou uma rede com ponte, conforme mostrado aqui: link

Em seguida, criei uma máquina virtual com o virt-manager. Eu tentei várias vezes, mas o convidado não consegue se conectar à rede! Alguma ajuda?

ifconfig:

      br0       Link encap:Ethernet  HWaddr d0:27:88:b0:e4:38  
                inet addr:192.168.20.100  Bcast:192.168.20.255  Mask:255.255.255.0
                inet6 addr: fe80::d227:88ff:feb0:e438/64 Scope:Link
                UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                RX packets:62 errors:0 dropped:0 overruns:0 frame:0
                TX packets:62 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:0 
                RX bytes:10493 (10.4 KB)  TX bytes:8433 (8.4 KB)

      eth0      Link encap:Ethernet  HWaddr d0:27:88:b0:e4:38  
                UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                RX packets:62 errors:0 dropped:0 overruns:0 frame:0
                TX packets:63 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:1000 
                RX bytes:11361 (11.3 KB)  TX bytes:8479 (8.4 KB)
                Interrupt:41 

      lo        Link encap:Local Loopback  
                inet addr:127.0.0.1  Mask:255.0.0.0
                inet6 addr: ::1/128 Scope:Host
                UP LOOPBACK RUNNING  MTU:16436  Metric:1
                RX packets:0 errors:0 dropped:0 overruns:0 frame:0
                TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:0 
                RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

      virbr0    Link encap:Ethernet  HWaddr 5a:8c:57:95:af:3b  
                inet addr:192.168.122.1  Bcast:192.168.122.255  Mask:255.255.255.0
                UP BROADCAST MULTICAST  MTU:1500  Metric:1
                RX packets:0 errors:0 dropped:0 overruns:0 frame:0
                TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:0 
                RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

mostra brctl:

 bridge name    bridge id      STP enabled    interfaces
 br0       8000.d02788b0e438   no        eth0
 virbr0         8000.000000000000   yes  

brctl showmacs br0:

 port no   mac addr       is local? ageing timer
   1  5c:d9:98:67:b6:28   no          48.33
   1  d0:27:88:b0:e4:38   yes          0.00
   1  e0:2a:82:f9:6c:09   no           0.00

rota ip:

 default via 192.168.20.1 dev br0  metric 100 
 192.168.20.0/24 dev br0  proto kernel  scope link  src 192.168.20.100 
 192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1

* No convidado * não consegui copiar e colar as informações do convidado porque não posso ssh para ele. Não obteve nenhum ip do DHCP. Não funciona mesmo depois de configurá-lo manualmente.

    
por THpubs 23.08.2012 / 18:56

3 respostas

18

Preliminares

Este seguinte funcionou para mim para o Ubuntu 12.04. Você deve desativar o firewall do seu computador enquanto testa isso para que ele não interfira.

O arquivo / etc / default / qemu-kvm deve ser originalmente instalado.

Você precisará ter bridge-utils qemu -kvm e libvirt-bin instalado. Todos os usuários que usam máquinas virtuais devem ser adicionados ao grupo libvirtd.

Não parece mais haver necessidade de adicionar o recurso CAP_NET_ADMIN.

Configuração da Rede

O modo de rede padrão é o modo de usuário, também chamado de SLIRP. Ele usa uma ponte virbr0 predefinida que é roteada para o computador convidado. O roteamento NAT usa o recurso ip_forwarding do kernel e iptables . O modo de ponte usa uma ponte virtual no convidado ao qual a interface Ethernet (não numerada) se conecta e na qual o host e o convidado têm suas interfaces de rede.

Os seguintes diagramas podem tornar as diferenças mais claras:

Você pode ver como a rede do usuário padrão é definida com:

virsh net-dumpxml default

Eu posso configurar o modo de ponte com as seguintes abordagens:

Em / etc / network / interfaces (da parte da postagem que você mencionou na sua pergunta):

auto lo
iface lo inet loopback
#auto eth0
#iface eth0 inet dhcp
auto eth0
iface eth0 inet manual
auto br0
iface br0 inet dhcp
    bridge_ports eth0
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0

Reinicie; e certifique-se de que a rede sem fio não esteja ativa. Verifique a rota IP padrão com ip route . Deve estar usando a interface br0.

N.B. Se a sua rede Ethernet não estiver conectada quando essa alteração for feita, você precisará ter o cabo Ethernet conectado e obter uma portadora ou a inicialização travará por dois minutos e você não terá capacidade de rede Isso porque a eth0 interface, por estar neste arquivo, deve aparecer antes que a inicialização possa prosseguir normalmente.

N.B. Geralmente você não pode usar uma rede sem fio em vez de eth0 por causa de sua incapacidade de usar múltiplos endereços MAC (eu deduzo que eles precisam de um segundo para a ponte).

Como alternativa, você pode desativar o uso da Ethernet e certificar-se de que ela não tenha um endereço IP e que não haja uma rota padrão configurada com ip route . Então:

 sudo ifconfig eth0 0.0.0.0 up
 sudo brctl addbr br0
 sudo brctl addif br0 eth0
 sudo ifconfig br0 up
 sudo dhclient br0 &

Você também pode fornecer um endereço IP estático aqui, além de definir a rota padrão e o endereço DNS. Para este exemplo, dhclient faz isso.

Aqui está minha tabela de rotas:

$ip route list
default via 192.168.1.1 dev br0  metric 100 
169.254.0.0/16 dev br0  scope link  metric 1000 
192.168.1.0/24 dev br0  proto kernel  scope link  src 192.168.1.45 
192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1

Usando o kvm

Eu posso inicializar uma máquina kvm em ponte com:

 $ sudo kvm -name Quantal -m 1024 -hda foo.qcow2 --soundhw ac97 -device virtio-net,netdev=tunnel -netdev tap,id=tunnel,ifname=vnet0

O parâmetro -netdev tap torna o sudo um requisito. Quando a VM é iniciada, o qemu-kvm executa os seguintes comandos:

ifconfig vnet0 0.0.0.0 up
brctl addif brctl addif br0 vnet0

Isso é feito por / etc / qemu-ifup

A interface vnet0 do vm é adicionada à ponte br0 porque a rota padrão acima usa essa interface de ponte. Se não estivesse lá, a interface de toque seria adicionada à interface do virbr0. Como isso não está conectado à Internet, o NAT seria usado para conectar o convidado ao host e à Internet, nos meus experimentos. Você pode direcionar o vnet0 para uma ponte específica em / etc / default / qemu-kvm. Usando o virt-manager abaixo, você pode direcionar explicitamente a qual bridge se conectar.

Devido aos comandos acima emitidos pelo qemu-kvm e ao parâmetro -netdev tap,id=tunnel,ifname=vnet0 , a máquina virtual vm está conectada ao túnel vnet0 e o túnel está conectado à ponte br0.

Agora posso ssh diretamente para este convidado vm de outro computador na minha rede.

Meu host ifconfig (observe a interface vnet0 que aparece na minha rede quando a VM está em execução):

$ifconfig
br0       Link encap:Ethernet  HWaddr 00:1e:33:88:07:e5  
          inet addr:192.168.1.45  Bcast:255.255.255.255  Mask:255.255.255.0
          inet6 addr: fe80::21e:33ff:fe88:7e5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6526 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7543 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2712940 (2.7 MB)  TX bytes:1071835 (1.0 MB)

eth0      Link encap:Ethernet  HWaddr 00:1e:33:88:07:e5  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:7181 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7740 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2974585 (2.9 MB)  TX bytes:1096580 (1.0 MB)
          Interrupt:43 Base address:0x6000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:664 (664.0 B)  TX bytes:664 (664.0 B)

vnet0      Link encap:Ethernet  HWaddr ca:0c:73:c3:bc:45  
          inet6 addr: fe80::c80c:73ff:fec3:bc45/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:226 errors:0 dropped:0 overruns:0 frame:0
          TX packets:429 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:26919 (26.9 KB)  TX bytes:58929 (58.9 KB)

virbr0    Link encap:Ethernet  HWaddr d6:18:22:db:ff:93  
          inet addr:192.168.122.1  Bcast:192.168.122.255  Mask:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Minha configuração de ponte durante a execução da VM:

$brctl show
bridge name bridge id       STP enabled interfaces
br0             8000.001e338807e5       no              eth0
                                                        vnet0
virbr0          8000.000000000000       yes

Observe que a interface vnet0 da máquina virtual e a interface eth0 estão conectadas à ponte br0.

E o MAC está na interface br0:

$brctl showmacs br0
port no mac addr        is local?   ageing timer
  1 00:05:5d:cf:64:61   no         2.54
  1 00:19:d2:42:5d:3f   no        36.76
  1 00:19:df:da:af:7c   no         2.86
  1 00:1e:33:88:07:e5   yes        0.00
  1 00:60:0f:e4:17:d6   no         0.79
  2 52:54:00:12:34:56   no         0.80
  1 58:6d:8f:17:5b:c0   no         5.91
  1 c8:aa:21:be:8d:16   no       167.69
  2 ca:0c:73:c3:bc:45   yes        0.00

Observe que a interface br0 conecta meu computador host à mesma ponte que está sendo usada pelo convidado.

Você pode verificar se você está em ponte em vez de NAT roteado para sua própria rede usando traceroute 8.8.8.8 . Se o primeiro nó for o roteador de sua rede em vez do endereço IP do convidado, sua rede deve estar funcionando corretamente.

Veja esta documentação .

virt-manager

Verifique se você instalou virt-manager e hal . O pacote hal é uma dependência sugerida para virt-manager e é usado para determinar a configuração de rede de seu sistema ao criar ou editar convidados.

Apesar de ter a ponte br0 definida acima, criei uma máquina virtual com virt-manager da seguinte forma:

Consegui ir diretamente para o resto da minha rede doméstica e para a Internet a partir deste convidado. Eu também era capaz de usar o SSH do outro computador Ubuntu (não-host, não-guest) na minha rede doméstica.

Aqui está o comando muito longo kvm executado pelo virt-manager (para comparação com EApubs ou qualquer outra pessoa que tenha problemas com isso):

/usr/bin/kvm -S -M pc-1.0 -enable-kvm -m 1024 -smp 1,sockets=1,cores=1,threads=1 -name precise -uuid f057a729-eda6-4b85-84dc-f100c9ae3789 -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/precise.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -drive file=/media/natty/home/gruber/ubuntu-kvm/tmpW8gSGB.qcow2,if=none,id=drive-ide0-0-0,format=qcow2 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 -netdev tap,fd=18,id=hostnet0 -device rtl8139,netdev=hostnet0,id=net0,mac=52:54:00:0e:da:9b,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -usb -vnc 127.0.0.1:0 -vga cirrus -device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5

Aqui está a parte da rede da descrição da máquina virtual em /etc/libvirt/qemu/quantal.xml

    <interface type='bridge'>
      <mac address='52:54:00:b0:8e:aa'/>
      <source bridge='br0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>

De acordo com este link, para desempenho e confiabilidade, pode ser melhor defina o modelo de dispositivo de rede como virtio , você pode fazer isso no virt-viewer pressionando o botão i , indo para a configuração da NIC e configurando o "Device model" para virtio . Você também pode adicionar isso ao xml acima, adicionando a linha:

      <model type='virtio'/>

Em resumo

Tudo isso aconteceu em 12.04:

  1. Instalando o virt-manager, o bridge-utils, o qemu-kvm e os pacotes relacionados
  2. Certifique-se de que cada usuário que deseje usar o kvm esteja no grupo libvirtd.
  3. Definindo / etc / network / interfaces como acima (que corresponde ao artigo citado)
  4. Reinicialize, certificando-se de que a Ethernet esteja conectada e sem fio (se houver) desativada.
  5. Execute kvm em uma imagem diretamente com, por exemplo, -device e1000,netdev=tunnel -netdev tap,id=tunnel,ifname=vnet0 , ou crie uma máquina virtual com o virt-manager, especificando a ponte de rede br0 sob o painel Opções Avançadas da Etapa 4 & gt;

Nenhuma alteração adicional foi necessária para redes, recursos, modelos ou configurações.

Para expor um serviço em seu novo convidado à Internet, você deve:

  1. Prepare e configure qualquer serviço de firewall que você precisará.
  2. Atribua um endereço estático à sua configuração de convidado ou ao seu serviço DHCP.
  3. Se você estiver usando um roteador NAT, abra uma porta para o serviço que está implementando, direcionando-o para o endereço IP do convidado.

Lembre-se de testar e reativar o serviço de firewall para o seu computador host. Pode precisar de qualquer entrada para encaminhar o tráfego para o hóspede.

Veja link , link e link .

    
por John S Gruber 15.09.2012 / 02:34
3

Estes são os dois scripts que eu uso para criar uma ponte para qemu-kvm .

Primeiro, deixe o host se tornar um roteador IP.

Script ip-router.sh :

#!/bin/bash

internetinterface="eth0"

username='whoami'

if [ "x$username" != "xroot" ] ; then

    echo    
    echo "You must be root in order to run this script..."
    echo    

    exit    

fi  

if [ "x" != "x" ] ; then
    internetinterface=""
fi  

if [ "x" == "xdel" ] || [ "x" == "xdel" ] ; then
    disable="1"
else
    disable="0"
fi  

if [ "$disable" == "0" ] ; then
    echo "Enabling IP forward and setting up masquerade NAT on interface $internetinterface"

    echo 1 > /proc/sys/net/ipv4/ip_forward

    iptables -t nat -A POSTROUTING -o $internetinterface -j MASQUERADE
else
    echo "Disable IP forward and setting down masquerade NAT on interface $internetinterface"

    echo 0 > /proc/sys/net/ipv4/ip_forward

    iptables -t nat -D POSTROUTING -o $internetinterface -j MASQUERADE
fi  

Em seguida, crie a interface tun-tap e bridge com sua interface padrão (geralmente aquela com conexão à Internet).

Script create-qemu-bridged-tuntap.sh :

#!/bin/bash

bridgename=br0
tapinterface=tap0
outinterface=eth1

if [ "x" != "x" ] ; then
    outinterface=""
fi  

ifaces='awk -F: '{print }' /proc/net/dev | tail -n +3'
iffound="0"

for i in $ifaces
do  
    if [ "$outinterface" == "$i" ] ; then
            iffound="1"
    fi  
done

if [ "$iffound" == "0" ] ; then
    echo
    echo "Can't find the output interface."
    echo
    exit 1
fi  

outifaceip='ifconfig | grep -A1 $outinterface | tail -1 | awk -F: '{print }' | awk '{print }''
outifaceiptokens='echo $outifaceip | awk -F \. '{print NF}''

if [ "$outifaceiptokens" != "4" ] ;  then
    echo
    echo "The selected output interface $outinterface doesn't seem to have a valid IP address."
    echo
    exit 1
fi  

hostaddress="192.168.1.1"
guestaddress="192.168.1.95"

sudo tunctl -t $tapinterface

sudo brctl addbr $bridgename
sudo brctl addif $bridgename $tapinterface

sudo ip link set $bridgename up
sudo ip addr add $hostaddress/24 dev $bridgename

sudo route add -host $guestaddress dev $bridgename
sudo parprouted eth1 $bridgename

sudo ~/scripts/ip-router.sh $outinterface

Eu uso esses scripts diariamente, então eles devem funcionar bem também para você. Você terá que instalar algum pacote para que tudo isso funcione. Usando:

dlocate 'which COMMAND'

você pode ver qual pacote é necessário para ter COMMAND . Por exemplo, para ver qual pacote é necessário para ter brctl , simplesmente execute:

dlocate 'which brctl'

e você terá:

bridge-utils: /sbin/brctl

Usando a mesma abordagem para todos os comandos nesses scripts, você deve (pelo menos) executar essa linha de comando aptitude :

sudo aptitude install dlocate iproute parprouted iptables uml-utilities bridge-utils net-tools

Finalmente, você pode iniciar o script principal (como um usuário normal):

#> create-qemu-bridged-tuntap.sh eth0
Set 'tap0' persistent and owned by uid 0
Enabling IP forward and setting up masquerade NAT on interface eth0

Em execução, ip addr , você verá uma interface br0 com o endereço IP 192.168.1.1 , conforme especificado no script create-qemu-bridged-tuntap.sh :

#> ip addr
8: br0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 36:76:ee:d6:63:b2 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 scope global br0

Este é o host address visto pelo guest . Por outro lado, o convidado terá como endereço IP 192.168.1.95 (novamente, isso pode ser facilmente alterado dentro do script principal).

Agora, usando virt-manager , basta configurar seu guest nic para usar br0 como interface física.

Dentro do guest , você só precisa fornecer a eth0 um endereço IP de 192.168.1.95 e tudo deve ser executado corretamente.

Slackware13:~> ifconfig 
eth0      Link encap:Ethernet  HWaddr 52:54:00:F7:6A:78  
          inet addr:192.168.1.95  Bcast:192.168.1.255  Mask:255.255.255.0
    
por Avio 14.09.2012 / 11:32
3

Se o comportamento que você está vendo for host, ele pode acessar o convidado, e convidado pode acessar o host, mas o convidado não pode acessar outras máquinas na rede ou vice-versa ... provavelmente o firewall do host está bloqueando o acesso. / p>

Veja: link

Especificamente, esta seção: "O passo final é desabilitar o netfilter na bridge:

# cat >> /etc/sysctl.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
EOF
    
por Jeremy Spilman 13.06.2013 / 07:59