Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow optionally setting node taints defined on the NodeFeatureRule CR #910

Merged
merged 3 commits into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/nfd-master/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ func initFlags(flagset *flag.FlagSet) *master.Args {
"NB: the label namespace is omitted i.e. the filter is only applied to the name part after '/'.")
flagset.BoolVar(&args.NoPublish, "no-publish", false,
"Do not publish feature labels")
flagset.BoolVar(&args.EnableTaints, "enable-taints", false,
"Enable node tainting feature")
flagset.BoolVar(&args.FeatureRulesController, "featurerules-controller", true,
"Enable controller for NodeFeatureRule objects. Generates node labels based on the rules in these CRs.")
flagset.IntVar(&args.Port, "port", 8080,
Expand Down
6 changes: 6 additions & 0 deletions deployment/base/nfd-crds/cr-sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ spec:
# The following feature demonstrates the capabilities of the matchFeatures and
# matchAny matchers.
- name: "my feature rule"
taints:
- effect: PreferNoSchedule
key: "feature.node.kubernetes.io/special-node"
value: "true"
- effect: NoExecute
key: "feature.node.kubernetes.io/dedicated-node"
labels:
"my-complex-feature": "my-value"
# matchFeatures implements a logical AND over feature matchers.
Expand Down
29 changes: 29 additions & 0 deletions deployment/base/nfd-crds/nodefeaturerule-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,35 @@ spec:
name:
description: Name of the rule.
type: string
taints:
description: Taints to create if the rule matches.
items:
description: The node this Taint is attached to has the "effect"
on any pod that does not tolerate the Taint.
properties:
effect:
description: Required. The effect of the taint on pods
that do not tolerate the taint. Valid effects are NoSchedule,
PreferNoSchedule and NoExecute.
type: string
key:
description: Required. The taint key to be applied to
a node.
type: string
timeAdded:
description: TimeAdded represents the time at which the
taint was added. It is only written for NoExecute taints.
format: date-time
type: string
value:
description: The taint value corresponding to the taint
key.
type: string
required:
- effect
- key
type: object
type: array
vars:
additionalProperties:
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,35 @@ spec:
name:
description: Name of the rule.
type: string
taints:
description: Taints to create if the rule matches.
items:
description: The node this Taint is attached to has the "effect"
on any pod that does not tolerate the Taint.
properties:
effect:
description: Required. The effect of the taint on pods
that do not tolerate the taint. Valid effects are NoSchedule,
PreferNoSchedule and NoExecute.
type: string
key:
description: Required. The taint key to be applied to
a node.
type: string
timeAdded:
description: TimeAdded represents the time at which the
taint was added. It is only written for NoExecute taints.
format: date-time
type: string
value:
description: The taint value corresponding to the taint
key.
type: string
required:
- effect
- key
type: object
type: array
vars:
additionalProperties:
type: string
Expand Down
12 changes: 12 additions & 0 deletions docs/reference/master-commandline-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ Example:
nfd-master -cert-file=/opt/nfd/master.crt -key-file=/opt/nfd/master.key -ca-file=/opt/nfd/ca.crt
```

### -enable-taints

The `-enable-taints` flag enables/disables node tainting feature of NFD.

Default: *false*

Example:

```bash
nfd-master -enable-taints=true
```

### -key-file

The `-key-file` is one of the three flags (together with `-ca-file` and
Expand Down
61 changes: 59 additions & 2 deletions docs/usage/customization-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ labeling:
## NodeFeatureRule custom resource

`NodeFeatureRule` objects provide an easy way to create vendor or application
specific labels. It uses a flexible rule-based mechanism for creating labels
based on node feature.
specific labels and taints. It uses a flexible rule-based mechanism for creating
labels and optionally taints based on node features.

### A NodeFeatureRule example

Expand Down Expand Up @@ -76,6 +76,54 @@ re-labeling delay up to the sleep-interval of nfd-worker (1 minute by default).

See [Label rule format](#label-rule-format) for detailed description of
available fields and how to write labeling rules.
### NodeFeatureRule tainting feature

This feature is experimental.

In some circumstances it is desirable keep nodes with specialized hardware away from
running general workload and instead leave them for workloads that need the specialized
hardware. One way to achieve it is to taint the nodes with the specialized hardware
and add corresponding toleration to pods that require the special hardware. NFD
offers node tainting functionality which is disabled by default. User can define
one or more custom taints via the `taints` field of the NodeFeatureRule CR. The
same rule-based mechanism is applied here and the NFD taints only rule matching nodes.

To enable the tainting feature, `--enable-taints` flag needs to be set to `true`.
If the flag `--enable-taints` is set to `false` (i.e. disabled), taints defined in
the NodeFeatureRule CR have no effect and will be ignored by the NFD master.

**NOTE**: Before enabling any taints, make sure to edit nfd-worker daemonset to
tolerate the taints to be created. Otherwise, already running pods that do not
tolerate the taint are evicted immediately from the node including the nfd-worker
pod.

Example NodeFeatureRule with custom taints:

```yaml
apiVersion: nfd.k8s-sigs.io/v1alpha1
kind: NodeFeatureRule
metadata:
name: my-sample-rule-object
spec:
rules:
- name: "my sample taint rule"
taints:
- effect: PreferNoSchedule
key: "feature.node.kubernetes.io/special-node"
value: "true"
- effect: NoExecute
key: "feature.node.kubernetes.io/dedicated-node"
matchFeatures:
- feature: kernel.loadedmodule
matchExpressions:
dummy: {op: Exists}
- feature: kernel.config
matchExpressions:
X86: {op: In, value: ["y"]}
```

In this example, if the `my sample taint rule` rule is matched, `feature.node.kubernetes.io/pci-0300_1d0f.present=true:NoExecute`
and `feature.node.kubernetes.io/cpu-cpuid.ADX:NoExecute` taints are set on the node.

### NodeFeatureRule controller

Expand Down Expand Up @@ -365,6 +413,15 @@ details.
labels specified in the `labels` field will override anything
originating from `labelsTemplate`.

### Taints

*taints* is a list of taint entries and each entry can have `key`, `value` and `effect`,
where the `value` is optional. Effect could be `NoSchedule`, `PreferNoSchedule`
or `NoExecute`. To learn more about the meaning of these effects, check out k8s [documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/).

**NOTE** taints field is not available for the custom rules of nfd-worker and only
for NodeFeatureRule objects.

#### Vars

The `.vars` field is a map of values (key-value pairs) to store for subsequent
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/nfd/v1alpha1/annotations_labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,7 @@ const (

// WorkerVersionAnnotation is the annotation that holds the version of nfd-worker running on the node
WorkerVersionAnnotation = AnnotationNs + "/worker.version"

// NodeTaintsAnnotation is the annotation that holds the taints that nfd-master set on the node
NodeTaintsAnnotation = AnnotationNs + "/taints"
)
6 changes: 3 additions & 3 deletions pkg/apis/nfd/v1alpha1/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
"strings"
"text/template"

corev1 "k8s.io/api/core/v1"
"k8s.io/klog/v2"

"sigs.k8s.io/node-feature-discovery/pkg/utils"
)

Expand All @@ -32,6 +32,7 @@ import (
type RuleOutput struct {
Labels map[string]string
Vars map[string]string
Taints []corev1.Taint
}

// Execute the rule against a set of input features.
Expand Down Expand Up @@ -94,9 +95,8 @@ func (r *Rule) Execute(features *Features) (RuleOutput, error) {
vars[k] = v
}

ret := RuleOutput{Labels: labels, Vars: vars}
ret := RuleOutput{Labels: labels, Vars: vars, Taints: r.Taints}
utils.KlogDump(2, fmt.Sprintf("rule %q matched with: ", r.Name), " ", ret)

return ret, nil
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/nfd/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -120,6 +121,10 @@ type Rule struct {
// +optional
VarsTemplate string `json:"varsTemplate"`

// Taints to create if the rule matches.
// +optional
Taints []corev1.Taint `json:"taints,omitempty"`

// MatchFeatures specifies a set of matcher terms all of which must match.
// +optional
MatchFeatures FeatureMatcher `json:"matchFeatures"`
Expand Down
8 changes: 8 additions & 0 deletions pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading