How To Do Live Migration Of OpenVZ Containers

Version 1.0
Author: Falko Timme

This guide explains how you can do a live migration of an OpenVZ container from one OpenVZ host to the other. Both OpenVZ hosts are running on Debian Lenny in this article, but the live migration does not differ on other distributions.

I do not issue any guarantee that this will work for you!

 

1 Preliminary Note

I'm using the following systems here:

  • OpenVZ host 1 : server.example.com, IP address: 192.168.0.100
  • OpenVZ host 2 : server2.example.com, IP address: 192.168.0.101
  • virtual machine: vm1.example.com, IP address: 192.168.0.102, VEID 102

The two OpenVZ hosts should be set up according to this tutorial: Installing And Using OpenVZ On Debian Lenny (AMD64). The virtual machine vm1.example.com is running on server1 with the VEID 102.

 

2 Live Migration Of vm1.example.com From server1 To server2

To check if the live migration is really done "live", i.e. without interruption of the guest, you can log into vm1.example.com (e.g. with SSH) and ping another server:

vm1.example.com:

ping google.com

This will ping google.com until you press CTRL + C. The pinging should continue even during the live migration.

server1:

I want to run the live migration as the root user. Live migration will work only if the root user on server1 can log into server2 via SSH without being asked for a password (this means SSH root logins must be allowed on server2 - check your sshd configuration: /etc/ssh/sshd_config). This can be achieved by generating a key pair for root@server1 and then store root@server1's public key in the ~/.ssh/authorized_keys file of root@server2. Fortunately, there's a bash script that can do this for us. We create the script as follows:

vi /usr/local/bin/ssh-keyput 
#!/bin/bash
#
# ssh-keyput -- set up passwordless openssh login.
#
# Copyright (C) 2001, 2002, 2006 by SWsoft.
# Author: Kir Kolyshkin
#
# This script is used to put your public ssh keys to another host's
# authorized_keys[2], so you will be able to ssh login without entering
# a password. Key pairs are generated if needed, and connectivity
# is checked after putting the keys.

PROGNAME=`basename $0`

function usage()
{
    echo "Usage: $PROGNAME [user@]IP [[user@]IP ...]" 1>&2
    exit 0
}

# Check for correct number of parameters
test $# -gt 0 || usage;

SSH_KEYGEN=`which ssh-keygen`
if test $? -ne 0; then
    # Error message is printed by 'which'
    exit 1
fi

SSH_DIR=~/.ssh
if ! test -d $SSH_DIR; then
    mkdir $SSH_DIR
fi
chmod 700 $SSH_DIR


if [ ! -f $SSH_DIR/identity ] || [ ! -f $SSH_DIR/identity.pub ]; then
    echo "Generating ssh1 RSA keys - please wait..."
    rm -f $SSH_DIR/identity $SSH_DIR/identity.pub
    $SSH_KEYGEN -t rsa1 -f $SSH_DIR/identity -P ''
    if [ $? -ne 0 ]; then
        echo "Command \"$SSH_KEYGEN -t rsa1 -f $SSH_DIR/identity" \
             "-P ''\" failed" 1>&2
        exit 1
    fi
else
    echo "ssh1 RSA key is present"
fi

if [ ! -f $SSH_DIR/id_dsa ] || [ ! -f $SSH_DIR/id_dsa.pub ]; then
    echo "Generating ssh2 DSA keys - please wait..."
    rm -f $SSH_DIR/id_dsa $SSH_DIR/id_dsa.pub
    $SSH_KEYGEN -t dsa -f $SSH_DIR/id_dsa -P ''
    if test $? -ne 0; then
        echo "Command \"$SSH_KEYGEN -t dsa -f $SSH_DIR/id_dsa" \
             "-P ''\" failed" 1>&2
        exit 1
    fi
else
    echo "ssh2 DSA key is present"
fi

SSH1_RSA_KEY=`cat $SSH_DIR/identity.pub`
SSH2_DSA_KEY=`cat $SSH_DIR/id_dsa.pub`

for IP in $*; do
    echo "You will now be asked for password for $IP"
#    set -x
    ssh -oStrictHostKeyChecking=no $IP "mkdir -p ~/.ssh; chmod 700 ~/.ssh; \
        echo \"$SSH1_RSA_KEY\" >> ~/.ssh/authorized_keys; \
        echo \"$SSH2_DSA_KEY\" >> ~/.ssh/authorized_keys2; \
        chmod 600 ~/.ssh/authorized_keys ~/.ssh/authorized_keys2"
#    set +x
    if test $? -eq 0; then
        echo "Keys were put successfully"
    else
        echo "Error putting keys to $IP" 1>&2
    fi
done

for IP in $*; do
    for ver in 1 2; do
        echo -n "Checking $IP connectivity by ssh$ver... "
        ssh -q -oProtocol=${ver} -oBatchMode=yes \
          -oStrictHostKeyChecking=no $IP /bin/true
        if [ $? -eq 0 ]; then
            echo "OK"
        else
            echo "failed" 1>&2
        fi
    done
done

Then we make the script executable...

chmod a+x /usr/local/bin/ssh-keyput

... and call it as follows to generate a keypair for root@server1 and store the public key in ~/.ssh/authorized_keys file of root@server2 (server2 = 192.168.0.101):

ssh-keyput 192.168.0.101  

server1:~# ssh-keyput 192.168.0.101
Generating ssh1 RSA keys - please wait...
Generating public/private rsa1 key pair.
Your identification has been saved in /root/.ssh/identity.
Your public key has been saved in /root/.ssh/identity.pub.
The key fingerprint is:
5f:5b:17:0d:6b:17:9e:ae:b8:bf:87:37:d2:27:db:65 [email protected]
The key's randomart image is:
+--[RSA1 2048]----+
|              .. |
|              .o+|
|              o+o|
|             ....|
|        S   . ...|
|         . ..o.. |
|          ....o E|
|            .o.Bo|
|           ..o*o+|
+-----------------+
Generating ssh2 DSA keys - please wait...
Generating public/private dsa key pair.
Your identification has been saved in /root/.ssh/id_dsa.
Your public key has been saved in /root/.ssh/id_dsa.pub.
The key fingerprint is:
29:84:d2:0f:ed:9d:25:52:6f:09:f5:5f:c3:fd:eb:26 [email protected]
The key's randomart image is:
+--[ DSA 1024]----+
|        o..      |
|   . o . o o  . .|
|  . + + . = .  oo|
|   . = o *   . .o|
|      + S     . .|
|       .        .|
|               . |
|             E.. |
|              o. |
+-----------------+
You will now be asked for password for 192.168.0.101
[email protected]'s password:
Keys were put successfully
Checking 192.168.0.101 connectivity by ssh1... failed
Checking 192.168.0.101 connectivity by ssh2... OK
server1:~#

Take a look at

vzlist -a

and you should see that vm1.example.com is still running on server1:

server1:~# vzlist -a
      VEID      NPROC STATUS  IP_ADDR         HOSTNAME
       102          9 running 192.168.0.102   vm1.example.com
server1:~#

Now we can start the live migration:

vzmigrate --online 192.168.0.101 102

(Use the IP address or the hostname of the target server after --online. The last argument is the VEID, in this case 102.)

server1:~# vzmigrate --online 192.168.0.101 102
OPT:--online
OPT:192.168.0.101
StartingPreparingInitializingSyncingLiveSyncingCleanup
server1:~#

During the migration, the pings on vm1.example.com should continue which means that the guest is running even during the migration process.

Afterwards, take a look at

vzlist -a

server1:~# vzlist -a
      VEID      NPROC STATUS  IP_ADDR         HOSTNAME
server1:~#

As you see, vm1.example.com isn't listed anymore on server1.

Let's check on server2:

server2:

vzlist -a

server2:~# vzlist -a
      VEID      NPROC STATUS  IP_ADDR         HOSTNAME
       102          9 running 192.168.0.102   vm1.example.com
server2:~#

If everything went well, vm1.example.com should now be running on server2.

If you want to migrate vm1.example.com back to server1, you must create a keypair for root@server2 now and copy the public key to server1:

