Skip to content

Commit 162b557

Browse files
committed
Expose swap behavior via label
Signed-off-by: Feruzjon Muyassarov <[email protected]>
1 parent 02a3ec0 commit 162b557

File tree

5 files changed

+89
-11
lines changed

5 files changed

+89
-11
lines changed

cmd/nfd-worker/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ func initFlags(flagset *flag.FlagSet) (*worker.Args, *worker.ConfigOverrideArgs)
106106
"Config file to use.")
107107
flagset.StringVar(&args.Kubeconfig, "kubeconfig", "",
108108
"Kubeconfig to use")
109+
flagset.StringVar(&args.KubeletConfigPath, "kubelet-config-path", "/var/lib/kubelet/config.yaml",
110+
"Path to the kubelet configuration file")
109111
flagset.BoolVar(&args.Oneshot, "oneshot", false,
110112
"Do not publish feature labels")
111113
flagset.IntVar(&args.Port, "port", 8080,

deployment/components/common/worker-mounts.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
- name: features-d
2323
hostPath:
2424
path: "/etc/kubernetes/node-feature-discovery/features.d/"
25+
- name: kubelet-dir
26+
hostPath:
27+
path: "/var/lib/kubelet/config.yaml"
2528
- name: nfd-worker-conf
2629
configMap:
2730
name: nfd-worker-conf
@@ -50,6 +53,9 @@
5053
- name: features-d
5154
mountPath: "/etc/kubernetes/node-feature-discovery/features.d/"
5255
readOnly: true
56+
- name: kubelet-dir
57+
mountPath: "/var/lib/kubelet/config.yaml"
58+
readOnly: true
5359
- name: nfd-worker-conf
5460
mountPath: "/etc/kubernetes/node-feature-discovery"
5561
readOnly: true

pkg/nfd-worker/nfd-worker.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import (
5757
_ "sigs.k8s.io/node-feature-discovery/source/kernel"
5858
_ "sigs.k8s.io/node-feature-discovery/source/local"
5959
_ "sigs.k8s.io/node-feature-discovery/source/memory"
60+
memory "sigs.k8s.io/node-feature-discovery/source/memory"
6061
_ "sigs.k8s.io/node-feature-discovery/source/network"
6162
_ "sigs.k8s.io/node-feature-discovery/source/pci"
6263
_ "sigs.k8s.io/node-feature-discovery/source/storage"
@@ -76,6 +77,14 @@ type NFDConfig struct {
7677
Sources sourcesConfig
7778
}
7879

80+
func configureKubeletConfigPath(kubeletConfigPath string) error {
81+
if kubeletConfigPath == "" {
82+
return fmt.Errorf("kubelet config path is empty, using default: '/var/lib/kubelet/config.yaml'")
83+
}
84+
memory.SetKubeletConfigPath(kubeletConfigPath)
85+
return nil
86+
}
87+
7988
type coreConfig struct {
8089
Klog klogutils.KlogConfigOpts
8190
LabelWhiteList utils.RegexpVal
@@ -94,13 +103,14 @@ type Labels map[string]string
94103

95104
// Args are the command line arguments of NfdWorker.
96105
type Args struct {
97-
ConfigFile string
98-
Klog map[string]*utils.KlogFlagVal
99-
Kubeconfig string
100-
Oneshot bool
101-
Options string
102-
Port int
103-
NoOwnerRefs bool
106+
ConfigFile string
107+
Klog map[string]*utils.KlogFlagVal
108+
Kubeconfig string
109+
Oneshot bool
110+
Options string
111+
Port int
112+
NoOwnerRefs bool
113+
KubeletConfigPath string
104114

105115
Overrides ConfigOverrideArgs
106116
}
@@ -312,6 +322,10 @@ func (w *nfdWorker) Run() error {
312322
httpMux.Handle("/metrics", promhttp.HandlerFor(promRegistry, promhttp.HandlerOpts{}))
313323
registerVersion(version.Get())
314324

325+
if err := configureKubeletConfigPath(w.args.KubeletConfigPath); err != nil {
326+
klog.ErrorS(err, "failed to configure kubelet config path")
327+
}
328+
315329
err = w.runFeatureDiscovery()
316330
if err != nil {
317331
return err

pkg/utils/kubeconf/kubelet_config_file.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@ package kubeconf
1818

1919
import (
2020
"fmt"
21+
"os"
2122

23+
"github.com/pkg/errors"
24+
kubeletconfig "k8s.io/kubelet/config/v1beta1"
2225
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
2326
kubeletconfigscheme "k8s.io/kubernetes/pkg/kubelet/apis/config/scheme"
2427
"k8s.io/kubernetes/pkg/kubelet/kubeletconfig/configfiles"
2528
utilfs "k8s.io/kubernetes/pkg/util/filesystem"
29+
"sigs.k8s.io/yaml"
2630
)
2731

2832
// GetKubeletConfigFromLocalFile returns KubeletConfiguration loaded from the node local config
@@ -54,3 +58,23 @@ func GetKubeletConfigFromLocalFile(kubeletConfigPath string) (*kubeletconfigv1be
5458

5559
return kubeletConfig, nil
5660
}
61+
62+
// ReadKubeletConfig reads and unmarshals a kubelet configuration file from the specified file.
63+
func ReadKubeletConfig(kubeletFile string) (*kubeletconfig.KubeletConfiguration, error) {
64+
_, err := os.Stat(kubeletFile)
65+
if os.IsNotExist(err) {
66+
return nil, fmt.Errorf("kubelet config file %s does not exist", kubeletFile)
67+
}
68+
69+
data, err := os.ReadFile(kubeletFile)
70+
if err != nil {
71+
return nil, errors.Wrapf(err, "failed to read kubelet configuration file %q", kubeletFile)
72+
}
73+
74+
var config kubeletconfig.KubeletConfiguration
75+
if err := yaml.Unmarshal(data, &config); err != nil {
76+
return nil, errors.Wrapf(err, "could not parse kubelet configuration file %q", kubeletFile)
77+
}
78+
79+
return &config, nil
80+
}

source/memory/memory.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/api/nfd/v1alpha1"
3232
"sigs.k8s.io/node-feature-discovery/pkg/utils"
3333
"sigs.k8s.io/node-feature-discovery/pkg/utils/hostpath"
34+
"sigs.k8s.io/node-feature-discovery/pkg/utils/kubeconf"
3435
"sigs.k8s.io/node-feature-discovery/source"
3536
)
3637

@@ -54,13 +55,25 @@ type memorySource struct {
5455
features *nfdv1alpha1.Features
5556
}
5657

58+
// KubeletConfigPath holds the path to the kubelet configuration file.
59+
type KubeletConfigPath struct {
60+
ConfigFilePath string
61+
}
62+
5763
// Singleton source instance
5864
var (
59-
src memorySource
60-
_ source.FeatureSource = &src
61-
_ source.LabelSource = &src
65+
src memorySource
66+
_ source.FeatureSource = &src
67+
_ source.LabelSource = &src
68+
defaultSwapBehavior = "NoSwap"
6269
)
6370

71+
var kubelet = KubeletConfigPath{}
72+
73+
func SetKubeletConfigPath(path string) {
74+
kubelet.ConfigFilePath = path
75+
}
76+
6477
// Name returns an identifier string for this feature source.
6578
func (s *memorySource) Name() string { return Name }
6679

@@ -80,6 +93,7 @@ func (s *memorySource) GetLabels() (source.FeatureLabels, error) {
8093
// Swap
8194
if isSwap, ok := features.Attributes[SwapFeature].Elements["enabled"]; ok && isSwap == "true" {
8295
labels["swap"] = true
96+
labels["swap.behavior"] = features.Attributes[SwapFeature].Elements["behavior"]
8397
}
8498

8599
// NVDIMM
@@ -107,11 +121,19 @@ func (s *memorySource) Discover() error {
107121
s.features.Attributes[NumaFeature] = nfdv1alpha1.AttributeFeatureSet{Elements: numa}
108122
}
109123

110-
// Detect Swap
124+
// Detect Swap and Swap Behavior
111125
if swap, err := detectSwap(); err != nil {
112126
klog.ErrorS(err, "failed to detect Swap nodes")
113127
} else {
114128
s.features.Attributes[SwapFeature] = nfdv1alpha1.AttributeFeatureSet{Elements: swap}
129+
swapBehavior, err := detectSwapBehavior(kubelet.ConfigFilePath)
130+
if err != nil {
131+
klog.V(3).ErrorS(err, "failed to detect swap behavior; kubelet swapBehavior configuration may be missing or misconfigured")
132+
} else if swapBehavior == "" {
133+
swap["behavior"] = defaultSwapBehavior
134+
} else {
135+
swap["behavior"] = swapBehavior
136+
}
115137
}
116138

117139
// Detect NVDIMM
@@ -155,6 +177,16 @@ func detectSwap() (map[string]string, error) {
155177
}, nil
156178
}
157179

180+
// detectSwapBehavior detects the swap behavior as configured in the kubelet.
181+
func detectSwapBehavior(configFilePath string) (string, error) {
182+
kubeletConfig, err := kubeconf.ReadKubeletConfig(configFilePath)
183+
if err != nil {
184+
return "", fmt.Errorf("failed to read kubelet configuration file %q: %w", configFilePath, err)
185+
}
186+
187+
return kubeletConfig.MemorySwap.SwapBehavior, nil
188+
}
189+
158190
// detectNuma detects NUMA node information
159191
func detectNuma() (map[string]string, error) {
160192
sysfsBasePath := hostpath.SysfsDir.Path("bus/node/devices")

0 commit comments

Comments
 (0)