Merge "add hypervisor version weigher"

This commit is contained in:
Zuul 2023-05-04 01:29:06 +00:00 committed by Gerrit Code Review
commit ad3b3681b6
6 changed files with 232 additions and 0 deletions

View File

@ -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
----------------------------

View File

@ -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
=======================================

View File

@ -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,

View 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

View File

@ -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)

View File

@ -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.