mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2025-03-18 22:33:09 +00:00
Merge pull request #1054 from PiotrProkop/use-new-nrt-api
Advertise TopologyManger policy and scope as Attributes in NRT api v1alpha2
This commit is contained in:
commit
38cc370e69
4 changed files with 91 additions and 19 deletions
|
@ -28,7 +28,6 @@ import (
|
||||||
|
|
||||||
topology "sigs.k8s.io/node-feature-discovery/pkg/nfd-topology-updater"
|
topology "sigs.k8s.io/node-feature-discovery/pkg/nfd-topology-updater"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/resourcemonitor"
|
"sigs.k8s.io/node-feature-discovery/pkg/resourcemonitor"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/topologypolicy"
|
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/utils/hostpath"
|
"sigs.k8s.io/node-feature-discovery/pkg/utils/hostpath"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/utils/kubeconf"
|
"sigs.k8s.io/node-feature-discovery/pkg/utils/kubeconf"
|
||||||
|
@ -88,11 +87,8 @@ func main() {
|
||||||
klog.Exitf("unsupported URI scheme: %v", u.Scheme)
|
klog.Exitf("unsupported URI scheme: %v", u.Scheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
tmPolicy := string(topologypolicy.DetectTopologyPolicy(klConfig.TopologyManagerPolicy, klConfig.TopologyManagerScope))
|
|
||||||
klog.Infof("detected kubelet Topology Manager policy %q", tmPolicy)
|
|
||||||
|
|
||||||
// Get new TopologyUpdater instance
|
// Get new TopologyUpdater instance
|
||||||
instance := topology.NewTopologyUpdater(*args, *resourcemonitorArgs, tmPolicy)
|
instance := topology.NewTopologyUpdater(*args, *resourcemonitorArgs, klConfig.TopologyManagerPolicy, klConfig.TopologyManagerScope)
|
||||||
|
|
||||||
if err = instance.Run(); err != nil {
|
if err = instance.Run(); err != nil {
|
||||||
klog.Exit(err)
|
klog.Exit(err)
|
||||||
|
|
|
@ -32,11 +32,19 @@ import (
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
|
"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/podres"
|
"sigs.k8s.io/node-feature-discovery/pkg/podres"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/resourcemonitor"
|
"sigs.k8s.io/node-feature-discovery/pkg/resourcemonitor"
|
||||||
|
"sigs.k8s.io/node-feature-discovery/pkg/topologypolicy"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
"sigs.k8s.io/node-feature-discovery/pkg/version"
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TopologyManagerPolicyAttributeName represents an attribute which defines Topology Manager Policy
|
||||||
|
TopologyManagerPolicyAttributeName = "topologyManagerPolicy"
|
||||||
|
// TopologyManagerScopeAttributeName represents an attribute which defines Topology Manager Policy Scope
|
||||||
|
TopologyManagerScopeAttributeName = "topologyManagerScope"
|
||||||
|
)
|
||||||
|
|
||||||
// Args are the command line arguments
|
// Args are the command line arguments
|
||||||
type Args struct {
|
type Args struct {
|
||||||
NoPublish bool
|
NoPublish bool
|
||||||
|
@ -60,10 +68,21 @@ type NfdTopologyUpdater interface {
|
||||||
type staticNodeInfo struct {
|
type staticNodeInfo struct {
|
||||||
nodeName string
|
nodeName string
|
||||||
tmPolicy string
|
tmPolicy string
|
||||||
|
tmScope string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStaticNodeInfo(policy, scope string) staticNodeInfo {
|
||||||
|
nodeName := utils.NodeName()
|
||||||
|
klog.InfoS("detected kubelet Topology Manager configuration", "policy", policy, "scope", scope, "nodeName", nodeName)
|
||||||
|
return staticNodeInfo{
|
||||||
|
nodeName: nodeName,
|
||||||
|
tmPolicy: policy,
|
||||||
|
tmScope: scope,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type nfdTopologyUpdater struct {
|
type nfdTopologyUpdater struct {
|
||||||
nodeInfo *staticNodeInfo
|
nodeInfo staticNodeInfo
|
||||||
args Args
|
args Args
|
||||||
apihelper apihelper.APIHelpers
|
apihelper apihelper.APIHelpers
|
||||||
resourcemonitorArgs resourcemonitor.Args
|
resourcemonitorArgs resourcemonitor.Args
|
||||||
|
@ -73,14 +92,11 @@ type nfdTopologyUpdater struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTopologyUpdater creates a new NfdTopologyUpdater instance.
|
// NewTopologyUpdater creates a new NfdTopologyUpdater instance.
|
||||||
func NewTopologyUpdater(args Args, resourcemonitorArgs resourcemonitor.Args, policy string) NfdTopologyUpdater {
|
func NewTopologyUpdater(args Args, resourcemonitorArgs resourcemonitor.Args, policy, scope string) NfdTopologyUpdater {
|
||||||
nfd := &nfdTopologyUpdater{
|
nfd := &nfdTopologyUpdater{
|
||||||
args: args,
|
args: args,
|
||||||
resourcemonitorArgs: resourcemonitorArgs,
|
resourcemonitorArgs: resourcemonitorArgs,
|
||||||
nodeInfo: &staticNodeInfo{
|
nodeInfo: newStaticNodeInfo(policy, scope),
|
||||||
nodeName: utils.NodeName(),
|
|
||||||
tmPolicy: policy,
|
|
||||||
},
|
|
||||||
stop: make(chan struct{}, 1),
|
stop: make(chan struct{}, 1),
|
||||||
config: &NFDConfig{},
|
config: &NFDConfig{},
|
||||||
}
|
}
|
||||||
|
@ -185,7 +201,8 @@ func (w *nfdTopologyUpdater) updateNodeResourceTopology(zoneInfo v1alpha2.ZoneLi
|
||||||
Name: w.nodeInfo.nodeName,
|
Name: w.nodeInfo.nodeName,
|
||||||
},
|
},
|
||||||
Zones: zoneInfo,
|
Zones: zoneInfo,
|
||||||
TopologyPolicies: []string{w.nodeInfo.tmPolicy},
|
TopologyPolicies: []string{string(topologypolicy.DetectTopologyPolicy(w.nodeInfo.tmPolicy, w.nodeInfo.tmScope))},
|
||||||
|
Attributes: createTopologyAttributes(w.nodeInfo.tmPolicy, w.nodeInfo.tmScope),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := cli.TopologyV1alpha2().NodeResourceTopologies().Create(context.TODO(), &nrtNew, metav1.CreateOptions{})
|
_, err := cli.TopologyV1alpha2().NodeResourceTopologies().Create(context.TODO(), &nrtNew, metav1.CreateOptions{})
|
||||||
|
@ -231,3 +248,16 @@ func (w *nfdTopologyUpdater) configure() error {
|
||||||
klog.Infof("configuration file %q parsed:\n %v", w.configFilePath, w.config)
|
klog.Infof("configuration file %q parsed:\n %v", w.configFilePath, w.config)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createTopologyAttributes(policy string, scope string) v1alpha2.AttributeList {
|
||||||
|
return v1alpha2.AttributeList{
|
||||||
|
{
|
||||||
|
Name: TopologyManagerPolicyAttributeName,
|
||||||
|
Value: policy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: TopologyManagerScopeAttributeName,
|
||||||
|
Value: scope,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -17,23 +17,40 @@ limitations under the License.
|
||||||
package kubeconf
|
package kubeconf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
|
||||||
|
|
||||||
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
|
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
|
||||||
|
kubeletconfigscheme "k8s.io/kubernetes/pkg/kubelet/apis/config/scheme"
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/kubeletconfig/configfiles"
|
||||||
|
utilfs "k8s.io/kubernetes/pkg/util/filesystem"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetKubeletConfigFromLocalFile returns KubeletConfiguration loaded from the node local config
|
// GetKubeletConfigFromLocalFile returns KubeletConfiguration loaded from the node local config
|
||||||
|
// based on https://github.com/kubernetes/kubernetes/blob/master/cmd/kubelet/app/server.go#L337
|
||||||
|
// it fills empty fields with default values
|
||||||
func GetKubeletConfigFromLocalFile(kubeletConfigPath string) (*kubeletconfigv1beta1.KubeletConfiguration, error) {
|
func GetKubeletConfigFromLocalFile(kubeletConfigPath string) (*kubeletconfigv1beta1.KubeletConfiguration, error) {
|
||||||
kubeletBytes, err := os.ReadFile(kubeletConfigPath)
|
const errFmt = "failed to load Kubelet config file %s, error %w"
|
||||||
|
|
||||||
|
loader, err := configfiles.NewFsLoader(&utilfs.DefaultFs{}, kubeletConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(errFmt, kubeletConfigPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
kc, err := loader.Load()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(errFmt, kubeletConfigPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
scheme, _, err := kubeletconfigscheme.NewSchemeAndCodecs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
kubeletConfig := &kubeletconfigv1beta1.KubeletConfiguration{}
|
kubeletConfig := &kubeletconfigv1beta1.KubeletConfiguration{}
|
||||||
if err := yaml.Unmarshal(kubeletBytes, kubeletConfig); err != nil {
|
err = scheme.Convert(kc, kubeletConfig, nil)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return kubeletConfig, nil
|
return kubeletConfig, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -28,6 +29,7 @@ import (
|
||||||
"github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha2"
|
"github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha2"
|
||||||
topologyclientset "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned"
|
topologyclientset "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned"
|
||||||
"github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
|
nfdtopologyupdater "sigs.k8s.io/node-feature-discovery/pkg/nfd-topology-updater"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/topologypolicy"
|
"sigs.k8s.io/node-feature-discovery/pkg/topologypolicy"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
@ -198,6 +200,24 @@ func IsValidNodeTopology(nodeTopology *v1alpha2.NodeResourceTopology, kubeletCon
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expectedPolicyAttribute := v1alpha2.AttributeInfo{
|
||||||
|
Name: nfdtopologyupdater.TopologyManagerPolicyAttributeName,
|
||||||
|
Value: kubeletConfig.TopologyManagerPolicy,
|
||||||
|
}
|
||||||
|
if !containsAttribute(nodeTopology.Attributes, expectedPolicyAttribute) {
|
||||||
|
framework.Logf("topology policy attributes don't have correct topologyManagerPolicy attribute expected %v attributeList %v", expectedPolicyAttribute, nodeTopology.Attributes)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedScopeAttribute := v1alpha2.AttributeInfo{
|
||||||
|
Name: nfdtopologyupdater.TopologyManagerScopeAttributeName,
|
||||||
|
Value: kubeletConfig.TopologyManagerScope,
|
||||||
|
}
|
||||||
|
if !containsAttribute(nodeTopology.Attributes, expectedScopeAttribute) {
|
||||||
|
framework.Logf("topology policy attributes don't have correct topologyManagerScope attribute expected %v attributeList %v", expectedScopeAttribute, nodeTopology.Attributes)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if nodeTopology.Zones == nil || len(nodeTopology.Zones) == 0 {
|
if nodeTopology.Zones == nil || len(nodeTopology.Zones) == 0 {
|
||||||
framework.Logf("failed to get topology zones from the node topology resource")
|
framework.Logf("failed to get topology zones from the node topology resource")
|
||||||
return false
|
return false
|
||||||
|
@ -259,3 +279,12 @@ func isValidResourceList(zoneName string, resources v1alpha2.ResourceInfoList) b
|
||||||
}
|
}
|
||||||
return foundCpu
|
return foundCpu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func containsAttribute(attributes v1alpha2.AttributeList, attribute v1alpha2.AttributeInfo) bool {
|
||||||
|
for _, attr := range attributes {
|
||||||
|
if reflect.DeepEqual(attr, attribute) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue