Difference between revisions of "Virtual Ethernet device"

From OpenVZ Virtuozzo Containers Wiki
Jump to: navigation, search
(syntax vzctl version < 3.0.14: changed less than to greater than)
(syntax vzctl version > 3.0.14: reverted)
Line 72: Line 72:
 
Syntax is the same as above, but without a <bridge> parameter.
 
Syntax is the same as above, but without a <bridge> parameter.
  
==== syntax vzctl version > 3.0.14 ====
+
==== syntax vzctl version < 3.0.14 ====
  
 
  vzctl set <CTID> --veth_add <dev_name>,<dev_addr>,<ve_dev_name>,<ve_dev_addr>
 
  vzctl set <CTID> --veth_add <dev_name>,<dev_addr>,<ve_dev_name>,<ve_dev_addr>

Revision as of 14:56, 6 May 2010

Virtual Ethernet device is an Ethernet-like device which can be used inside a container. Unlike venet network device, veth device has a MAC address, therefore it can be used in configurations, when veth is bridged to ethX or other device and container's user fully sets up his networking himself, including IPs, gateways etc.

Virtual Ethernet device consist of two Ethernet devices -- the one in CT0 and another one in CT. These devices are connected to each other, so if a packet goes to one device it will come out from the other device.

Virtual Ethernet device usage

Kernel module

First of all, make sure the vzethdev module is loaded:

# lsmod | grep vzeth
vzethdev                8224  0
vzmon                  35164  5 vzethdev,vznetdev,vzrst,vzcpt
vzdev                   3080  4 vzethdev,vznetdev,vzmon,vzdquota

In case it is not loaded, load it:

# modprobe vzethdev
Yellowpin.svg Note: in vzctl < 3.0.11, vzethdev is not autoloaded by /etc/init.d/vz script, so you have to edit it to load this module.

MAC addresses

In the below commands, you should use random MAC addresses. Do not use MAC addresses of real eth devices, because this can lead to collisions.

MAC addresses must be entered in XX:XX:XX:XX:XX:XX format.

YOU MAY NOT NEED TO GENERATE MAC ADDRESSES BY HAND BECAUSE vzctl --veth_add MAY GENERATE THEM AUTOMATICALLY AS NECESSARY.

Nevertheless, there is a utility script available for generating MAC addresses: http://www.easyvmx.com/software/easymac.sh. It is to be used like this:

chmod +x easymac.sh
./easymac.sh -R

Adding veth to a CT

syntax vzctl version > 3.0.22

vzctl set <CTID> --netif_add <ifname>[,<mac>,<host_ifname>,<host_mac>,<bridge>]

Here

  • ifname is the Ethernet device name in the CT
  • mac is its MAC address in the CT
  • host_ifname is the Ethernet device name on the host (CT0)
  • host_mac is its MAC address on the host (CT0)
  • bridge is an optional parameter which can be used in custom network start scripts to automatically add the interface to a bridge.
Yellowpin.svg Note: All parameters except ifname are optional and are automatically generated if not specified.

Example:

vzctl set 101 --netif_add eth0 --save

Or, if you want to specify everything:

vzctl set 101 --netif_add eth0,00:12:34:56:78:9A,veth101.0,00:12:34:56:78:9B --save

Or, if you want to specify the bridge and leave the other values autogenerated:

vzctl set 101 --netif_add eth0,,,,vmbr1 --save

syntax vzctl version <= 3.0.14

Syntax is the same as above, but without a <bridge> parameter.

syntax vzctl version < 3.0.14

vzctl set <CTID> --veth_add <dev_name>,<dev_addr>,<ve_dev_name>,<ve_dev_addr>


Here

  • dev_name is the Ethernet device name that you are creating on the host system
  • dev_addr is its MAC address
  • ve_dev_name is the corresponding Ethernet device name you are creating on the CT
  • ve_dev_addr is its MAC address
Yellowpin.svg Note: this option is incremental, so devices are added to already existing ones.

NB there should no spaces after the commas.

Example:

[host-node] ifconfig eth0
...
HWaddress 00:12:34:56:78:9B
...
[host-node] easymac.sh -R
00:12:34:56:78:9A
vzctl set 101 --veth_add veth101.0,00:12:34:56:78:9A,eth0,00:12:34:56:78:9B --save

After executing this command veth device will be created for CT 101 and veth configuration will be saved to a CT configuration file. Host-side Ethernet device will have veth101.0 name and 00:12:34:56:78:9A MAC address. CT-side Ethernet device will have eth0 name and 00:12:34:56:78:9B MAC address.

Removing veth from a CT

syntax vzctl version >= 3.0.14

vzctl set <CTID> --netif_del <dev_name>|all

Here

  • dev_name is the Ethernet device name in the CT.
Yellowpin.svg Note: If you want to remove all Ethernet devices in CT, use all.

Example:

vzctl set 101 --netif_del eth0 --save

syntax vzctl version < 3.0.14

vzctl set <CTID> --veth_del <dev_name>

Here dev_name is the Ethernet device name in the host system.

Example:

vzctl set 101 --veth_del veth101.0 --save

