diff --git a/deployment/helm/node-feature-discovery/templates/_helpers.tpl b/deployment/helm/node-feature-discovery/templates/_helpers.tpl index 73784a547..612bf9105 100644 --- a/deployment/helm/node-feature-discovery/templates/_helpers.tpl +++ b/deployment/helm/node-feature-discovery/templates/_helpers.tpl @@ -61,3 +61,14 @@ Create the name of the service account to use {{ default "default" .Values.serviceAccount.name }} {{- end -}} {{- end -}} + +{{/* +Create the name of the service account which topologyUpdater will use +*/}} +{{- define "node-feature-discovery.topologyUpdater.serviceAccountName" -}} +{{- if .Values.topologyUpdater.serviceAccount.create -}} + {{ default (printf "%s-topology-updater" (include "node-feature-discovery.fullname" .)) .Values.topologyUpdater.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.topologyUpdater.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/deployment/helm/node-feature-discovery/templates/clusterrole.yaml b/deployment/helm/node-feature-discovery/templates/clusterrole.yaml index a4da2303d..28412b439 100644 --- a/deployment/helm/node-feature-discovery/templates/clusterrole.yaml +++ b/deployment/helm/node-feature-discovery/templates/clusterrole.yaml @@ -18,4 +18,38 @@ rules: - patch - update - list +{{- if .Values.topologyUpdater.enable }} +- apiGroups: + - topology.node.k8s.io + resources: + - noderesourcetopologies + verbs: + - create + - get + - update +{{- end }} +{{- end }} + +--- +{{- if .Values.topologyUpdater.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "node-feature-discovery.fullname" . }}-topology-updater + labels: + {{- include "node-feature-discovery.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list +- apiGroups: + - "" + resources: + - pods + verbs: + - get {{- end }} diff --git a/deployment/helm/node-feature-discovery/templates/clusterrolebinding.yaml b/deployment/helm/node-feature-discovery/templates/clusterrolebinding.yaml index 4766d9a1b..a2e28dd76 100644 --- a/deployment/helm/node-feature-discovery/templates/clusterrolebinding.yaml +++ b/deployment/helm/node-feature-discovery/templates/clusterrolebinding.yaml @@ -14,3 +14,21 @@ subjects: name: {{ include "node-feature-discovery.serviceAccountName" . }} namespace: {{ $.Release.Namespace }} {{- end }} + +--- +{{- if .Values.topologyUpdater.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "node-feature-discovery.fullname" . }}-topology-updater + labels: + {{- include "node-feature-discovery.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "node-feature-discovery.fullname" . }}-topology-updater +subjects: +- kind: ServiceAccount + name: {{ include "node-feature-discovery.topologyUpdater.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} diff --git a/deployment/helm/node-feature-discovery/templates/master.yaml b/deployment/helm/node-feature-discovery/templates/master.yaml index 63dea55d0..752ac578d 100644 --- a/deployment/helm/node-feature-discovery/templates/master.yaml +++ b/deployment/helm/node-feature-discovery/templates/master.yaml @@ -62,6 +62,11 @@ spec: {{- if .Values.master.extraLabelNs | empty | not }} - "--extra-label-ns={{- join "," .Values.master.extraLabelNs }}" {{- end }} + {{- if .Values.master.topologyUpdaterNs | empty }} + - "--nrt-namespace={{ $.Release.Namespace }}" + {{- else }} + - "--nrt-namespace={{ .Values.master.topologyUpdaterNs }}" + {{- end }} ## Enable TLS authentication ## The example below assumes having the root certificate named ca.crt stored in ## a ConfigMap named nfd-ca-cert, and, the TLS authentication credentials stored diff --git a/deployment/helm/node-feature-discovery/templates/serviceaccount.yaml b/deployment/helm/node-feature-discovery/templates/serviceaccount.yaml index e4b09bad9..2950475d1 100644 --- a/deployment/helm/node-feature-discovery/templates/serviceaccount.yaml +++ b/deployment/helm/node-feature-discovery/templates/serviceaccount.yaml @@ -9,4 +9,18 @@ metadata: annotations: {{- toYaml . | nindent 4 }} {{- end }} -{{- end -}} +{{- end }} + +--- +{{- if .Values.topologyUpdater.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "node-feature-discovery.topologyUpdater.serviceAccountName" . }} + labels: + {{- include "node-feature-discovery.labels" . | nindent 4 }} + {{- with .Values.topologyUpdater.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/deployment/helm/node-feature-discovery/templates/topologyupdater-crds.yaml b/deployment/helm/node-feature-discovery/templates/topologyupdater-crds.yaml new file mode 100644 index 000000000..b6098f14d --- /dev/null +++ b/deployment/helm/node-feature-discovery/templates/topologyupdater-crds.yaml @@ -0,0 +1,146 @@ +{{- if and .Values.topologyUpdater.enable .Values.topologyUpdater.createCRDs -}} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/pull/1870 + controller-gen.kubebuilder.io/version: v0.6.0 + creationTimestamp: null + name: noderesourcetopologies.topology.node.k8s.io + namespace: "" +spec: + group: topology.node.k8s.io + names: + kind: NodeResourceTopology + listKind: NodeResourceTopologyList + plural: noderesourcetopologies + shortNames: + - node-res-topo + singular: noderesourcetopology + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: NodeResourceTopology describes node resources and their topology. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + topologyPolicies: + items: + type: string + type: array + zones: + description: ZoneList contains an array of Zone objects. + items: + description: Zone represents a resource topology zone, e.g. socket, + node, die or core. + properties: + attributes: + description: AttributeList contains an array of AttributeInfo objects. + items: + description: AttributeInfo contains one attribute of a Zone. + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + costs: + description: CostList contains an array of CostInfo objects. + items: + description: CostInfo describes the cost (or distance) between + two Zones. + properties: + name: + type: string + value: + format: int64 + type: integer + required: + - name + - value + type: object + type: array + name: + type: string + parent: + type: string + resources: + description: ResourceInfoList contains an array of ResourceInfo + objects. + items: + description: ResourceInfo contains information about one resource + type. + properties: + allocatable: + anyOf: + - type: integer + - type: string + description: Allocatable quantity of the resource, corresponding + to allocatable in node status, i.e. total amount of this + resource available to be used by pods. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + available: + anyOf: + - type: integer + - type: string + description: Available is the amount of this resource currently + available for new (to be scheduled) pods, i.e. Allocatable + minus the resources reserved by currently running pods. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + capacity: + anyOf: + - type: integer + - type: string + description: Capacity of the resource, corresponding to capacity + in node status, i.e. total amount of this resource that + the node has. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + name: + description: Name of the resource. + type: string + required: + - allocatable + - available + - capacity + - name + type: object + type: array + type: + type: string + required: + - name + - type + type: object + type: array + required: + - topologyPolicies + - zones + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end }} diff --git a/deployment/helm/node-feature-discovery/templates/topologyupdater.yaml b/deployment/helm/node-feature-discovery/templates/topologyupdater.yaml new file mode 100644 index 000000000..bb4647765 --- /dev/null +++ b/deployment/helm/node-feature-discovery/templates/topologyupdater.yaml @@ -0,0 +1,94 @@ +{{- if .Values.topologyUpdater.enable -}} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "node-feature-discovery.fullname" . }}-topology-updater + labels: + {{- include "node-feature-discovery.labels" . | nindent 4 }} + role: topology-updater +spec: + selector: + matchLabels: + {{- include "node-feature-discovery.selectorLabels" . | nindent 6 }} + role: topology-updater + template: + metadata: + labels: + {{- include "node-feature-discovery.selectorLabels" . | nindent 8 }} + role: topology-updater + annotations: + {{- toYaml .Values.topologyUpdater.annotations | nindent 8 }} + spec: + serviceAccountName: {{ include "node-feature-discovery.topologyUpdater.serviceAccountName" . }} + dnsPolicy: ClusterFirstWithHostNet + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.topologyUpdater.podSecurityContext | nindent 8 }} + containers: + - name: topology-updater + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - "nfd-topology-updater" + args: + - "--server={{ include "node-feature-discovery.fullname" . }}-master:{{ .Values.master.service.port }}" + {{- if .Values.topologyUpdater.updateInterval | empty | not }} + - "--sleep-interval={{ .Values.topologyUpdater.updateInterval }}" + {{- else }} + - "--sleep-interval=3s" + {{- end }} + {{- if .Values.topologyUpdater.watchNamespace | empty | not }} + - "--watch-namespace={{ .Values.topologyUpdater.watchNamespace }}" + {{- else }} + - "--watch-namespace=*" + {{- end }} + volumeMounts: + - name: kubelet-config + mountPath: /host-var/lib/kubelet/config.yaml + - name: kubelet-podresources-sock + mountPath: /host-var/lib/kubelet/pod-resources/kubelet.sock + - name: host-sys + mountPath: /host-sys + resources: + {{- toYaml .Values.topologyUpdater.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.topologyUpdater.securityContext | nindent 12 }} + volumes: + - name: host-sys + hostPath: + path: "/sys" + - name: kubelet-config + hostPath: + {{- if .Values.topologyUpdater.kubeletConfigPath | empty | not }} + path: {{ .Values.topologyUpdater.kubeletConfigPath }} + {{- else }} + path: /var/lib/kubelet/config.yaml + {{- end }} + - name: kubelet-podresources-sock + hostPath: + {{- if .Values.topologyUpdater.kubeletPodResourcesSockPath | empty | not }} + path: {{ .Values.topologyUpdater.kubeletPodResourcesSockPath }} + {{- else }} + path: /var/lib/kubelet/pod-resources/kubelet.sock + {{- end }} + {{- with .Values.topologyUpdater.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.topologyUpdater.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.topologyUpdater.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/deployment/helm/node-feature-discovery/values.yaml b/deployment/helm/node-feature-discovery/values.yaml index 6f726adf3..426b907ac 100644 --- a/deployment/helm/node-feature-discovery/values.yaml +++ b/deployment/helm/node-feature-discovery/values.yaml @@ -27,6 +27,7 @@ master: podSecurityContext: {} # fsGroup: 2000 + topologyUpdaterNs: "" securityContext: allowPrivilegeEscalation: false capabilities: @@ -228,6 +229,49 @@ worker: annotations: {} + affinity: {} + +topologyUpdater: + enable: false + createCRDs: false + + serviceAccount: + create: false + annotations: {} + name: + rbac: + create: false + + kubeletConfigPath: + kubeletPodResourcesSockPath: + updateInterval: 60s + watchNamespace: "*" + + podSecurityContext: {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: [ "ALL" ] + readOnlyRootFilesystem: true + runAsUser: 0 + + resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + nodeSelector: {} + tolerations: [] + annotations: {} + affinity: {} + ## RBAC parameteres ## https://kubernetes.io/docs/reference/access-authn-authz/rbac/ ## diff --git a/docs/get-started/deployment-and-usage.md b/docs/get-started/deployment-and-usage.md index 9c6fab4cf..902dbbbb3 100644 --- a/docs/get-started/deployment-and-usage.md +++ b/docs/get-started/deployment-and-usage.md @@ -248,20 +248,21 @@ We have introduced the following Chart parameters. ##### Master pod parameters -| Name | Type | Default | description | -| ---- | ---- | ------- | ----------- | -| `master.*` | dict | | NFD master deployment configuration | -| `master.instance` | string | | Instance name. Used to separate annotation namespaces for multiple parallel deployments | -| `master.extraLabelNs` | array | [] | List of allowed extra label namespaces | -| `master.replicaCount` | integer | 1 | Number of desired pods. This is a pointer to distinguish between explicit zero and not specified | -| `master.podSecurityContext` | dict | {} | SecurityContext holds pod-level security attributes and common container settings | -| `master.service.type` | string | ClusterIP | NFD master service type | -| `master.service.port` | integer | port | NFD master service port | -| `master.resources` | dict | {} | NFD master pod [resources management](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) | -| `master.nodeSelector` | dict | {} | NFD master pod [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) | -| `master.tolerations` | dict | _Scheduling to master node is disabled_ | NFD master pod [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | -| `master.annotations` | dict | {} | NFD master pod [metadata](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) | -| `master.affinity` | dict | | NFD master pod required [node affinity](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | +| Name | Type | Default | description | +|-----------------------------|---------|-----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------| +| `master.*` | dict | | NFD master deployment configuration | +| `master.instance` | string | | Instance name. Used to separate annotation namespaces for multiple parallel deployments | +| `master.extraLabelNs` | array | [] | List of allowed extra label namespaces | +| `master.topologyUpdaterNs` | string | "" | Namespace in which Node Resource Topology CR are created, the namespace specified must be already existed. | +| `master.replicaCount` | integer | 1 | Number of desired pods. This is a pointer to distinguish between explicit zero and not specified | +| `master.podSecurityContext` | dict | {} | SecurityContext holds pod-level security attributes and common container settings | +| `master.service.type` | string | ClusterIP | NFD master service type | +| `master.service.port` | integer | port | NFD master service port | +| `master.resources` | dict | {} | NFD master pod [resources management](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) | +| `master.nodeSelector` | dict | {} | NFD master pod [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) | +| `master.tolerations` | dict | _Scheduling to master node is disabled_ | NFD master pod [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | +| `master.annotations` | dict | {} | NFD master pod [metadata](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) | +| `master.affinity` | dict | | NFD master pod required [node affinity](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | ##### Worker pod parameters @@ -277,6 +278,30 @@ We have introduced the following Chart parameters. | `worker.tolerations` | dict | {} | NFD worker pod [node tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | | `worker.annotations` | dict | {} | NFD worker pod [metadata](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) | +##### Topology updater parameters + +| Name | Type | Default | description | +|-----------------------------------------------|--------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `topologyUpdater.*` | dict | | NFD Topology Updater configuration | +| `topologyUpdater.enable` | bool | false | Specifies whether the NFD Topology Updater should be created | +| `topologyUpdater.createCRDs` | bool | false | Specifies whether the NFD Topology Updater CRDs should be created | +| `topologyUpdater.serviceAccount.create` | bool | true | Specifies whether the service account for topology updater should be created | +| `topologyUpdater.serviceAccount.annotations` | dict | {} | Annotations to add to the service account for topology updater | +| `topologyUpdater.serviceAccount.name` | string | | The name of the service account for topology updater to use. If not set and create is true, a name is generated using the fullname template and `-topology-updater` suffix | +| `topologyUpdater.rbac` | dict | | RBAC [parameteres](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) for the topology updater | +| `topologyUpdater.rbac.create` | bool | false | Specifies whether the cluster role and binding for topology updater should be created | +| `topologyUpdater.kubeletConfigPath` | string | "" | Specifies the kubelet config host path | +| `topologyUpdater.kubeletPodResourcesSockPath` | string | "" | Specifies the kubelet sock path to read pod resources | +| `topologyUpdater.updateInterval` | string | 60s | Time to sleep between CR updates. Non-positive value implies no CR update. | +| `topologyUpdater.watchNamespace` | string | `*` | Namespace to watch pods, `*` for all namespaces | +| `topologyUpdater.podSecurityContext` | dict | {} | SecurityContext holds pod-level security attributes and common container settings | +| `topologyUpdater.securityContext` | dict | {} | Container [security settings](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) | +| `topologyUpdater.resources` | dict | {} | Topology updater pod [resources management](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) | +| `topologyUpdater.nodeSelector` | dict | {} | Topology updater pod [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) | +| `topologyUpdater.tolerations` | dict | {} | Topology updater pod [node tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) | +| `topologyUpdater.annotations` | dict | {} | Topology updater pod [metadata](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) | +| `topologyUpdater.affinity` | dict | {} | Topology updater pod [affinity](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) | + ### Build your own If you want to use the latest development version (master branch) you need to