kuberneteskubernetes-apiserver

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


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.


Solution

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