Гид по технологиям

Как выполнить живую миграцию контейнеров OpenVZ

• 6 min read • DevOps • Обновлено 27 Nov 2025
Живая миграция контейнеров OpenVZ
Живая миграция контейнеров OpenVZ

Version 1.0
Author: Falko Timme

Важно: описанный процесс предполагает, что вы действуете под root и контролируете оба хоста. Всегда тестируйте на стенде перед продакшеном.

Содержание

  • Предварительное примечание
  • Подготовка passwordless SSH
  • Запуск live‑миграции и проверка
  • Обратная миграция
  • Контрольный чеклист перед миграцией
  • Отладка и типичные ошибки
  • Альтернативные подходы и рекомендации
  • Роль‑базированные задачи
  • Краткий глоссарий
  • Ссылки

1 Предварительное примечание

В примерах используются следующие хосты и контейнер:

  • OpenVZ хост 1: server.example.com, IP: 192.168.0.100
  • OpenVZ хост 2: server2.example.com, IP: 192.168.0.101
  • виртуальная машина: vm1.example.com, IP: 192.168.0.102, VEID 102

Оба OpenVZ‑хоста в статье работают на Debian Lenny, но процедура в целом не зависит от дистрибутива. Я не даю гарантий — тестируйте в вашей среде.

2 Подготовка: passwordless SSH между хостами

Ключевое требование для корректной live‑миграции: root на исходном сервере должен иметь возможность подключаться по SSH к целевому серверу без запроса пароля. Это означает, что на целевом сервере разрешены SSH‑логины для root (проверьте /etc/ssh/sshd_config) и в ~/.ssh/authorized_keys присутствует публичный ключ.

Ниже показан удобный bash‑скрипт ssh-keyput, который генерирует ключи при необходимости и добавляет публичные ключи в ~/.ssh/authorized_keys удалённого хоста. Создайте скрипт на исходном хосте:

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

Сделайте скрипт исполняемым:

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

И запустите его, чтобы скопировать публичный ключ root@server1 в root@server2:

ssh-keyput 192.168.0.101

После выполнения вы увидите сообщения о генерации ключей и проверке подключения. Например, одна из проверок может вернуть OK для ssh2.

Примечание: если в вашей среде отключены SSH‑логины для root, настройте отдельного пользователя с правами доступа или используйте временно разрешение, но учтите риски безопасности.

3 Проверка состояния контейнера перед миграцией

Убедитесь, что контейнер запущен на исходном хосте и имеет нужный VEID. На исходном хосте выполните:

vzlist -a

Ожидаемый вывод будет содержать строку с VEID 102, IP 192.168.0.102 и hostname vm1.example.com.

4 Запуск live‑миграции

Команда для запуска миграции в режиме онлайн (live):

vzmigrate --online 192.168.0.101 102

Где 192.168.0.101 — IP целевого хоста, а 102 — VEID контейнера.

Пример вывода команды:

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

Во время процесса гостевая ОС должна оставаться доступной; запущенные pings/ssh‑сессии не должны прерываться.

После завершения на исходном хосте vzlist не будет показывать контейнер:

vzlist -a

А на целевом хосте контейнер должен появиться и быть в статусе running:

vzlist -a

Пример:

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

5 Обратная миграция

Если нужно вернуть контейнер на исходный сервер, повторите процесс, но в обратную сторону: создайте passwordless SSH из нового текущего хоста в целевой и запустите vzmigrate с указанием IP‑адреса исходного.

Снова используйте скрипт ssh-keyput (создайте его на server2 или скопируйте), сделайте исполняемым и запустите:

ssh-keyput 192.168.0.100

Затем на server2 выполните:

vzmigrate --online 192.168.0.100 102

И проверьте vzlist на server1.

6 Контрольный чеклист перед миграцией

  • Полная резервная копия данных контейнера (если возможно).
  • Проверка сетевой связности между хостами (ping, ssh).
  • Наличие свободного дискового места на целевом хосте для образа контейнера.
  • Синхронизация версий OpenVZ/ядра (желательно одинаковые версии).
  • Настроен passwordless SSH для root или подходящего пользователя.
  • Спланировано окно миграции и уведомлены пользователи/заинтересованные стороны.
  • Проверка запущенных служб в контейнере, которые чувствительны к миграции (например, сервисы с держанием TCP‑сессий).