vi /usr/local/bin/ssh-keyput 
#!/bin/bash
#
# ssh-keyput -- set up passwordless openssh login.
#
# Copyright (C) 2001, 2002, 2006 by SWsoft.
# Author: Kir Kolyshkin
#
# This script is used to put your public ssh keys to another host's
# authorized_keys[2], so you will be able to ssh login without entering
# a password. Key pairs are generated if needed, and connectivity
# is checked after putting the keys.

PROGNAME=`basename $0`

function usage()
{
    echo "Usage: $PROGNAME [user@]IP [[user@]IP ...]" 1>&2
    exit 0
}

# Check for correct number of parameters
test $# -gt 0 || usage;

SSH_KEYGEN=`which ssh-keygen`
if test $? -ne 0; then
    # Error message is printed by 'which'
    exit 1
fi

SSH_DIR=~/.ssh
if ! test -d $SSH_DIR; then
    mkdir $SSH_DIR
fi
chmod 700 $SSH_DIR


if [ ! -f $SSH_DIR/identity ] || [ ! -f $SSH_DIR/identity.pub ]; then
    echo "Generating ssh1 RSA keys - please wait..."
    rm -f $SSH_DIR/identity $SSH_DIR/identity.pub
    $SSH_KEYGEN -t rsa1 -f $SSH_DIR/identity -P ''
    if [ $? -ne 0 ]; then
        echo "Command \"$SSH_KEYGEN -t rsa1 -f $SSH_DIR/identity" \
             "-P ''\" failed" 1>&2
        exit 1
    fi
else
    echo "ssh1 RSA key is present"
fi

if [ ! -f $SSH_DIR/id_dsa ] || [ ! -f $SSH_DIR/id_dsa.pub ]; then
    echo "Generating ssh2 DSA keys - please wait..."
    rm -f $SSH_DIR/id_dsa $SSH_DIR/id_dsa.pub
    $SSH_KEYGEN -t dsa -f $SSH_DIR/id_dsa -P ''
    if test $? -ne 0; then
        echo "Command \"$SSH_KEYGEN -t dsa -f $SSH_DIR/id_dsa" \
             "-P ''\" failed" 1>&2
        exit 1
    fi
else
    echo "ssh2 DSA key is present"
fi

SSH1_RSA_KEY=`cat $SSH_DIR/identity.pub`
SSH2_DSA_KEY=`cat $SSH_DIR/id_dsa.pub`

for IP in $*; do
    echo "You will now be asked for password for $IP"
#    set -x
    ssh -oStrictHostKeyChecking=no $IP "mkdir -p ~/.ssh; chmod 700 ~/.ssh; \
        echo \"$SSH1_RSA_KEY\" >> ~/.ssh/authorized_keys; \
        echo \"$SSH2_DSA_KEY\" >> ~/.ssh/authorized_keys2; \
        chmod 600 ~/.ssh/authorized_keys ~/.ssh/authorized_keys2"
#    set +x
    if test $? -eq 0; then
        echo "Keys were put successfully"
    else
        echo "Error putting keys to $IP" 1>&2
    fi
done

for IP in $*; do
    for ver in 1 2; do
        echo -n "Checking $IP connectivity by ssh$ver... "
        ssh -q -oProtocol=${ver} -oBatchMode=yes \
          -oStrictHostKeyChecking=no $IP /bin/true
        if [ $? -eq 0 ]; then
            echo "OK"
        else
            echo "failed" 1>&2
        fi
    done
done

Then we make the script executable...

chmod a+x /usr/local/bin/ssh-keyput

... and call it as follows to generate a keypair for root@server2 and store the public key in ~/.ssh/authorized_keys file of root@server1 (server1 = 192.168.0.100):

ssh-keyput 192.168.0.100

Then we migrate vm1.example.com (VEID 102) to server1 (IP address 192.168.0.100):

vzmigrate --online 192.168.0.100 102

server2:~# vzmigrate --online 192.168.0.100 102
OPT:--online
OPT:192.168.0.100
StartingPreparingInitializingSyncingLiveSyncingCleanup
server2:~#

 

Share this page:

3 Comment(s)