KVM Bridged Network non funziona

20

Ho appena installato KVM sul mio server Ubuntu in base a questa guida: link

Quindi preparato una rete a ponte come mostrato qui: link

Quindi, ho creato una macchina virtuale con virt-manager. Ho provato diverse volte ma l'ospite non riesce a connettersi alla rete! Qualche aiuto?

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)

brctl show:

 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

percorso 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

* Nel guest * non ero in grado di copiare incolla le informazioni dal guest perché non posso ssh su di esso. Non ha ricevuto alcun IP da DHCP. Non funzionerà anche dopo averlo configurato manualmente.

    
posta THpubs 23.08.2012 - 18:56

3 risposte

18

Preliminari

Questo lavoro ha funzionato per me per Ubuntu 12.04. Devi disabilitare il firewall del tuo computer mentre esegui il test in modo che non interferisca.

Il file / etc / default / qemu-kvm dovrebbe essere come originariamente installato.

Avrai bisogno di bridge-utils qemu -kvm e libvirt-bin installato. Tutti gli utenti che utilizzano macchine virtuali dovrebbero essere aggiunti al gruppo libvirtd.

Sembra che non sia più necessario aggiungere funzionalità CAP_NET_ADMIN.

Impostazione rete

La modalità di rete predefinita è la modalità Utente, detta anche SLIRP. Utilizza un ponte virbr0 predefinito che viene instradato NAT sul computer guest. Il routing NAT utilizza la funzione ip_forwarding del kernel e iptables . La modalità Bridge utilizza un bridge virtuale nel guest a cui si connette l'interfaccia Ethernet (non numerata) e su cui sia l'host che l'ospite hanno le loro interfacce di rete.

I seguenti diagrammi possono rendere più chiare le differenze:

Puoi vedere come viene definita la rete utente predefinita con:

virsh net-dumpxml default

Posso impostare la modalità a ponte con i seguenti approcci:

In / etc / network / interfaces (dalla parte di bridging del post che hai citato nella tua domanda):

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

Reboot; e assicurarsi che la rete wireless non sia attiva. Verifica la route IP predefinita con ip route . Deve utilizzare l'interfaccia br0.

NB. Se la tua Ethernet non è collegata quando viene apportata questa modifica, devi collegare il tuo cavo Ethernet e ottenere un gestore telefonico o il boot si bloccherà per due minuti e non avrai la capacità di rete Questo perché eth0 l'interfaccia, essendo in questo file, deve apparire prima che l'avvio possa procedere normalmente.

NB. Generalmente non è possibile utilizzare una rete wireless invece di eth0 a causa della loro impossibilità di utilizzare più indirizzi MAC (deduco che hanno bisogno di un secondo per il bridge).

In alternativa puoi disabilitare l'uso di Ethernet e assicurarti che non disponga di un indirizzo IP, e che non ci sia una route predefinita configurata con ip route . Poi:

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

Qui puoi anche fornire un indirizzo IP statico, oltre a definire il percorso predefinito e l'indirizzo DNS. Per questo esempio dhclient fa questo.

Ecco la mia tabella di percorso:

$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

Utilizzo di kvm

Posso quindi avviare una macchina KVM con ponte con:

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

Il parametro -netdev tap rende sudo un requisito. All'avvio di vm, qemu-kvm esegue i seguenti comandi:

ifconfig vnet0 0.0.0.0 up
brctl addif brctl addif br0 vnet0

Questo è fatto da / etc / qemu-ifup

L'interfaccia vnet0 di vm è stata aggiunta al bridge br0 perché la route predefinita in alto utilizza quell'interfaccia bridge. Se non fosse lì, l'interfaccia di tocco sarebbe invece aggiunta all'interfaccia di virbr0. Dal momento che non è connesso a Internet, NAT verrebbe utilizzato per collegare l'ospite all'host e a Internet, nei miei esperimenti. È possibile indirizzare il vnet0 a un particolare bridge in / etc / default / qemu-kvm. Usando virt-manager qui sotto puoi dirigere esplicitamente a quale bridge connetterti.

A causa dei comandi sopra emessi da qemu-kvm e del parametro -netdev tap,id=tunnel,ifname=vnet0 , la macchina virtuale vm è connessa al tunnel vnet0 e il tunnel è connesso al bridge br0.

Ora posso ssh direttamente in questo guest vm da un altro computer sulla mia rete.

Il mio host ifconfig (nota l'interfaccia vnet0 che appare sulla mia rete quando il vm è in esecuzione):

$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)

Configurazione del mio bridge durante l'esecuzione della VM:

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

Si noti che sia l'interfaccia vnet0 della macchina virtuale che l'interfaccia eth0 sono collegate al bridge br0.

E i MAC sull'interfaccia 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

Si noti che l'interfaccia br0 collega il mio computer host allo stesso bridge utilizzato dal guest.

