Kubernetes add-on that detects hardware features and system configuration on nodes and advertises them as node labels, annotations, and extended resources. This is the OpenShift downstream fork of kubernetes-sigs/node-feature-discovery.
- Go 1.25+ (see
go.mod) podman(ordockerviaCONTAINER_COMMAND=docker)kubectl,helmfor deployment workflowsgolangci-lintfor linting (installed by CI viascripts/test-infra/verify.sh)
make build # compile all binaries into bin/
make image # build container image (uses podman by default)
make install # go install all binariesBinaries are built from cmd/:
nfd-master— cluster-side component, manages node labelsnfd-worker— node-side component, detects featuresnfd-topology-updater— reports NUMA topologynfd-gc— garbage collector for stale NFD labelsnfd— unified binary with subcommandskubectl-nfd— kubectl plugin
Override variables: IMAGE_REGISTRY, IMAGE_TAG_NAME, CONTAINER_COMMAND, HOSTMOUNT_PREFIX.
Run unit tests:
make testThis runs go test -covermode=atomic -coverprofile=coverage.out ./cmd/... ./pkg/... ./source/... and separately tests api/nfd/....
Test files live alongside source files (e.g. pkg/nfd-master/nfd-master_test.go).
Run e2e tests (requires a running cluster and KUBECONFIG):
make e2e-test KUBECONFIG=<path>E2e tests are in test/e2e/ and use Ginkgo v2 (github.com/onsi/ginkgo/v2). Test data is in test/e2e/data/.
- Format:
gofmt -s— runmake verify-gofmtto check - Lint:
golangci-lint run --timeout 10mviamake ci-lint - Markdown lint:
make mdlint(runs in a container) - Helm lint:
make helm-lint - Log checker:
logcheckwith config atscripts/test-infra/logcheck.conf - Boilerplate header:
hack/boilerplate.go.txt
CI runs all checks via scripts/test-infra/verify.sh: gofmt, golangci-lint, helm lint, logcheck, unit tests, template freshness, kustomize overlay validation, Helm schema and README sync.
cmd/— entry points for each binarypkg/— core packages:pkg/nfd-master/— master server logic, label management, API controllerpkg/nfd-worker/— worker logic, feature detection orchestrationpkg/nfd-topology-updater/— topology updater logicpkg/nfd-gc/— garbage collectorapi/nfd/v1alpha1/types.go— CRD type definitions (NodeFeatureRule)pkg/features/— feature representation typespkg/resourcemonitor/— resource monitoring and pod resource scanningpkg/utils/— shared utilities (flags, hostpath, kubernetes helpers)
source/— feature source plugins (cpu, kernel, memory, network, pci, storage, system, usb, local, custom, fake)api/nfd/— separate Go module for the NFD API typesdeployment/— Kubernetes manifests:deployment/base/— kustomize base resourcesdeployment/overlays/— kustomize overlays (default, prune, prometheus, etc.)deployment/helm/node-feature-discovery/— Helm chartdeployment/components/— component configs (worker, master, topology-updater)
hack/— code generation and release scriptsscripts/test-infra/— CI scripts (build, verify, e2e)
Feature sources in source/ implement the LabelSource interface (see source/source.go). Each source detects specific hardware/OS features (CPU flags, kernel config, PCI devices, etc.) and returns them as labels.
The master uses a NodeFeatureRule CRD (defined in pkg/apis/nfd/) to apply custom labeling rules.
Communication between worker and master using NodeFeature object.
The project has two Go modules:
- Root module:
github.com/openshift/node-feature-discovery(Go 1.25) - API module:
github.com/openshift/node-feature-discovery/api/nfd(Go 1.24, separatego.mod)
The root module replaces the API module with a local path: replace github.com/openshift/node-feature-discovery/api/nfd => ./api/nfd.
Generate kustomize YAMLs:
make yamlsDeploy to a cluster:
make deployClean NFD labels:
make deploy-pruneUpdate Helm values from config examples:
make templatesGenerate CRDs and client code:
make generate