After executing this command veth device with host-side Ethernet name veth101.0 will be removed from CT101 and veth configuration will be updated in CT config file.

Common configurations with virtual Ethernet devices

Module vzethdev must be loaded to operate with veth devices.

Simple configuration with virtual Ethernet device

Assuming you have 192.168.0.0/24 on your LAN, you will learn how to integrate a container in this LAN using veth.

Start a CT

[host-node]# vzctl start 101

Add veth device to CT

[host-node]# vzctl set 101 --netif_add eth0 --save

This allocates a MAC address and associates it with the host eth0 port.

Configure devices in CT0

[host-node]# ifconfig veth101.0 0
[host-node]# echo 1 > /proc/sys/net/ipv4/conf/veth101.0/forwarding
[host-node]# echo 1 > /proc/sys/net/ipv4/conf/veth101.0/proxy_arp
[host-node]# echo 1 > /proc/sys/net/ipv4/conf/eth0/forwarding
[host-node]# echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp

Configure device in CT

[host-node]# vzctl enter 101
[ve-101]# /sbin/ifconfig eth0 0
[ve-101]# /sbin/ip addr add 192.168.0.101 dev eth0
[ve-101]# /sbin/ip route add default dev eth0

Notes:

Add route in CT0

[host-node]# ip route add 192.168.0.101 dev veth101.0


Using a directly routed IPv4 with virtual Ethernet device

Situation

Hardware Node (HN/CT0) has 192.168.0.1/24 with router 192.168.0.254.

We also know that IPv4 10.0.0.1/32 is directly routed to 192.168.0.1 (this is called a fail-over IP).

We want to give this directly routed IPv4 address to a container (CT).

Start container

[host-node]# vzctl start 101

Add veth device to CT

[host-node]# vzctl set 101 --netif_add eth0 --save

This allocates a MAC address and associates it with the host eth0 port.

Configure device and add route in CT0

[host-node]# ifconfig veth101.0 0
[host-node]# ip route add 10.0.0.1 dev veth101.0

You can automatize this at VPS creation by using a mount script $VEID.mount.

The problem here is that the veth interface appears in CT0 after VPS has started, therefore we cannot directly use the commands in the mount script. We launch a shell script (enclosed by { }) in background (operator &) that waits for the interface to be ready and then adds the IP route.

Contents of the mount script /etc/vz/conf/101.mount:

#!/bin/bash
# This script source VPS configuration files in the same order as vzctl does

# if one of these files does not exist then something is really broken
[ -f /etc/vz/vz.conf ] || exit 1
[ -f $VE_CONFFILE ] || exit 1

# source both files. Note the order, it is important
. /etc/vz/vz.conf
. $VE_CONFFILE

# Configure veth with IP after VPS has started
{
  IP=X.Y.Z.T
  DEV=veth101.0
  while sleep 1; do
    /sbin/ifconfig $DEV 0 >/dev/null 2>&1
    if [ $? -eq 0 ]; then
      /sbin/ip route add $IP dev $DEV
      break
    fi
  done
} &

Make sure IPv4 forwarding is enabled in CT0

[host-node]# echo 1 > /proc/sys/net/ipv4/ip_forward
[host-node]# echo 1 > /proc/sys/net/ipv4/conf/eth0/forwarding
[host-node]# echo 1 > /proc/sys/net/ipv4/conf/veth101.0/forwarding

You can permanently set this by using /etc/sysctl.conf.

Configure device in CT

1. Configure IP address

2. Add gateway

3. Add default route

[ve-101]# /sbin/ifconfig eth0 10.0.0.1 netmask 255.255.255.255
[ve-101]# /sbin/ip route add 192.168.0.1 dev eth0
[ve-101]# /sbin/ip route default via 192.168.0.1

In a Debian container, you can configure this permanently by using /etc/network/interfaces:

auto eth0
iface eth0 inet static
        address 10.0.0.1
        netmask 255.255.255.255
        up /sbin/ip route add 192.168.0.1 dev eth0
        up /sbin/ip route add default via 192.168.0.1

Virtual Ethernet device with IPv6

See the VEs and HNs in same subnets article.

Virtual Ethernet devices can be joined in one bridge

Perform steps 1 - 4 from Simple configuration chapter for several containers and/or veth devices

Create bridge device

[host-node]# brctl addbr vzbr0

Add veth devices to bridge

[host-node]# brctl addif vzbr0 veth101.0
...
[host-node]# brctl addif vzbr0 veth101.n
[host-node]# brctl addif vzbr0 veth102.0
...
...
[host-node]# brctl addif vzbr0 vethXXX.N

Configure bridge device

[host-node]# ifconfig vzbr0 0
[host-node]# echo 1 > /proc/sys/net/ipv4/conf/vzbr0/forwarding
[host-node]# echo 1 > /proc/sys/net/ipv4/conf/vzbr0/proxy_arp

Add routes in CT0

[host-node]# ip route add 192.168.101.1 dev vzbr0
...
[host-node]# ip route add 192.168.101.n dev vzbr0
[host-node]# ip route add 192.168.102.1 dev vzbr0
...
...
[host-node]# ip route add 192.168.XXX.N dev vzbr0