Puoi verificare che tu sia collegato in parallelo anziché NAT indirizzato alla tua rete utilizzando traceroute 8.8.8.8 . Se il primo nodo è il router della tua rete anziché l'indirizzo IP del guest, la tua rete dovrebbe funzionare correttamente.

Vedi questa documentazione .

virt-manager

Assicurati di aver installato virt-manager e hal . Il pacchetto hal è una dipendenza suggerita per virt-manager e viene utilizzato per determinare la configurazione di rete del sistema quando si creano o si modificano i guest.

Pur avendo il bridge br0 definito come sopra, ho creato una macchina virtuale con virt-manager come segue:

Sono stato in grado di andare direttamente al resto della rete domestica e a Internet da questo ospite. Sono stato anche in grado di installarlo da un altro computer Ubuntu (non host, non ospite) sulla mia rete domestica.

Ecco il comando kvm molto lungo eseguito da virt-manager (per il confronto con EApubs o chiunque altro abbia problemi con questo):

/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

Ecco la parte di rete della descrizione della macchina virtuale in /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>

Secondo questo link, per prestazioni e affidabilità, potrebbe essere meglio imposta il modello del dispositivo di rete su virtio , puoi farlo nel virt-viewer premendo il pulsante i , andando all'impostazione NIC e impostando il "Modello dispositivo" su virtio . Puoi anche aggiungere questo al xml sopra aggiungendo la riga:

      <model type='virtio'/>

In breve

Tutto ciò ha richiesto il 12.04 è stato:

  1. Installazione di virt-manager, bridge-utils, qemu-kvm e pacchetti correlati
  2. Assicurati che ogni utente che desidera utilizzare kvm si trovi nel gruppo libvirtd.
  3. Definizione di / etc / network / interfacce come sopra (che corrisponde all'articolo citato)
  4. Riavvia, assicurati che Ethernet sia collegato e wireless (se presente) sia spento.
  5. Esegui kvm su un'immagine direttamente con, ad es. -device e1000,netdev=tunnel -netdev tap,id=tunnel,ifname=vnet0 , o crea una macchina virtuale con virt-manager, specificando br0 Bridge di rete nel pannello Step 4- & gt; Opzioni avanzate.

Non sono state necessarie ulteriori modifiche a networking, funzionalità, modelli o configurazioni.

Per esporre un servizio nel tuo nuovo ospite a Internet dovresti:

  1. Prepara e configura qualsiasi servizio firewall di cui avrai bisogno.
  2. Assegna un indirizzo statico nella configurazione del guest o nel servizio DHCP.
  3. Se stai utilizzando un router NAT, apri una porta per il servizio che stai implementando indirizzandola all'indirizzo IP del guest.

Ricordati di testare e riattivare il servizio firewall per il tuo computer host. Potrebbe essere necessaria una voce per inoltrare il traffico al guest.

Vedi link , link e link .

    
risposta data John S Gruber 15.09.2012 - 02:34
3

Questi sono i due script che uso per creare un bridge per qemu-kvm .

Innanzitutto, fai diventare l'host un router 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  

Quindi, crea l'interfaccia tun-tap e bridge con l'interfaccia predefinita (di solito quella con una connessione 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

Uso quotidianamente questi script, quindi dovrebbero funzionare bene anche per te. Dovrai installare qualche pacchetto per far funzionare tutto questo. Usando:

dlocate 'which COMMAND'

puoi vedere quale pacchetto è necessario per avere COMMAND . Ad esempio, per vedere quale pacchetto è necessario avere brctl , esegui semplicemente:

dlocate 'which brctl'

e avrai:

bridge-utils: /sbin/brctl

Usando lo stesso approccio per tutti i comandi di questi script, dovresti (almeno) eseguire questa riga di comando aptitude :

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

Infine, puoi avviare lo script principale (come utente normale):

#> 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

Eseguendo ip addr dovresti vedere un'interfaccia br0 con indirizzo IP 192.168.1.1 , come specificato nello 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

Questo è il host address visto da guest . Viceversa, il guest avrà come indirizzo IP 192.168.1.95 (anche in questo caso può essere facilmente modificato all'interno dello script principale).

Ora, usando virt-manager , devi solo configurare il tuo guest nic per usare br0 come interfaccia fisica.

All'interno di guest , devi solo dare a eth0 un indirizzo IP di 192.168.1.95 e tutto dovrebbe funzionare bene.

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
    
risposta data Avio 14.09.2012 - 11:32
3

Se il comportamento che stai vedendo è l'host può accedere al guest, e il guest può accedere all'host, ma il guest non può accedere ad altre macchine sulla rete o viceversa ... probabilmente il firewall dell'host sta bloccando l'accesso.

Vedi: link

In particolare, questa sezione: "Il passo finale è disabilitare netfilter sul 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
    
risposta data Jeremy Spilman 13.06.2013 - 07:59

Leggi altre domande sui tag