Back to Cloud VPS Documentation

    OpenVZ to KVM Migration Guide

    Migrate your OpenVZ container to RamNode Cloud VPS and unlock full virtualization capabilities.

    Introduction

    This guide provides step-by-step instructions for migrating workloads from an OpenVZ container to a KVM-based virtual private server on RamNode's cloud infrastructure. KVM virtualization offers significant advantages including full kernel access, broader OS support, better resource isolation, and the ability to run Docker and other containerization technologies natively.

    The migration process involves preparing your source environment, provisioning a new KVM VPS, transferring data securely, and validating the new deployment. This guide assumes you have root or administrative access to both the source OpenVZ container and the target KVM instance.

    Understanding OpenVZ vs KVM

    FeatureOpenVZKVM
    Virtualization TypeContainer-based (OS-level)Full virtualization (hardware-level)
    KernelShared with hostIndependent per VM
    OS SupportLinux onlyLinux, Windows, BSD, etc.
    Docker SupportLimited/NoneFull native support
    Resource IsolationSoft limits, shared resourcesHard limits, dedicated resources
    Custom KernelsNot supportedFully supported
    Kernel ModulesHost-dependentLoad any module

    Prerequisites

    Source Environment (OpenVZ)

    • Root or sudo access to the OpenVZ container
    • Sufficient disk space for backups (at least 2x used space)
    • rsync, tar, and SSH client installed
    • Complete inventory of running services
    • Database export tools if applicable (mysqldump, pg_dump)

    Target Environment (RamNode KVM)

    • Active RamNode account with a provisioned KVM VPS
    • VPS sized appropriately for your workload
    • SSH access with root credentials
    • Compatible OS installed (matching or newer than source)
    • Network connectivity between source and target

    1Pre-Migration Assessment

    Step 1: Document Current Configuration

    Begin by capturing comprehensive information about your OpenVZ container:

    # System information
    uname -a
    cat /etc/os-release
    hostname
    
    # Resource usage
    df -h
    free -m
    cat /proc/cpuinfo | grep processor | wc -l

    Step 2: Inventory Running Services

    Identify all services that need to be migrated:

    # List enabled services (systemd)
    systemctl list-unit-files --state=enabled
    
    # Or for SysVinit systems
    chkconfig --list 2>/dev/null | ls /etc/rc3.d/S*
    
    # List listening ports and associated processes
    ss -tlnp
    # Or on older systems
    netstat -tlnp

    Step 3: Document Network Configuration

    # IP configuration
    ip addr show
    ip route show
    
    # DNS settings
    cat /etc/resolv.conf
    
    # Hosts file entries
    cat /etc/hosts

    Step 4: Identify OpenVZ-Specific Configurations

    Some OpenVZ configurations won't transfer directly to KVM. Check for:

    • TUN/TAP device configurations (commonly used for VPNs)
    • FUSE filesystem mounts
    • Custom kernel parameters in /etc/sysctl.conf
    • Any workarounds for OpenVZ kernel limitations
    • NFS mounts or shared storage configurations

    2Provision RamNode KVM VPS

    Step 1: Select Appropriate VPS Specifications

    Log into your RamNode client portal and provision a new KVM VPS. Consider:

    • CPU cores: Match or exceed your OpenVZ container allocation
    • RAM: Account for full kernel overhead (add 256-512MB to current usage)
    • Storage: Plan for at least 20% headroom above current usage
    • Location: Choose a datacenter geographically optimal for your users
    • Operating system: Select the same distribution and version when possible

    Step 2: Initial VPS Configuration

    Once provisioned, connect to your new KVM VPS and perform initial setup:

    # Update system packages
    apt update && apt upgrade -y     # Debian/Ubuntu
    # Or
    dnf update -y                    # RHEL/AlmaLinux/Rocky
    
    # Set timezone to match source
    timedatectl set-timezone America/New_York
    
    # Configure hostname
    hostnamectl set-hostname your-hostname

    Step 3: Configure SSH for Secure Transfer

    Set up SSH key authentication to enable secure, password-less transfers:

    # On the source OpenVZ container, generate SSH key if not exists
    ssh-keygen -t ed25519 -C "migration-key"
    
    # Copy public key to target KVM VPS
    ssh-copy-id -i ~/.ssh/id_ed25519.pub root@TARGET_IP
    
    # Test connection
    ssh root@TARGET_IP 'echo Connection successful'

    3Data Backup and Transfer

    Step 1: Export Databases

    MySQL/MariaDB:

    # Export all databases
    mysqldump --all-databases --single-transaction \
      --routines --triggers --events > /root/all_databases.sql
    
    # Or export specific database
    mysqldump --single-transaction --routines --triggers \
      database_name > /root/database_name.sql
    
    # Compress the export
    gzip /root/all_databases.sql

    PostgreSQL:

    # Export all databases
    sudo -u postgres pg_dumpall > /root/all_postgres.sql
    
    # Or export specific database
    sudo -u postgres pg_dump database_name > /root/database_name.sql
    
    # Compress the export
    gzip /root/all_postgres.sql

    Step 2: Create System Backup Archive

    Create a comprehensive backup of essential system directories:

    # Create backup archive excluding system directories
    tar czvf /root/system_backup.tar.gz \
      --exclude='/proc' \
      --exclude='/sys' \
      --exclude='/dev' \
      --exclude='/run' \
      --exclude='/tmp' \
      --exclude='/var/tmp' \
      --exclude='/root/system_backup.tar.gz' \
      --exclude='/var/cache/apt' \
      --exclude='/var/cache/yum' \
      /etc /var/www /home /root /var/lib/mysql /opt

    Step 3: Transfer Using rsync (Recommended)

    rsync provides efficient incremental transfers with progress monitoring and resume capability:

    # Install rsync on both servers if not present
    apt install rsync -y     # Debian/Ubuntu
    dnf install rsync -y     # RHEL/AlmaLinux
    
    # Transfer web content
    rsync -avzP --delete /var/www/ root@TARGET_IP:/var/www/
    
    # Transfer home directories
    rsync -avzP /home/ root@TARGET_IP:/home/
    
    # Transfer configuration files
    rsync -avzP /etc/ root@TARGET_IP:/etc_backup/
    
    # Transfer database exports
    rsync -avzP /root/*.sql.gz root@TARGET_IP:/root/

    Rsync flags: -a (archive mode), -v (verbose), -z (compress), -P (progress + resume), --delete (remove files on target not on source)

    Step 4: Alternative Transfer Using SCP

    For smaller transfers or when rsync is unavailable:

    # Transfer backup archive
    scp /root/system_backup.tar.gz root@TARGET_IP:/root/
    
    # Transfer with compression
    scp -C /root/large_file.tar.gz root@TARGET_IP:/root/

    4Target System Configuration

    Step 1: Install Required Packages

    On the target KVM VPS, install packages matching your source environment:

    # For a typical LAMP stack (Debian/Ubuntu)
    apt install -y apache2 mariadb-server php php-mysql \
      php-curl php-gd php-mbstring php-xml php-zip
    
    # For a typical LEMP stack
    apt install -y nginx mariadb-server php-fpm php-mysql \
      php-curl php-gd php-mbstring php-xml php-zip
    
    # For RHEL-based systems
    dnf install -y httpd mariadb-server php php-mysqlnd \
      php-curl php-gd php-mbstring php-xml php-zip

    Step 2: Restore Configuration Files

    Important: Carefully merge configuration files rather than blindly overwriting. Some paths and settings differ between OpenVZ and KVM environments.

    # Create backup of default configs
    cp -r /etc/apache2 /etc/apache2.default
    cp -r /etc/nginx /etc/nginx.default
    
    # Restore web server configurations
    cp /etc_backup/apache2/sites-available/* /etc/apache2/sites-available/
    cp /etc_backup/apache2/sites-enabled/* /etc/apache2/sites-enabled/
    
    # Or for nginx
    cp /etc_backup/nginx/sites-available/* /etc/nginx/sites-available/
    cp /etc_backup/nginx/sites-enabled/* /etc/nginx/sites-enabled/
    
    # Restore PHP configuration
    cp /etc_backup/php/*/php.ini /etc/php/*/
    
    # Validate configurations
    apache2ctl configtest
    nginx -t

    Step 3: Import Databases

    # Start MariaDB/MySQL
    systemctl start mariadb
    systemctl enable mariadb
    
    # Secure the installation
    mysql_secure_installation
    
    # Import databases
    gunzip /root/all_databases.sql.gz
    mysql < /root/all_databases.sql
    
    # For PostgreSQL
    systemctl start postgresql
    systemctl enable postgresql
    sudo -u postgres psql < /root/all_postgres.sql

    Step 4: Set File Permissions

    # Set web directory ownership
    chown -R www-data:www-data /var/www/
    
    # For RHEL-based systems
    chown -R apache:apache /var/www/
    
    # Set appropriate permissions
    find /var/www -type d -exec chmod 755 {} \;
    find /var/www -type f -exec chmod 644 {} \;
    
    # Restore home directory ownership
    for dir in /home/*/; do
      user=$(basename "$dir")
      chown -R "$user:$user" "$dir"
    done

    Step 5: Update Network-Specific Configurations

    # Search for old IP references
    grep -r "OLD_IP_ADDRESS" /etc/
    grep -r "OLD_IP_ADDRESS" /var/www/
    
    # Common files requiring updates:
    # - /etc/hosts
    # - Virtual host configurations
    # - Application database connection strings
    # - SSL certificate paths
    
    # Update hosts file
    echo "NEW_IP_ADDRESS hostname.domain.com hostname" >> /etc/hosts

    5Service Activation and Testing

    Step 1: Enable and Start Services

    # Enable services to start on boot
    systemctl enable mariadb apache2 php-fpm
    
    # Start services
    systemctl start mariadb
    systemctl start php-fpm
    systemctl start apache2
    
    # Check service status
    systemctl status mariadb apache2 php-fpm

    Step 2: Configure Firewall

    KVM VPS instances have full firewall control:

    # Using UFW (Ubuntu/Debian)
    ufw allow 22/tcp      # SSH
    ufw allow 80/tcp      # HTTP
    ufw allow 443/tcp     # HTTPS
    ufw enable
    
    # Using firewalld (RHEL/AlmaLinux)
    firewall-cmd --permanent --add-service=ssh
    firewall-cmd --permanent --add-service=http
    firewall-cmd --permanent --add-service=https
    firewall-cmd --reload

    Step 3: Verify Service Functionality

    Test each service systematically:

    1. Web Server Test: Access your site via IP address or temporary hostname
    2. Database Connectivity: Verify applications can connect to databases
    3. Email Functionality: Test sending and receiving if applicable
    4. SSL Certificates: Reinstall or transfer SSL certificates
    5. Cron Jobs: Verify scheduled tasks are properly configured
    # Check web server response
    curl -I http://localhost
    
    # Test database connection
    mysql -u root -p -e "SHOW DATABASES;"
    
    # Verify cron jobs
    crontab -l
    ls -la /etc/cron.d/

    Step 4: SSL Certificate Installation

    If using Let's Encrypt, install certbot and obtain new certificates:

    # Install certbot
    apt install certbot python3-certbot-apache -y
    
    # Obtain certificate
    certbot --apache -d yourdomain.com -d www.yourdomain.com
    
    # Or for nginx
    apt install certbot python3-certbot-nginx -y
    certbot --nginx -d yourdomain.com -d www.yourdomain.com
    
    # Verify auto-renewal
    certbot renew --dry-run

    6DNS Migration and Go-Live

    Step 1: Update DNS Records

    Once testing confirms proper functionality, update DNS records:

    1. Lower TTL values 24-48 hours before migration (e.g., 300 seconds)
    2. Update A records to point to new IP address
    3. Update any AAAA records if using IPv6
    4. Verify MX records if migrating mail services
    5. After propagation, restore TTL to normal values

    Step 2: Final Data Synchronization

    Perform a final rsync to capture any changes during DNS propagation:

    # Final sync of web content
    rsync -avzP --delete /var/www/ root@TARGET_IP:/var/www/
    
    # Final database export and import if needed
    mysqldump --all-databases --single-transaction | \
      ssh root@TARGET_IP 'mysql'

    Step 3: Monitor and Verify

    Monitor the new server closely during the first 24-48 hours:

    # Monitor logs in real-time
    tail -f /var/log/apache2/error.log
    tail -f /var/log/nginx/error.log
    tail -f /var/log/mysql/error.log
    
    # Monitor system resources
    htop
    # Or
    watch -n 1 'free -m; echo; df -h'

    Troubleshooting Common Issues

    Permission Denied Errors

    # Reset SELinux contexts (RHEL-based)
    restorecon -Rv /var/www/
    
    # Check and fix Apache/Nginx user ownership
    ps aux | grep -E 'apache|nginx|httpd'
    chown -R www-data:www-data /var/www/

    Database Connection Failures

    # Check user grants
    mysql -e "SELECT user,host FROM mysql.user;"
    
    # Reset user password if needed
    mysql -e "ALTER USER 'user'@'localhost' IDENTIFIED BY 'password';"
    mysql -e "FLUSH PRIVILEGES;"

    Service Won't Start

    # Check service status and logs
    systemctl status servicename
    journalctl -xe -u servicename
    
    # Test configuration syntax
    apache2ctl configtest
    nginx -t
    php-fpm -t

    Taking Advantage of KVM Features

    Now that you're running on KVM, you can leverage features that weren't available on OpenVZ:

    Docker and Containerization

    # Install Docker
    curl -fsSL https://get.docker.com | sh
    systemctl enable docker
    systemctl start docker
    
    # Verify installation
    docker run hello-world

    Custom Kernel Parameters

    # Full sysctl control
    echo 'net.core.somaxconn = 65535' >> /etc/sysctl.conf
    echo 'vm.swappiness = 10' >> /etc/sysctl.conf
    sysctl -p

    Kernel Module Loading

    # Load modules as needed
    modprobe wireguard
    modprobe nf_conntrack
    
    # Persist across reboots
    echo 'wireguard' >> /etc/modules-load.d/wireguard.conf

    Post-Migration Checklist

    • All data transferred and verified
    • Databases imported and accessible
    • Web applications functional
    • SSL certificates installed/renewed
    • DNS records updated
    • Firewall configured
    • Backups configured on new server
    • Monitoring/alerting set up
    • Cron jobs verified
    • Email functionality tested
    • Old OpenVZ container can be decommissioned

    Migration Complete!

    Keep your old OpenVZ container running for at least one week after migration as a fallback option. Once you've confirmed everything is working correctly, you can safely decommission the old container.