Skip to content
This repository has been archived by the owner before Nov 9, 2022. It is now read-only.
Permalink
main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
2 contributors

Users who have contributed to this file

@guineveresaenger @grodrigues3

Admission control plugin: LimitRanger

Background

This document proposes a system for enforcing resource requirements constraints as part of admission control.

Use cases

  1. Ability to enumerate resource requirement constraints per namespace
  2. Ability to enumerate min/max resource constraints for a pod
  3. Ability to enumerate min/max resource constraints for a container
  4. Ability to specify default resource limits for a container
  5. Ability to specify default resource requests for a container
  6. Ability to enforce a ratio between request and limit for a resource.
  7. Ability to enforce min/max storage requests for persistent volume claims

Data Model

The LimitRange resource is scoped to a Namespace.

Type

// LimitType is a type of object that is limited
type LimitType string

const (
  // Limit that applies to all pods in a namespace
  LimitTypePod LimitType = "Pod"
  // Limit that applies to all containers in a namespace
  LimitTypeContainer LimitType = "Container"
)

// LimitRangeItem defines a min/max usage limit for any resource that matches
// on kind.
type LimitRangeItem struct {
  // Type of resource that this limit applies to.
  Type LimitType `json:"type,omitempty"`
  // Max usage constraints on this kind by resource name.
  Max ResourceList `json:"max,omitempty"`
  // Min usage constraints on this kind by resource name.
  Min ResourceList `json:"min,omitempty"`
  // Default resource requirement limit value by resource name if resource limit
  // is omitted.
  Default ResourceList `json:"default,omitempty"`
  // DefaultRequest is the default resource requirement request value by
  // resource name if resource request is omitted.
  DefaultRequest ResourceList `json:"defaultRequest,omitempty"`
  // MaxLimitRequestRatio if specified, the named resource must have a request
  // and limit that are both non-zero where limit divided by request is less
  // than or equal to the enumerated value; this represents the max burst for
  // the named resource.
  MaxLimitRequestRatio ResourceList `json:"maxLimitRequestRatio,omitempty"`
}

// LimitRangeSpec defines a min/max usage limit for resources that match
// on kind.
type LimitRangeSpec struct {
  // Limits is the list of LimitRangeItem objects that are enforced.
  Limits []LimitRangeItem `json:"limits"`
}

// LimitRange sets resource usage limits for each kind of resource in a
// Namespace.
type LimitRange struct {
  TypeMeta `json:",inline"`
  // Standard object's metadata.
  // More info: 
  //    http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
  ObjectMeta `json:"metadata,omitempty"`

  // Spec defines the limits enforced.
  // More info:
  //   http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
  Spec LimitRangeSpec `json:"spec,omitempty"`
}

// LimitRangeList is a list of LimitRange items.
type LimitRangeList struct {
  TypeMeta `json:",inline"`
  // Standard list metadata.
  // More info: 
  //   http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
  ListMeta `json:"metadata,omitempty"`

  // Items is a list of LimitRange objects.
  // More info:
  //   http://releases.k8s.io/HEAD/docs/design/admission_control_limit_range.md
  Items []LimitRange `json:"items"`
}

Validation

Validation of a LimitRange enforces that for a given named resource the following rules apply:

Min (if specified) <= DefaultRequest (if specified) <= Default (if specified) <= Max (if specified)

Default Value Behavior

The following default value behaviors are applied to a LimitRange for a given named resource.

if LimitRangeItem.Default[resourceName] is undefined 
  if LimitRangeItem.Max[resourceName] is defined
    LimitRangeItem.Default[resourceName] = LimitRangeItem.Max[resourceName]
if LimitRangeItem.DefaultRequest[resourceName] is undefined
  if LimitRangeItem.Default[resourceName] is defined
    LimitRangeItem.DefaultRequest[resourceName] = LimitRangeItem.Default[resourceName]
  else if LimitRangeItem.Min[resourceName] is defined
    LimitRangeItem.DefaultRequest[resourceName] = LimitRangeItem.Min[resourceName]

AdmissionControl plugin: LimitRanger

The LimitRanger plug-in introspects all incoming pod requests and evaluates the constraints defined on a LimitRange.

If a constraint is not specified for an enumerated resource, it is not enforced or tracked.

To enable the plug-in and support for LimitRange, the kube-apiserver must be configured as follows:

$ kube-apiserver --admission-control=LimitRanger

Enforcement of constraints

Type: Container

Supported Resources:

  1. memory
  2. cpu

Supported Constraints:

Per container, the following must hold true:

Constraint Behavior
Min Min <= Request (required) <= Limit (optional)
Max Limit (required) <= Max
LimitRequestRatio LimitRequestRatio <= ( Limit (required, non-zero) / Request (required, non-zero))

Supported Defaults:

  1. Default - if the named resource has no enumerated values, the Limit is equal to the Default
  2. DefaultRequest - if the named resource has no enumerated values, the Request is equal to the DefaultRequest

Type: Pod

Supported Resources:

  1. memory
  2. cpu

Supported Constraints:

Across all containers in pod, the following must hold true

Constraint Behavior
Min Min <= Request (required) <= Limit (optional)
Max Limit (required) <= Max
LimitRequestRatio LimitRequestRatio <= ( Limit (required, non-zero) / Request (non-zero) )

Type: PersistentVolumeClaim

Supported Resources:

  1. storage

Supported Constraints:

Across all claims in a namespace, the following must hold true:

Constraint Behavior
Min Min >= Request (required)
Max Max <= Request (required)

Supported Defaults: None. Storage is a required field in PersistentVolumeClaim, so defaults are not applied at this time.

Run-time configuration

The default LimitRange that is applied via Salt configuration will be updated as follows:

apiVersion: "v1"
kind: "LimitRange"
metadata:
  name: "limits"
  namespace: default
spec:
  limits:
    - type: "Container"
      defaultRequest:
        cpu: "100m"

Example

An example LimitRange configuration:

Type Resource Min Max Default DefaultRequest LimitRequestRatio
Container cpu .1 1 500m 250m 4
Container memory 250Mi 1Gi 500Mi 250Mi

Assuming an incoming container that specified no incoming resource requirements, the following would happen.

  1. The incoming container cpu would request 250m with a limit of 500m.
  2. The incoming container memory would request 250Mi with a limit of 500Mi
  3. If the container is later resized, it's cpu would be constrained to between .1 and 1 and the ratio of limit to request could not exceed 4.