Add live migration support and firewall rules

The nova live migration url was set to qemu_ssh//... which doesn't work
on Red Hat distributions as the user in the packages is set up with a
nologin shell.
The desired way to do live migrations is to use qemu+tcp://...
The libvirt config option (listen_tcp) is already set to 1 in this
patch - https://review.openstack.org/#/c/106436/

Fixes: rhbz#1122457, rhbz#1122703, rhbz#1117524

Change-Id: I36055847fa293edb63a972a0c9f597bc2e27b7ab
This commit is contained in:
Vladan Popovic
2014-07-28 12:03:10 +02:00
committed by Gilles Dubreuil
parent 1575898829
commit 2ff66be39c
5 changed files with 74 additions and 33 deletions

View File

@@ -195,6 +195,9 @@ Nova Options
**CONFIG_NOVA_COMPUTE_PRIVIF**
Private interface for Flat DHCP on the Nova compute servers.
**CONFIG_NOVA_COMPUTE_MIGRATE_PROTOCOL**
Protocol used for instance migration. Allowed values are tcp and ssh. Note that by defaul nova user is created with /sbin/nologin shell so that ssh protocol won't be working. To make ssh protocol work you have to fix nova user on compute hosts manually.
**CONFIG_NOVA_NETWORK_HOSTS**
List of IP address of the servers on which to install the Nova Network service.

View File

