[pve-devel] [PATCH v2] allow dedicated migration network, bug #1177

Thomas Lamprecht t.lamprecht at proxmox.com
Mon Oct 31 09:42:31 CET 2016


Without this patch we use the network were the cluster traffic runs
for sending migration traffic. This is not ideal as it may hinder
cluster traffic. Further some users have a powerful network which
would be perfect for migrations, with this patch they can run the
migration traffic over such a network without having the corosync
traffic on the same network.

The network is configurable through /etc/pve/datacenter.cfg which
got a new property, namely migration. migration has two
subproperties: type (replaces the old migration_unsecure property)
and network.

For the case of a network failure or that a VM has to be moved over
another network for arbitrary other reasons I added the
migration_type and migration_network parameters to qm migrate (and
respectively vm_start as this gets used on migration).
They allow overwriting the datacenter.cfg settings.

Fixes bug #1177

Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---

changes since v1:
* fix a bug when using a IPv6 network
* fix a bug when setting the migration address on the qm migrate
  command directly (was not passed to the qm start command on the
  other node)


 PVE/API2/Qemu.pm   | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 PVE/QemuMigrate.pm | 17 ++++++++++++++---
 PVE/QemuServer.pm  | 14 +++++++++++---
 3 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index ac04dff..66dc69a 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -1626,6 +1626,20 @@ __PACKAGE__->register_method({
 	    skiplock => get_standard_option('skiplock'),
 	    stateuri => get_standard_option('pve-qm-stateuri'),
 	    migratedfrom => get_standard_option('pve-node',{ optional => 1 }),
+	    migration_type => {
+		type => 'string',
+		enum => ['secure', 'insecure'],
+		description => "Migration traffic is encrypted using an SSH " .
+		  "tunnel by default. On secure, completely private networks " .
+		  "this can be disabled to increase performance.",
+		optional => 1,
+	    },
+	    migration_network => {
+		type => 'string',
+		format => 'CIDR',
+		description => "CIDR of the (sub) network that is used for migration.",
+		optional => 1,
+	    },
 	    machine => get_standard_option('pve-qm-machine'),
 	},
     },