7 Отладка и типичные ошибки

  • Ошибка аутентификации SSH: убедитесь, что публичный ключ действительно добавлен в ~/.ssh/authorized_keys целевого хоста и права на ~/.ssh/authorized_keys = 600.
  • Разные версии OpenVZ/ядра: миграция может завершиться с ошибками. Лучший сценарий — одинаковые версии на обоих хостах.
  • Недостаток дискового пространства: миграция может не завершиться — проверьте свободное место.
  • Падает сеть во время live‑фазы: в зависимости от состояния данных миграция может завершиться неудачно; подготовьте откатный план.

Совет по диагностике: запуск vzmigrate с повышенной подробностью и просмотр логов /var/log/vzctl/* и системных логов может подсказать причину.

8 Когда живая миграция может не пройти (контрпримеры)

  • Контейнер использует специфические аппаратные ресурсы, привязанные к исходному хосту (например, локальные устройства/файловые системы, которые не доступны на целевом хосте).
  • Значительные различия в конфигурации сети/bridge/interfaces между хостами.
  • Неоднородные версии OpenVZ или ядра, несовместимые возможности миграции.

В таких случаях используйте офлайн‑миграцию (остановка контейнера, копирование данных, запуск на другом хосте) или настройку репликации на уровне приложений.

9 Альтернативные подходы

  • Офлайн‑миграция: vzctl stop, копирование данных (rsync, tar), запуск на другом хосте. Надёжнее для несовместимых окружений.
  • Репликация на уровне приложений: настройка кластера/реплик базы данных и переключение трафика.
  • Контейнеризация в LXC/Docker и использование инструментов оркестрации для миграций — долгосрочная альтернатива.

10 Роль‑базированные чеклисты

Администратор (тот, кто выполняет миграцию):

  • Провёл резервное копирование.
  • Настроил passwordless SSH.
  • Проверил совместимость версий OpenVZ/ядра.
  • Выполнил vzmigrate и мониторил логи.

Оператор поддержки (коммуникация и тесты):

  • Уведомил пользователей о текущей операции.
  • Выполнил smoke‑тесты сервисов в контейнере (HTTP, DB ping и т.д.).
  • Проверил доступность метрик и мониторинга.

11 Мини‑методология для безопасной live‑миграции

  1. Тестируйте на стенде с идентичными версиями программного обеспечения.
  2. Выполните полную резервную копию данных контейнера.
  3. Настройте passwordless SSH и проверьте соединение.
  4. Запустите миграцию в нерабочее время, если возможно.
  5. Наблюдайте за поведением сервисов; выполняйте smoke‑тесты.
  6. При проблемах — откатите или выполните офлайн‑копирование.

12 Пример плейбука / шаги (коротко)

  • Проверка: vzlist -a, df -h, uname -r
  • Настройка ключей: ssh-keyput
  • Старт миграции: vzmigrate –online
  • Проверка на целевом хосте: vzlist -a
  • Smoke‑тесты: ping, curl, mysqladmin ping и т.п.

13 Краткий глоссарий (1‑строчные определения)

  • VEID: идентификатор контейнера OpenVZ.
  • vzmigrate: утилита для миграции контейнера между хостами OpenVZ.
  • passwordless SSH: настройка ssh‑аутентификации с помощью ключей, без ввода пароля.

14 Риски и рекомендации по безопасности

  • Разрешение root‑логинов по SSH увеличивает риск. Лучше использовать ограниченные ключи, временные права или изолированные сети управления.
  • Храните приватные ключи безопасно, используйте passphrase и ssh‑агент при необходимости.

15 Критерии приёмки

  • Контейнер запущен на целевом хосте и статус running.
  • Все критичные сервисы контейнера проходят smoke‑тесты.
  • Пользовательские сессии и соединения не прерываются (проверено ping/ssh).

16 Отказ и откат

Если миграция прошла с ошибками или сервисы недоступны после переноса:

  1. Попробуйте повторную миграцию обратно (при наличии passwordless SSH в обратную сторону).
  2. Если повторная миграция невозможна — остановите контейнер на целевом хосте, выполните офлайн‑копирование данных на исходный хост и запустите контейнер локально.
  3. Сообщите пользователям и задокументируйте шаги отката.

17 Ссылки


Краткое резюме:

  • Настройте passwordless SSH между хостами.
  • Убедитесь в совместимости версий OpenVZ/ядра и наличии места.
  • Выполните vzmigrate –online и проверьте контейнер на целевом хосте.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро