How to enable ResourceQuota in k8s?Doubts about k8s resource configuration

48 views Asked by At

The official K8s documentation states that it is necessary to include ResourceQuota in the --enable-admission-plugins of apiserver to enable resource quota. https://kubernetes.io/docs/concepts/policy/resource-quotas/#enabling-resource-quota

In a certain K8s 1.19 environment, I did not find the ResourceQuota configuration in --enable-admission-plugins. However, once resourcequota is set for each Namespace, this resourcequota will take effect. enter image description here

Additionally, by examining the source code of apiserver(release-1.28), the Register method in pkg/admission/plugin/resourcequota/admission.go is not referenced. In pkg/server/options/admission.go, the Validate method of AdmissionOptions will check whether the plugins in the configuration are registered. If not registered, it will return an error. This Validate method is called from the Validate method of RecommendedOptions, but NewRecommendedOptions is not called.

I'm confused.

I would appreciate any guidance from experts. Thank you.

I want to figure out how the ResourceQuota in K8s takes effect. I would like to find the basis from the source code.

1

There are 1 answers

0
Buddie.Wei On BEST ANSWER

I have find the answer to this question myself. The function "enablePluginNames" of AdmissionOptions in vendor/k8s.io/apiserver/pkg/server/options/admission.go is the answer.

// enabledPluginNames makes use of RecommendedPluginOrder, DefaultOffPlugins,
// EnablePlugins, DisablePlugins fields
// to prepare a list of ordered plugin names that are enabled.
func (a *AdmissionOptions) enabledPluginNames() []string {
    allOffPlugins := append(a.DefaultOffPlugins.List(), a.DisablePlugins...)
    disabledPlugins := sets.NewString(allOffPlugins...)
    enabledPlugins := sets.NewString(a.EnablePlugins...)
    disabledPlugins = disabledPlugins.Difference(enabledPlugins)

    orderedPlugins := []string{}
    for _, plugin := range a.RecommendedPluginOrder {
        if !disabledPlugins.Has(plugin) {
            orderedPlugins = append(orderedPlugins, plugin)
        }
    }

    return orderedPlugins
}

The plugins in RecommendedPluginOrder will be enabled by default as long as they are not disabled.

RecommendedPlugionOrder is initialized in the NewAdmissionOptions method in pkg/kubeapiserver/options/admission.go.

// NewAdmissionOptions creates a new instance of AdmissionOptions
// Note:
//
//  In addition it calls RegisterAllAdmissionPlugins to register
//  all kube-apiserver admission plugins.
//
//  Provides the list of RecommendedPluginOrder that holds sane values
//  that can be used by servers that don't care about admission chain.
//  Servers that do care can overwrite/append that field after creation.
func NewAdmissionOptions() *AdmissionOptions {
    options := genericoptions.NewAdmissionOptions()
    // register all admission plugins
    RegisterAllAdmissionPlugins(options.Plugins)
    // set RecommendedPluginOrder
    options.RecommendedPluginOrder = AllOrderedPlugins
    // set DefaultOffPlugins
    options.DefaultOffPlugins = DefaultOffAdmissionPlugins()

    return &AdmissionOptions{
        GenericAdmission: options,
    }
}

AllOrderedPlugins is declared like this:

// AllOrderedPlugins is the list of all the plugins in order.
var AllOrderedPlugins = []string{
    admit.PluginName,                        // AlwaysAdmit
    autoprovision.PluginName,                // NamespaceAutoProvision
    lifecycle.PluginName,                    // NamespaceLifecycle
    exists.PluginName,                       // NamespaceExists
    scdeny.PluginName,                       // SecurityContextDeny
    antiaffinity.PluginName,                 // LimitPodHardAntiAffinityTopology
    limitranger.PluginName,                  // LimitRanger
    serviceaccount.PluginName,               // ServiceAccount
    noderestriction.PluginName,              // NodeRestriction
    nodetaint.PluginName,                    // TaintNodesByCondition
    alwayspullimages.PluginName,             // AlwaysPullImages
    imagepolicy.PluginName,                  // ImagePolicyWebhook
    podsecurity.PluginName,                  // PodSecurity
    podnodeselector.PluginName,              // PodNodeSelector
    podpriority.PluginName,                  // Priority
    defaulttolerationseconds.PluginName,     // DefaultTolerationSeconds
    podtolerationrestriction.PluginName,     // PodTolerationRestriction
    eventratelimit.PluginName,               // EventRateLimit
    extendedresourcetoleration.PluginName,   // ExtendedResourceToleration
    label.PluginName,                        // PersistentVolumeLabel
    setdefault.PluginName,                   // DefaultStorageClass
    storageobjectinuseprotection.PluginName, // StorageObjectInUseProtection
    gc.PluginName,                           // OwnerReferencesPermissionEnforcement
    resize.PluginName,                       // PersistentVolumeClaimResize
    runtimeclass.PluginName,                 // RuntimeClass
    certapproval.PluginName,                 // CertificateApproval
    certsigning.PluginName,                  // CertificateSigning
    ctbattest.PluginName,                    // ClusterTrustBundleAttest
    certsubjectrestriction.PluginName,       // CertificateSubjectRestriction
    defaultingressclass.PluginName,          // DefaultIngressClass
    denyserviceexternalips.PluginName,       // DenyServiceExternalIPs

    // new admission plugins should generally be inserted above here
    // webhook, resourcequota, and deny plugins must go at the end

    mutatingwebhook.PluginName,           // MutatingAdmissionWebhook
    validatingadmissionpolicy.PluginName, // ValidatingAdmissionPolicy
    validatingwebhook.PluginName,         // ValidatingAdmissionWebhook
    resourcequota.PluginName,             // ResourceQuota
    deny.PluginName,                      // AlwaysDeny
}

Therefore, the ResourceQuota plugin will be enabled by default, event without being declared in the --enable-admission-plugins parameter.