add hypervisor version weigher
implements: blueprint weigh-host-by-hypervisor-version Change-Id: I36b16a388383c26bdf432030bc9e28b2fd75d120
This commit is contained in:
parent
01ffb6df85
commit
e38d6a356b
@ -1049,6 +1049,37 @@ Otherwise, it will fall back to the
|
||||
more than one value is found for a host in aggregate metadata, the minimum
|
||||
value will be used.
|
||||
|
||||
``HypervisorVersionWeigher``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. versionadded:: 28.0.0 (Bobcat)
|
||||
|
||||
Weigh hosts by their relative hypervisor version reported by the virt driver.
|
||||
|
||||
While the hypervisor_version filed for all virt drivers is an int,
|
||||
each nova virt driver uses a different algorithm to convert the hypervisor-specific
|
||||
version sequence into an int. As such the values are not directly comparable between
|
||||
hosts with different hypervisors.
|
||||
|
||||
For example, the ironic virt driver uses the ironic API micro-version as the hypervisor
|
||||
version for a given node. The libvirt driver uses the libvirt version
|
||||
i.e. Libvirt `7.1.123` becomes `700100123` vs Ironic `1.82` becomes `1`
|
||||
Hyper-V `6.3` becomes `6003`.
|
||||
|
||||
If you have a mixed virt driver deployment in the ironic vs non-ironic
|
||||
case nothing special needs to be done. ironic nodes are scheduled using custom
|
||||
resource classes so ironic flavors will never match non-ironic compute nodes.
|
||||
|
||||
If a deployment has multiple non-ironic virt drivers it is recommended to use aggregates
|
||||
to group hosts by virt driver. While this is not strictly required, it is
|
||||
desirable to avoid bias towards one virt driver.
|
||||
see :ref:`filtering_hosts_by_isolating_aggregates` and :ref:`AggregateImagePropertiesIsolation`
|
||||
for more information.
|
||||
|
||||
The default behavior of the HypervisorVersionWeigher is to select newer hosts.
|
||||
If you prefer to invert the behavior set the
|
||||
:oslo.config:option:`filter_scheduler.hypervisor_version_weight_multiplier` option
|
||||
to a negative number and the weighing has the opposite effect of the default.
|
||||
|
||||
Utilization-aware scheduling
|
||||
----------------------------
|
||||
|
@ -13,6 +13,8 @@
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
.. _filtering_hosts_by_isolating_aggregates:
|
||||
|
||||
Filtering hosts by isolating aggregates
|
||||
=======================================
|
||||
|
||||
|
@ -463,6 +463,49 @@ Possible values:
|
||||
|
||||
* An integer or float value, where the value corresponds to the multipler
|
||||
ratio for this weigher.
|
||||
"""),
|
||||
cfg.FloatOpt("hypervisor_version_weight_multiplier",
|
||||
default=1.0,
|
||||
help="""
|
||||
Hypervisor Version weight multiplier ratio.
|
||||
|
||||
The multiplier is used for weighting hosts based on the reported
|
||||
hypervisor version.
|
||||
Negative numbers indicate preferring older hosts,
|
||||
the default is to prefer newer hosts to aid with upgrades.
|
||||
|
||||
Possible values:
|
||||
|
||||
* An integer or float value, where the value corresponds to the multiplier
|
||||
ratio for this weigher.
|
||||
|
||||
Example:
|
||||
|
||||
* Strongly prefer older hosts
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[filter_scheduler]
|
||||
hypervisor_version_weight_multiplier=-1000
|
||||
|
||||
|
||||
* Moderately prefer new hosts
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[filter_scheduler]
|
||||
hypervisor_version_weight_multiplier=2.5
|
||||
|
||||
* Disable weigher influence
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[filter_scheduler]
|
||||
hypervisor_version_weight_multiplier=0
|
||||
|
||||
Related options:
|
||||
|
||||
* ``[filter_scheduler] weight_classes``
|
||||
"""),
|
||||
cfg.FloatOpt("io_ops_weight_multiplier",
|
||||
default=-1.0,
|
||||
|
39
nova/scheduler/weights/hypervisor_version.py
Normal file
39
nova/scheduler/weights/hypervisor_version.py
Normal file
@ -0,0 +1,39 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Hypervisor Version Weigher. Weigh hosts by their relative hypervior version.
|
||||
|
||||
The default is to select newer hosts. If you prefer
|
||||
to invert the behavior set the 'hypervisor_version_weight_multiplier' option
|
||||
to a negative number and the weighing has the opposite effect of the default.
|
||||
"""
|
||||
|
||||
import nova.conf
|
||||
from nova.scheduler import utils
|
||||
from nova.scheduler import weights
|
||||
|
||||
CONF = nova.conf.CONF
|
||||
|
||||
|
||||
class HypervisorVersionWeigher(weights.BaseHostWeigher):
|
||||
|
||||
def weight_multiplier(self, host_state):
|
||||
"""Override the weight multiplier."""
|
||||
return utils.get_weight_multiplier(
|
||||
host_state, 'hypervisor_version_weight_multiplier',
|
||||
CONF.filter_scheduler.hypervisor_version_weight_multiplier)
|
||||
|
||||
def _weigh_object(self, host_state, weight_properties):
|
||||
"""Higher weights win. We want newer hosts by default."""
|
||||
# convert None to 0
|
||||
return host_state.hypervisor_version or 0
|
@ -0,0 +1,97 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""
|
||||
Tests For Scheduler hypervisor version weights.
|
||||
"""
|
||||
|
||||
from nova.scheduler import weights
|
||||
from nova.scheduler.weights import hypervisor_version
|
||||
from nova import test
|
||||
from nova.tests.unit.scheduler import fakes
|
||||
|
||||
|
||||
class HypervisorVersionWeigherTestCase(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.weight_handler = weights.HostWeightHandler()
|
||||
self.weighers = [hypervisor_version.HypervisorVersionWeigher()]
|
||||
|
||||
def _get_weighed_host(self, hosts, weight_properties=None):
|
||||
if weight_properties is None:
|
||||
weight_properties = {}
|
||||
return self.weight_handler.get_weighed_objects(self.weighers,
|
||||
hosts, weight_properties)[0]
|
||||
|
||||
def _get_all_hosts(self):
|
||||
host_values = [
|
||||
('host1', 'node1', {'hypervisor_version': 1}),
|
||||
('host2', 'node2', {'hypervisor_version': 200}),
|
||||
('host3', 'node3', {'hypervisor_version': 100}),
|
||||
('host4', 'node4', {'hypervisor_version': 1000}),
|
||||
]
|
||||
return [fakes.FakeHostState(host, node, values)
|
||||
for host, node, values in host_values]
|
||||
|
||||
def test_multiplier_default(self):
|
||||
hostinfo_list = self._get_all_hosts()
|
||||
weighed_host = self._get_weighed_host(hostinfo_list)
|
||||
self.assertEqual(1.0, weighed_host.weight)
|
||||
self.assertEqual('host4', weighed_host.obj.host)
|
||||
|
||||
def test_multiplier_default_full_ordering(self):
|
||||
hostinfo_list = self._get_all_hosts()
|
||||
weighed_hosts = self.weight_handler.get_weighed_objects(
|
||||
self.weighers, hostinfo_list, {}
|
||||
)
|
||||
expected_hosts = [fakes.FakeHostState(host, node, values)
|
||||
for host, node, values in [
|
||||
('host4', 'node4', {'hypervisor_version': 1000}),
|
||||
('host2', 'node2', {'hypervisor_version': 200}),
|
||||
('host3', 'node3', {'hypervisor_version': 100}),
|
||||
('host1', 'node1', {'hypervisor_version': 1}),
|
||||
]]
|
||||
for actual, expected in zip(
|
||||
weighed_hosts,
|
||||
expected_hosts
|
||||
):
|
||||
self.assertEqual(actual.obj.host, expected.host)
|
||||
|
||||
def test_multiplier_none(self):
|
||||
multi = 0.0
|
||||
self.flags(
|
||||
hypervisor_version_weight_multiplier=multi,
|
||||
group='filter_scheduler'
|
||||
)
|
||||
hostinfo_list = self._get_all_hosts()
|
||||
weighed_host = self._get_weighed_host(hostinfo_list)
|
||||
self.assertEqual(multi, weighed_host.weight)
|
||||
|
||||
def test_multiplier_positive(self):
|
||||
multi = 2.0
|
||||
self.flags(
|
||||
hypervisor_version_weight_multiplier=multi,
|
||||
group='filter_scheduler'
|
||||
)
|
||||
hostinfo_list = self._get_all_hosts()
|
||||
weighed_host = self._get_weighed_host(hostinfo_list)
|
||||
self.assertEqual(1.0 * multi, weighed_host.weight)
|
||||
self.assertEqual('host4', weighed_host.obj.host)
|
||||
|
||||
def test_multiplier_negative(self):
|
||||
multi = -1.0
|
||||
self.flags(
|
||||
hypervisor_version_weight_multiplier=multi,
|
||||
group='filter_scheduler'
|
||||
)
|
||||
hostinfo_list = self._get_all_hosts()
|
||||
weighed_host = self._get_weighed_host(hostinfo_list)
|
||||
self.assertEqual('host1', weighed_host.obj.host)
|
@ -0,0 +1,20 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
A new hypervisor version weigher has been added to prefer selecting hosts
|
||||
with newer hypervisors installed. For the libvirt driver, this is the version
|
||||
of libvirt on the compute node not the version of qemu. As with all
|
||||
weighers this is enabled by default and its behavior can be modified using
|
||||
the new ``hypervisor_version_weight_multiplier`` config option in the
|
||||
``filter_scheduler`` section.
|
||||
upgrade:
|
||||
- |
|
||||
A new hypervisor version weigher has been added that will prefer selecting
|
||||
hosts with a newer hypervisor installed. This can help simplify rolling
|
||||
upgrades by preferring the already upgraded hosts when moving workloads around
|
||||
using live or cold migration. To restore the old behavior either remove
|
||||
the weigher from the list of enabled weighers or set
|
||||
``[filter_scheduler] hypervisor_version_weight_multiplier=0``. The default
|
||||
value of the hypervisor_version_weight_multiplier is 1 so only a mild
|
||||
preference is given to new hosts, higher values will make the effect
|
||||
more pronounced and negative values will prefer older hosts.
|
Loading…
Reference in New Issue
Block a user