Configure unified limits for quota enforcement

Unified limits is a quota system that stores operational limits in the Identity (keystone) service to optimize cloud resources. Use unified limits to enforce default quotas globally or specific quotas at the project level.

There are three steps for quota enforcement:

  1. Quota limits are retrieved by calling the unified limits API of the Identity service.
  2. Quota usage is counted from the Placement API service.
  3. Quota is enforced locally by using the oslo.limit limit enforcement library.

In unified limits, the following terms are different from legacy quota limits:

  • Registered limit: A default limit that applies to all projects
  • Limit: A project-scoped limit that applies to a particular project

To enable unified limits, you must configure the nova-api service and the nova-conductor services for each cell. To manage quota limits in the Identity service, cloud operators must use the OpenStackClient (OSC) registered limit and limit commands.

Prerequisites

  • You have installed Red Hat OpenStack Services on OpenShift (RHOSO) 18.0.
  • You are logged on to a workstation that has access to the RHOSO control plane as a user with cluster-admin privileges.
  • The oc and podman command line tools are installed on the workstation.

Enable unified limits

To enable unified limits, you must configure the nova-api service and the nova-conductor services for each cell. You can also define a list of resources to either require or ignore registered limits.

About this task

Important

A server in ERROR state that has never been scheduled to a Compute host does not have Placement allocations, so it does not consume quota usage for cores and RAM.

A server in SHELVED_OFFLOADED state does not have Placement allocations, so it does not consume quota usage for cores and RAM. Because of this, a request to unshelve a server might be rejected if the user does not have enough quota available to support the cores and RAM that is needed by the server to be unshelved.

When you enable unified limits, during a server resize, quota use is inflated until the resize is complete. For more information, see https://bugs.launchpad.net/nova/+bug/1790204.)

Procedure

  1. For quota enforcement on per-project quotas, add the reader role with system scope to the Compute service user:
    $ oc exec openstackclient -- openstack role add --user nova --user-domain <service_domain_name> --system all reader
    • Replace <service_domain_name> with the name of the service domain name.
  2. Retrieve the Compute service endpoint ID. You need this value to configure the nova-api and nova-conductor services:
    $ oc exec openstackclient -- openstack endpoint list --service nova -f value -c ID
  3. Open your OpenStackControlPlane custom resource (CR) file, openstack_control_plane.yaml, on your workstation.
  4. Configure the nova-api and nova-conductor services in openstack_control_plane.yaml. Set the driver parameter to nova.quota.UnifiedLimitsDriver. You must define the Compute service endpoint_id that you retrieved in a previous step in apiServiceTemplate.customServiceConfig and in conductorServiceTemplate.customServiceConfig for each cell.

    Simple example:

    apiVersion: core.openstack.org/v1beta1
    kind: OpenStackControlPlane
    spec:
      nova:
        template:
          apiServiceTemplate:
            customServiceConfig: |
              [quota]
              driver = nova.quota.UnifiedLimitsDriver
              [oslo_limit]
              endpoint_id = <service_endpoint_id>
          cellTemplates:
            cell0:
              conductorServiceTemplate:
                customServiceConfig: |
                  [quota]
                  driver = nova.quota.UnifiedLimitsDriver
                  [oslo_limit]
                  endpoint_id = <service_endpoint_id>
            cell1:
              conductorServiceTemplate:
                customServiceConfig: |
                  [quota]
                  driver = nova.quota.UnifiedLimitsDriver
                  [oslo_limit]
                  endpoint_id = <service_endpoint_id>
    • Replace <service_endpoint_id> with the Compute service endpoint ID you retrieved in a previous step. Note
      If you add a cell, you must also configure the new cell for unified limits. To add a new cell, see Add Compute cells to the control plane.
  5. Optional: Configure the [quota] unified limits resource strategy to either ignore or require registered limits by setting the unified_limits_resource_list parameter. The default strategy is require and the default resource list contains servers:

    Example configuration with resource strategy require:

    apiVersion: core.openstack.org/v1beta1
    kind: OpenStackControlPlane
    spec:
      nova:
        template:
          apiServiceTemplate:
            customServiceConfig: |
              [quota]
              driver = nova.quota.UnifiedLimitsDriver
              unified_limits_resource_strategy = require
    
              # Do not allow allocation of a resource in this list unless it has
              # a limit set in Keystone.
              unified_limits_resource_list = servers,class:VCPU,class:MEMORY_MB,class:DISK_GB
              [oslo_limit]
              endpoint_id = <service_endpoint_id>
          cellTemplates:
            cell0:
               conductorServiceTemplate:
                customServiceConfig: |
                  [quota]
                  driver = nova.quota.UnifiedLimitsDriver
                  unified_limits_resource_strategy = require
    
                  # Do not allow allocation of a resource in this list unless it has
                  # a limit set in Keystone.
                  unified_limits_resource_list = servers,class:VCPU,class:MEMORY_MB,class:DISK_GB
                  [oslo_limit]
                  endpoint_id = <service_endpoint_id>
            cell1:
               conductorServiceTemplate:
                customServiceConfig: |
                  [quota]
                  driver = nova.quota.UnifiedLimitsDriver
                  unified_limits_resource_strategy = require
    
                  # Do not allow allocation of a resource in this list unless it has
                  # a limit set in Keystone.
                  unified_limits_resource_list = servers,class:VCPU,class:MEMORY_MB,class:DISK_GB
                  [oslo_limit]
                  endpoint_id = <service_endpoint_id>

    Example configuration with resource strategy ignore:

    apiVersion: core.openstack.org/v1beta1
    kind: OpenStackControlPlane
    spec:
      nova:
        template:
          apiServiceTemplate:
            customServiceConfig: |
              [quota]
              driver = nova.quota.UnifiedLimitsDriver
              unified_limits_resource_strategy = ignore
    
              # Allow unlimited allocation of a resource in this list unless it
              # has a limit set in Keystone.
    
              unified_limits_resource_list = servers,class:VCPU,class:MEMORY_MB,class:DISK_GB
              [oslo_limit]
              endpoint_id = <service_endpoint_id>
          cellTemplates:
            cell0:
               conductorServiceTemplate:
                customServiceConfig: |
                  [quota]
                  driver = nova.quota.UnifiedLimitsDriver
                  unified_limits_resource_strategy = ignore
    
                  # Allow unlimited allocation of a resource in this list unless it
                  # has a limit set in Keystone.
                  unified_limits_resource_list = servers,class:VCPU,class:MEMORY_MB,class:DISK_GB
                  [oslo_limit]
                  endpoint_id = <service_endpoint_id>
            cell1:
               conductorServiceTemplate:
                customServiceConfig: |
                  [quota]
                  driver = nova.quota.UnifiedLimitsDriver
                  unified_limits_resource_strategy = ignore
    
                  # Allow unlimited allocation of a resource in this list unless it
                  # has a limit set in Keystone.
                  unified_limits_resource_list = servers,class:VCPU,class:MEMORY_MB,class:DISK_GB
                  [oslo_limit]
                  endpoint_id = <service_endpoint_id>
  6. Update the control plane:
    $ oc apply -f openstack_control_plane.yaml -n openstack
  7. Wait until Red Hat OpenShift Container Platform (RHOCP) creates the resources related to the OpenStackControlPlane CR. Run the following command to check the status:
    $ oc get openstackcontrolplane -n openstack

    The OpenStackControlPlane resources are created when the status is Setup complete.

    Tip
    Append the -w option to the end of the get command to track deployment progress.
  8. Optional: Confirm that the control plane is deployed by reviewing the pods in the openstack namespace for each of the cells you created. The control plane is deployed when all the pods are either completed or running.

Migrate quota limits to the Identity service

You can migrate legacy quota limits from the Nova database to unified limits in the Identity (keystone) service by using the nova-managelimits migrate_to_unified_limits CLI command.

Procedure

  1. In the nova conductor pod, run the migration command once to migrate default limits and detect missing limits:
    $ oc exec nova-cell0-conductor-0 -- nova-manage limits migrate_to_unified_limits

    The command outputs a table showing which resources do not have limits set in the Identity service.

  2. Optional: In the nova conductor pod, you can run the migration command once per project to migrate per-project limits:
    $ oc exec nova-cell0-conductor-0 -- nova-manage limits migrate_to_unified_limits --no-embedded-flavor-scan --quiet --project-id <project_id>
    • Replace <project_id> with the ID number of the project.
  3. Create default registered limits and per-project limits manually for any remaining resources. Set the limit to -1 to indicate unlimited.
    • Set default limits:
      $ oc exec openstackclient -- openstack registered limit create --service nova --default-limit <limit> <resource>
      • Replace <limit> with the limit value.
      • Replace <resource> with the name of the resource.
    • Set project limits:
      $ oc exec openstackclient -- openstack limit create --service nova --project <project_id> --resource-limit <limit> <resource>

      Quota resource names have the following format:

      Table 1. Formats of quota resource names
      $RESOURCEDescription

      class:VCPU

      Number of shared CPU cores (VCPUs) allowed per project

      class:PCPU

      Number of dedicated CPU cores (PCPUs) allowed per project

      servers

      Number of instances allowed per project

      server_key_pairs

      Number of key pairs allowed per user

      server_metadata_items

      Number of metadata items allowed per instance

      class:MEMORY_GB

      Megabytes of instance RAM allowed per project

      server_groups

      Number of server groups per project

      server_group_members

      Number of servers per server group

      class:DISK_GB

      Gigabytes of instance disk allowed per project

      class:<resource_class>

      Any resource class in the Placement API service can have a quota limit specified for it, for example, class:VGPU