@@ -1657,6 +1671,14 @@ __PACKAGE__->register_method({
 	raise_param_exc({ migratedfrom => "Only root may use this option." })
 	    if $migratedfrom && $authuser ne 'root at pam';
 
+	my $migration_type = extract_param($param, 'migration_type');
+	raise_param_exc({ migration_type => "Only root may use this option." })
+	    if $migration_type && $authuser ne 'root at pam';
+
+	my $migration_network = extract_param($param, 'migration_network');
+	raise_param_exc({ migration_network => "Only root may use this option." })
+	    if $migration_network && $authuser ne 'root at pam';
+
 	# read spice ticket from STDIN
 	my $spice_ticket;
 	if ($stateuri && ($stateuri eq 'tcp') && $migratedfrom && ($rpcenv->{type} eq 'cli')) {
@@ -1697,7 +1719,7 @@ __PACKAGE__->register_method({
 		syslog('info', "start VM $vmid: $upid\n");
 
 		PVE::QemuServer::vm_start($storecfg, $vmid, $stateuri, $skiplock, $migratedfrom, undef,
-					  $machine, $spice_ticket);
+					  $machine, $spice_ticket, $migration_network, $migration_type);
 
 		return;
 	    };
@@ -2648,6 +2670,20 @@ __PACKAGE__->register_method({
 		description => "Allow to migrate VMs which use local devices. Only root may use this option.",
 		optional => 1,
 	    },
+	    migration_type => {
+		type => 'string',
+		enum => ['secure', 'insecure'],
+		description => "Migration traffic is encrypted using an SSH " .
+		  "tunnel by default. On secure, completely private networks " .
+		  "this can be disabled to increase performance.",
+		optional => 1,
+	    },
+	    migration_network => {
+		type => 'string',
+		format => 'CIDR',
+		description => "CIDR of the (sub) network that is used for migration.",
+		optional => 1,
+	    },
 	},
     },
     returns => {
@@ -2677,6 +2713,13 @@ __PACKAGE__->register_method({
 	raise_param_exc({ force => "Only root may use this option." })
 	    if $param->{force} && $authuser ne 'root at pam';
 
+	raise_param_exc({ migration_type => "Only root may use this option." })
+	    if $param->{migration_type} && $authuser ne 'root at pam';
+
+	# allow root only until better network permissions are available
+	raise_param_exc({ migration_network => "Only root may use this option." })
+	    if $param->{migration_network} && $authuser ne 'root at pam';
+
 	# test if VM exists
 	my $conf = PVE::QemuConfig->load_config($vmid);
 
diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm
index 22a49ef..8a65fe6 100644
--- a/PVE/QemuMigrate.pm
+++ b/PVE/QemuMigrate.pm
@@ -459,9 +459,20 @@ sub phase2 {
     # secure migration use UNIX sockets now, this *breaks* compatibilty when trying
     # to migrate from new to old but *not* from old to new.
     my $datacenterconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
-    my $secure_migration = ($datacenterconf->{migration_unsecure}) ? 0 : 1;
 
-    if (!$secure_migration) {
+    my $migration_type = 'secure';
+    if (defined($self->{opts}->{migration_type})) {
+	$migration_type = $self->{opts}->{migration_type};
+    } elsif (defined($datacenterconf->{migration}->{type})) {
+        $migration_type = $datacenterconf->{migration}->{type};
+    }
+
+    push @$cmd, '--migration_type', $migration_type;
+
+    push @$cmd, '--migration_network', $self->{opts}->{migration_network}
+      if $self->{opts}->{migration_network};
+
+    if ($migration_type eq 'insecure') {
 	push @$cmd, '--stateuri', 'tcp';
     } else {
 	push @$cmd, '--stateuri', 'unix';
@@ -503,7 +514,7 @@ sub phase2 {
 
     die "unable to detect remote migration address\n" if !$raddr;
 
-    if ($secure_migration) {
+    if ($migration_type eq 'secure') {
 	$self->log('info', "start remote tunnel");
 
 	if ($ruri =~ /^unix:/) {
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 7cb5ffc..9999b83 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -4429,7 +4429,7 @@ sub vmconfig_update_disk {
 
 sub vm_start {
     my ($storecfg, $vmid, $statefile, $skiplock, $migratedfrom, $paused,
-	$forcemachine, $spice_ticket) = @_;
+	$forcemachine, $spice_ticket, $migration_network, $migration_type) = @_;
 
     PVE::QemuConfig->lock_config($vmid, sub {
 	my $conf = PVE::QemuConfig->load_config($vmid, $migratedfrom);
@@ -4459,10 +4459,18 @@ sub vm_start {
 		my $localip = "localhost";
 		my $datacenterconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
 		my $nodename = PVE::INotify::nodename();
-		if ($datacenterconf->{migration_unsecure}) {
+
+		if ($migration_type eq 'insecure') {
+		    my $migrate_network_addr = PVE::Cluster::get_local_migration_ip($migration_network);
+		    if ($migrate_network_addr) {
+			$localip = $migrate_network_addr;
+		    } else {
 			$localip = PVE::Cluster::remote_node_ip($nodename, 1);
-			$localip = "[$localip]" if Net::IP::ip_is_ipv6($localip);
+		    }
+
+		    $localip = "[$localip]" if Net::IP::ip_is_ipv6($localip);
 		}
+
 		my $pfamily = PVE::Tools::get_host_address_family($nodename);
 		$migrate_port = PVE::Tools::next_migrate_port($pfamily);
 		$migrate_uri = "tcp:${localip}:${migrate_port}";
-- 
2.1.4





More information about the pve-devel mailing list