Change:
A kubernetes cluster is normally constructed from a variety of machine templates. Different instance groups may have different CPU, memory capacity. They may be equipped with specialized accelerators, network devices. I think we should have an extensible way for users to custom node configuration to simulate real production cluster states. Currently, nodelabel and nodetaints are supported. I am consider to accept a template with more configuration like resources so we won't grow option list in the future. Without this feature, it's hard for users to simulate heterogeneous cluster.
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/assign
/sig scalability

Discussion:
"k8s.io/klog/v2" v1 "k8s.io/api/core/v1" <ins> "k8s.io/apimachinery/pkg/api/resource" </ins> "k8s.io/apimachinery/pkg/util/sets" clientset "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest"

ProxierMinSyncPeriod time.Duration NodeLabels           map[string]string RegisterWithTaints   []core.Taint <ins> MaxPods              int ExtendedResources    map[string]string </ins> } const (

bindableNodeLabels := cliflag.ConfigurationMap(c.NodeLabels) fs.Var(&bindableNodeLabels, "node-labels", "Additional node labels") fs.Var(utiltaints.NewTaintsVar(&c.RegisterWithTaints), "register-with-taints", "Register the node with the given list of taints (comma separated "<key>=<value>:<effect>"). No-op if register-node is false.") <ins> fs.IntVar(&c.MaxPods, "max-pods", maxPods, "Number of pods that can run on this Kubelet.") bindableExtendedResources := cliflag.ConfigurationMap(c.ExtendedResources) fs.Var(&bindableExtendedResources, "extended-resources", "Register the node with extended resources (comma separated "<name>=<quantity>")") </ins> } func (c *hollowNodeConfig) createClientConfigFromFile() (*restclient.Config, error) {

NodeName:            c.NodeName, KubeletPort:         c.KubeletPort, KubeletReadOnlyPort: c.KubeletReadOnlyPort, <del> MaxPods:             maxPods, </del> <ins> MaxPods:             c.MaxPods, </ins> PodsPerCore:         podsPerCore, NodeLabels:          c.NodeLabels, RegisterWithTaints:  c.RegisterWithTaints,

// newControllerManagerCommand creates a *cobra.Command object with default parameters func newHollowNodeCommand() *cobra.Command { s := &hollowNodeConfig{ <del> NodeLabels: make(map[string]string), </del> <ins> NodeLabels:        make(map[string]string), ExtendedResources: make(map[string]string), </ins> } cmd := &cobra.Command{

cadvisorInterface := &cadvisortest.Fake{ NodeName: config.NodeName, } <del> containerManager := cm.NewStubContainerManager() </del> <ins> var containerManager cm.ContainerManager if config.ExtendedResources != nil { extendedResources := v1.ResourceList{} for k, v := range config.ExtendedResources { extendedResources[v1.ResourceName(k)] = resource.MustParse(v) } containerManager = cm.NewStubContainerManagerWithDevicePluginResource(extendedResources) } else { containerManager = cm.NewStubContainerManager() } </ins> endpoint, err := fakeremote.GenerateEndpoint() if err != nil {

type containerManagerStub struct { shouldResetExtendedResourceCapacity bool <ins> extendedPluginResources             v1.ResourceList </ins> } var _ ContainerManager = &containerManagerStub{}

} func (cm *containerManagerStub) GetDevicePluginResourceCapacity() (v1.ResourceList, v1.ResourceList, []string) { <del> return nil, nil, []string{} </del> <ins> return cm.extendedPluginResources, cm.extendedPluginResources, []string{} </ins> } func (cm *containerManagerStub) NewPodContainerManager() PodContainerManager {

func NewStubContainerManagerWithExtendedResource(shouldResetExtendedResourceCapacity bool) ContainerManager { return &containerManagerStub{shouldResetExtendedResourceCapacity: shouldResetExtendedResourceCapacity} } <ins> func NewStubContainerManagerWithDevicePluginResource(extendedPluginResources v1.ResourceList) ContainerManager { return &containerManagerStub{ shouldResetExtendedResourceCapacity: false, extendedPluginResources:             extendedPluginResources, } } </ins>