@@ -90,6 +90,24 @@ def initConfig(controller):
"USE_DEFAULT": False,
"NEED_CONFIRM": False,
"CONDITION": False},
{"CMD_OPTION": "novacompute-migrate-protocol",
"USAGE": ("Protocol used for instance migration. Allowed values "
"are tcp and ssh. Note that by defaul nova user is "
"created with /sbin/nologin shell so that ssh protocol "
"won't be working. To make ssh protocol work you have "
"to fix nova user on compute hosts manually."),
"PROMPT": ("Enter protocol which will be used for instance "
"migration"),
"OPTION_LIST": ['tcp', 'ssh'],
"VALIDATORS": [validators.validate_options],
"DEFAULT_VALUE": 'tcp',
"MASK_INPUT": False,
"LOOSE_VALIDATION": True,
"CONF_NAME": "CONFIG_NOVA_COMPUTE_MIGRATE_PROTOCOL",
"USE_DEFAULT": False,
"NEED_CONFIRM": False,
"CONDITION": False},
],
"NOVA_NETWORK": [
@@ -309,7 +327,7 @@ def initSequences(controller):
{'title': 'Creating ssh keys for Nova migration',
'functions': [create_ssh_keys]},
{'title': 'Gathering ssh host keys for Nova migration',
'functions': [gather_host_keys]},
'functions': [gather_host_keys]},
{'title': 'Adding Nova Compute manifest entries',
'functions': [create_compute_manifest]},
{'title': 'Adding Nova Scheduler manifest entries',
@@ -434,12 +452,23 @@ def create_conductor_manifest(config, messages):
def create_compute_manifest(config, messages):
global compute_hosts, network_hosts
migrate_protocol = config['CONFIG_NOVA_COMPUTE_MIGRATE_PROTOCOL']
if migrate_protocol == 'ssh':
config['CONFIG_NOVA_COMPUTE_MIGRATE_URL'] = (
'qemu+ssh://nova@%s/system?no_verify=1&'
'keyfile=/etc/nova/ssh/nova_migration_key'
)
else:
config['CONFIG_NOVA_COMPUTE_MIGRATE_URL'] = (
'qemu+tcp://nova@%s/system'
)
ssh_hostkeys = ''
for host in compute_hosts:
try:
host_name, host_aliases, host_addrs = socket.gethostbyaddr(host)
hostname, aliases, addrs = socket.gethostbyaddr(host)
except socket.herror:
host_name, host_aliases, host_addrs = (host, [], [])
hostname, aliases, addrs = (host, [], [])
for hostkey in config['HOST_KEYS_%s' % host].split('\n'):
hostkey = hostkey.strip()
@@ -447,9 +476,9 @@ def create_compute_manifest(config, messages):
continue
_, host_key_type, host_key_data = hostkey.split()
config['SSH_HOST_NAME'] = host_name
config['SSH_HOST_NAME'] = hostname
config['SSH_HOST_ALIASES'] = ','.join(
'"%s"' % addr for addr in host_aliases + host_addrs
'"%s"' % addr for addr in aliases + addrs
)
config['SSH_HOST_KEY'] = host_key_data
config['SSH_HOST_KEY_TYPE'] = host_key_type
@@ -459,15 +488,16 @@ def create_compute_manifest(config, messages):
config["CONFIG_NOVA_COMPUTE_HOST"] = host
manifestdata = getManifestTemplate("nova_compute.pp")
for c_host in compute_hosts:
config['FIREWALL_SERVICE_NAME'] = "nova qemu migration"
config['FIREWALL_PORTS'] = "'49152-49215'"
config['FIREWALL_CHAIN'] = "INPUT"
config['FIREWALL_PROTOCOL'] = 'tcp'
config['FIREWALL_ALLOWED'] = "'%s'" % c_host
config['FIREWALL_SERVICE_ID'] = ("nova_qemu_migration_%s_%s"
% (host, c_host))
manifestdata += getManifestTemplate("firewall.pp")
if migrate_protocol == 'ssh':
for c_host in compute_hosts:
config['FIREWALL_SERVICE_NAME'] = "nova qemu migration"
config['FIREWALL_PORTS'] = "'49152-49215'"
config['FIREWALL_CHAIN'] = "INPUT"
config['FIREWALL_PROTOCOL'] = 'tcp'
config['FIREWALL_ALLOWED'] = "'%s'" % c_host
config['FIREWALL_SERVICE_ID'] = ("nova_qemu_migration_%s_%s"
% (host, c_host))
manifestdata += getManifestTemplate("firewall.pp")
if config['CONFIG_VMWARE_BACKEND'] == 'y':
manifestdata += getManifestTemplate("nova_compute_vmware.pp")
@@ -502,10 +532,12 @@ def create_compute_manifest(config, messages):
manifestdata += getManifestTemplate(mq_template)
manifestdata += getManifestTemplate("nova_ceilometer.pp")
config['FIREWALL_PORTS'] = ['5900-5999']
if migrate_protocol == 'tcp':
config['FIREWALL_PORTS'].append('16509')
config['FIREWALL_ALLOWED'] = "'%s'" % config['CONFIG_CONTROLLER_HOST']
config['FIREWALL_SERVICE_NAME'] = "nova compute"
config['FIREWALL_SERVICE_ID'] = "nova_compute"
config['FIREWALL_PORTS'] = "'5900-5999'"
config['FIREWALL_CHAIN'] = "INPUT"
config['FIREWALL_PROTOCOL'] = 'tcp'
manifestdata += getManifestTemplate("firewall.pp")

View File

@@ -1,4 +1,13 @@
$private_key = {
type => '%(NOVA_MIGRATION_KEY_TYPE)s',
key => '%(NOVA_MIGRATION_KEY_SECRET)s',
}
$public_key = {
type => '%(NOVA_MIGRATION_KEY_TYPE)s',
key => '%(NOVA_MIGRATION_KEY_PUBLIC)s',
}
class { "nova":
glance_api_servers => "%(CONFIG_CONTROLLER_HOST)s:9292",
qpid_hostname => "%(CONFIG_AMQP_HOST)s",
@@ -9,13 +18,7 @@ class { "nova":
qpid_protocol => '%(CONFIG_AMQP_PROTOCOL)s',
verbose => true,
debug => %(CONFIG_DEBUG_MODE)s,
nova_public_key => {
type => '%(NOVA_MIGRATION_KEY_TYPE)s',
key => '%(NOVA_MIGRATION_KEY_PUBLIC)s',
},
nova_private_key => {
type => '%(NOVA_MIGRATION_KEY_TYPE)s',
key => '%(NOVA_MIGRATION_KEY_SECRET)s',
},
nova_public_key => $public_key,
nova_private_key => $private_key,
nova_shell => '/bin/bash',
}

View File

@@ -1,4 +1,13 @@
$private_key = {
type => '%(NOVA_MIGRATION_KEY_TYPE)s',
key => '%(NOVA_MIGRATION_KEY_SECRET)s',
}
$public_key = {
type => '%(NOVA_MIGRATION_KEY_TYPE)s',
key => '%(NOVA_MIGRATION_KEY_PUBLIC)s',
}
class { "nova":
glance_api_servers => "%(CONFIG_CONTROLLER_HOST)s:9292",
rabbit_host => "%(CONFIG_AMQP_HOST)s",
@@ -7,13 +16,7 @@ class { "nova":
rabbit_password => '%(CONFIG_AMQP_AUTH_PASSWORD)s',
verbose => true,
debug => %(CONFIG_DEBUG_MODE)s,
nova_public_key => {
type => '%(NOVA_MIGRATION_KEY_TYPE)s',
key => '%(NOVA_MIGRATION_KEY_PUBLIC)s',
},
nova_private_key => {
type => '%(NOVA_MIGRATION_KEY_TYPE)s',
key => '%(NOVA_MIGRATION_KEY_SECRET)s',
},
nova_public_key => $public_key,
nova_private_key => $private_key,
nova_shell => '/bin/bash',
}

View File

@@ -1,3 +1,4 @@
package{'python-cinderclient':
before => Class["nova"]
}
@@ -21,7 +22,7 @@ file { '/etc/nova/ssh/nova_migration_key':
nova_config{
"DEFAULT/volume_api_class": value => "nova.volume.cinder.API";
"libvirt/live_migration_uri": value => "qemu+ssh://nova@%%s/system?no_verify=1&keyfile=/etc/nova/ssh/nova_migration_key";
"libvirt/live_migration_uri": value => "%(CONFIG_NOVA_COMPUTE_MIGRATE_URL)s";
}
class {"nova::compute":
@@ -74,4 +75,3 @@ exec {'tuned-virtual-host':
command => '/usr/sbin/tuned-adm profile virtual-host',
require => Service['tuned'],
}