Index ¦ Archives ¦ Atom

Unpacking the Nova Scheduler (part 1 of ?)

As of late 2015 the scheduler part of Nova (the part of OpenStack that manages compute resources) is responsible for determining on which compute nodes a set of VMs (or other compute resources) will be placed when an agent (human or otherwise) requests a set of servers.

In the future it will be responsible for scheduling in a more general fashion and will hopefully not be a part of Nova. To get it there it needs to become more tidy and contained. To make it more tidy and contained it needs to be understood. I'm new to the Nova codebase so I've gone on a little field trip through the code. These are notes from that exploration. There will likely be multiple parts. Some of this may be wrong. Please help me correct it if it is.

From a user's standpoint the scheduler is mostly a black box. The client asks for a server or servers to be created that match a set of requirements and gets back a URL where the progress of the build can be tracked. The scheduler does its job asynchronously, selecting a list of potential destinations for the requested servers in a task that is spawned during the request.

The body of the POST to create the servers contains some attributes (e.g. availability zones, scheduler hints, flavor choice) that will be used to constrain the selected destinations. Details of that specification will be described in a later post.

The HTTP API calls create on the compute API, realized as nova.compute.api.API.create. This validates all inputs and then calls build_instances methods through a series of layers of indirection that eventually call conductor.manager.build_instances.

An aside about the architecture of Nova may be useful here. Different types of service run as indepdendent processes which communicate using RPC driven by an AMQP message bus. The RPC API is considered private and the only stable interface is the HTTP API. At the center of the several services is a service called the conductor which, as you might expect, conducts most of the activity by acting on requests from service A and coordinating the required actions on other services, B. The conductor is the primary conduit with the storage layer.

Much, but not yet all, of this conducting happens with data encapsulated in something called versioned objects. These allow the different services in Nova to be updgraded on different timetables. The conductor can transform an object that is currently a version a target service cannot handle into a version it can (this is an oversimplification, but gets the main gist).

The HTTP API service and the scheduler service don't talk. The HTTP API service has been asked to create some instances, so it tells the conductor it needs to build_instances but doesn't know it needs to schedule them. The conductor does.

The conductor manager has a scheduler client which calls select_destinations on the scheduler itself. Unlike the earlier request to build_instances, this is a synchronous call that waits for a result. The result is an ordered lists of hosts. These hosts are paired with the requested servers and builds of the instances are started.

That list of hosts is constrained by request_spec and filter_properties. In the past these were separate objects. In the evolving scheduler, these will be represented by a RequestSpec object. The details of what this is for and how it is created and used will be in the next post.

© Chris Dent. Built using Pelican. Theme by Giulio Fidente on github.