Thus you'll have more convinient configuration, i.e. all routes to containers will be through this bridge and containers can communicate with each other even without these routes.



Making a veth-device persistent

According to http://bugzilla.openvz.org/show_bug.cgi?id=301 , a bug that stopped the veth device persistent was "Obsoleted now when --veth_add/--veth_del are introduced"

See http://wiki.openvz.org/w/index.php?title=Virtual_Ethernet_device&diff=5990&oldid=5989#Making_a_veth-device_persistent for a workaround that used to be described in this section.

That's it! At this point, when you restart the CT you should see a new line in the output, indicating that the interface is being configured and a new route being added. And you should be able to ping the host, and to enter the CT and use the network.

Making a bridged veth-device persistent

Like the above example, here it is how to add the veth device to a bridge in a persistent way.

method for vzctl version > 3.0.22

Newer versions of vzctl includes a 'vznetaddbr' script, which makes use of the new <bridge> parameter of the --netif_add switch.

Just create /etc/vz/vznet.conf containing the following.

#!/bin/bash
EXTERNAL_SCRIPT="/usr/sbin/vznetaddbr"

The script uses 'vmbr0' as default bridge name when no bridge is specified.

method for vzctl version <= 3.0.22

Older vzctl doesn't offer an automatic function to do this.

1. First, edit the CT's configuration to specify what is the host bridge , and to indicate that a custom script should be run when starting up a CT.

  • Open up /etc/vz/conf/CTID.conf
  • Comment out any IP_ADDRESS entries to prevent a CTNET-device from being created in the CT
  • Add or change the entry CONFIG_CUSTOMIZED="yes"
  • Add an entry VZHOSTBR="<bridge if>" which is the bridge interface (already configured and up), you want to extend.

2. Now to create that "custom script". The following helper script will check the configuration file for the bridge interface name and for the veth interface, and add the interface to the bridge. Create the script /usr/sbin/vznetaddbr to have the following, and then chmod 0500 /usr/sbin/vznetaddbr to make it executable.

#!/bin/bash
# /usr/sbin/vznetaddbr
# a script to add virtual network interfaces (veth's) in a CT to a bridge on CT0

CONFIGFILE=/etc/vz/conf/$VEID.conf
. $CONFIGFILE
VZHOSTIF=`echo $NETIF |sed 's/^.*host_ifname=\(.*\),.*$/\1/g'`

if [ ! -n "$VZHOSTIF" ]; then
   echo "According to $CONFIGFILE CT$VEID has no veth interface configured."
   exit 1
fi

if [ ! -n "$VZHOSTBR" ]; then
   echo "According to $CONFIGFILE CT$VEID has no bridge interface configured."
   exit 1
fi

echo "Adding interface $VZHOSTIF to bridge $VZHOSTBR on CT0 for CT$VEID"
/sbin/ifconfig $VZHOSTIF 0
echo 1 > /proc/sys/net/ipv4/conf/$VZHOSTIF/proxy_arp
echo 1 > /proc/sys/net/ipv4/conf/$VZHOSTIF/forwarding
/usr/sbin/brctl addif $VZHOSTBR $VZHOSTIF

exit 0

3. Now create /etc/vz/vznet.conf containing the following. This is what defines the "custom script" as being the vznetaddbr which you just created.

#!/bin/bash
EXTERNAL_SCRIPT="/usr/sbin/vznetaddbr"

This may not work for particularily old versions of vzctl, e.g., the version 3.0.11 that ships with Debian Etch. For those versions, you can try a hack: Use the custom script /etc/vz/conf/$VID.mount which is available, even in these old versions. But it gets called too early, before the networking has been set up. But it can start some background process, which waits and occasionally polls until $VZHOSTIF has become available. Here is one way to go about it:

#!/bin/bash

CONFIGFILE="/etc/vz/conf/$VEID.conf"

if [ -f "$CONFIGFILE" ]
then
   . "$CONFIGFILE"
   VZHOSTIF=`echo $NETIF |sed 's/^.*host_ifname=\(.*\),.*$/\1/g'`
   export VZHOSTIF
   export VZHOSTBR

   # Fork into the background and try a few times,
   # until the host side of the interface appears:
   /bin/bash -c 'for i in 5 10 20 40 80 160
     do
        if ifconfig -a | grep -q "$VZHOSTIF"
        then
           exec /usr/sbin/vznetaddbr
        else
           sleep "$i"
        fi
     done
   ' &

   # In the meantime, let the CT's start process continue,
   # or else the interface will never appear:
   exit 0
else
   $0: Config file "$CONFIGFILE" does not exist.
   exit 1
fi

4. Of course, the CT's operating system will need to have . Consult the manual for your CT's OS for details.

When the CT is started, the veth specified in the NETIF value is added to the bridge specified. You can check this by doing brctl show

Inside the CT you can configure the interface statically or using dhcp, as a real interface attached to a switch on the lan.

Virtual Ethernet devices + VLAN

This configuration can be done by adding vlan device to the previous configuration.

See also

External links