Este contenido no está disponible en el idioma seleccionado.
Specialized hardware and driver enablement
Learn about hardware enablement on OpenShift Container Platform
Abstract
Chapter 1. About specialized hardware and driver enablement Copiar enlaceEnlace copiado en el portapapeles!
The Driver Toolkit (DTK) is a container image in the OpenShift Container Platform payload which is meant to be used as a base image on which to build driver containers. The Driver Toolkit image contains the kernel packages commonly required as dependencies to build or install kernel modules as well as a few tools needed in driver containers. The version of these packages will match the kernel version running on the RHCOS nodes in the corresponding OpenShift Container Platform release.
Driver containers are container images used for building and deploying out-of-tree kernel modules and drivers on container operating systems such as Red Hat Enterprise Linux CoreOS (RHCOS). Kernel modules and drivers are software libraries running with a high level of privilege in the operating system kernel. They extend the kernel functionalities or provide the hardware-specific code required to control new devices. Examples include hardware devices like field-programmable gate arrays (FPGA) or graphics processing units (GPU), and software-defined storage solutions, which all require kernel modules on client machines. Driver containers are the first layer of the software stack used to enable these technologies on OpenShift Container Platform deployments.
Chapter 2. Driver Toolkit Copiar enlaceEnlace copiado en el portapapeles!
Learn about the Driver Toolkit and how you can use it as a base image for driver containers for enabling special software and hardware devices on OpenShift Container Platform deployments.
2.1. About the Driver Toolkit Copiar enlaceEnlace copiado en el portapapeles!
Background
The Driver Toolkit is a container image in the OpenShift Container Platform payload used as a base image on which you can build driver containers. The Driver Toolkit image includes the kernel packages commonly required as dependencies to build or install kernel modules, as well as a few tools needed in driver containers. The version of these packages will match the kernel version running on the Red Hat Enterprise Linux CoreOS (RHCOS) nodes in the corresponding OpenShift Container Platform release.
Driver containers are container images used for building and deploying out-of-tree kernel modules and drivers on container operating systems like RHCOS. Kernel modules and drivers are software libraries running with a high level of privilege in the operating system kernel. They extend the kernel functionalities or provide the hardware-specific code required to control new devices. Examples include hardware devices like Field Programmable Gate Arrays (FPGA) or GPUs, and software-defined storage (SDS) solutions, such as Lustre parallel file systems, which require kernel modules on client machines. Driver containers are the first layer of the software stack used to enable these technologies on Kubernetes.
The list of kernel packages in the Driver Toolkit includes the following and their dependencies:
-
kernel-core -
kernel-devel -
kernel-headers -
kernel-modules -
kernel-modules-extra
In addition, the Driver Toolkit also includes the corresponding real-time kernel packages:
-
kernel-rt-core -
kernel-rt-devel -
kernel-rt-modules -
kernel-rt-modules-extra
The Driver Toolkit also has several tools that are commonly needed to build and install kernel modules, including:
-
elfutils-libelf-devel -
kmod -
binutilskabi-dw -
kernel-abi-whitelists - dependencies for the above
Purpose
Prior to the Driver Toolkit’s existence, users would install kernel packages in a pod or build config on OpenShift Container Platform using entitled builds or by installing from the kernel RPMs in the hosts
machine-os-content
The Driver Toolkit is also used by the Kernel Module Management (KMM), which is currently available as a community Operator on OperatorHub. KMM supports out-of-tree and third-party kernel drivers and the support software for the underlying operating system. Users can create modules for KMM to build and deploy a driver container, as well as support software like a device plugin, or metrics. Modules can include a build config to build a driver container-based on the Driver Toolkit, or KMM can deploy a prebuilt driver container.
2.2. Pulling the Driver Toolkit container image Copiar enlaceEnlace copiado en el portapapeles!
The
driver-toolkit
oc adm
2.2.1. Pulling the Driver Toolkit container image from registry.redhat.io Copiar enlaceEnlace copiado en el portapapeles!
Instructions for pulling the
driver-toolkit
registry.redhat.io
podman
registry.redhat.io
registry.redhat.io/openshift4/driver-toolkit-rhel8:v4.12
2.2.2. Finding the Driver Toolkit image URL in the payload Copiar enlaceEnlace copiado en el portapapeles!
Prerequisites
- You obtained the image pull secret from the Red Hat OpenShift Cluster Manager.
-
You installed the OpenShift CLI ().
oc
Procedure
Use the
command to extract the image URL of theoc admcorresponding to a certain release:driver-toolkitFor an x86 image, enter the following command:
$ oc adm release info quay.io/openshift-release-dev/ocp-release:4.12.z-x86_64 --image-for=driver-toolkitFor an ARM image, enter the following command:
$ oc adm release info quay.io/openshift-release-dev/ocp-release:4.12.z-aarch64 --image-for=driver-toolkit
Example output
quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:0fd84aee79606178b6561ac71f8540f404d518ae5deff45f6d6ac8f02636c7f4Obtain this image by using a valid pull secret, such as the pull secret required to install OpenShift Container Platform:
$ podman pull --authfile=path/to/pullsecret.json quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:<SHA>
2.3. Using the Driver Toolkit Copiar enlaceEnlace copiado en el portapapeles!
As an example, the Driver Toolkit can be used as the base image for building a very simple kernel module called
simple-kmod
The Driver Toolkit includes the necessary dependencies,
openssl
mokutil
keyutils
simple-kmod
Secure Boot
2.3.1. Build and run the simple-kmod driver container on a cluster Copiar enlaceEnlace copiado en el portapapeles!
Prerequisites
- You have a running OpenShift Container Platform cluster.
-
You set the Image Registry Operator state to for your cluster.
Managed -
You installed the OpenShift CLI ().
oc -
You are logged into the OpenShift CLI as a user with privileges.
cluster-admin
Procedure
Create a namespace. For example:
$ oc new-project simple-kmod-demo
The YAML defines an
for storing theImageStreamdriver container image, and asimple-kmodfor building the container. Save this YAML asBuildConfig.0000-buildconfig.yaml.templateapiVersion: image.openshift.io/v1 kind: ImageStream metadata: labels: app: simple-kmod-driver-container name: simple-kmod-driver-container namespace: simple-kmod-demo spec: {} --- apiVersion: build.openshift.io/v1 kind: BuildConfig metadata: labels: app: simple-kmod-driver-build name: simple-kmod-driver-build namespace: simple-kmod-demo spec: nodeSelector: node-role.kubernetes.io/worker: "" runPolicy: "Serial" triggers: - type: "ConfigChange" - type: "ImageChange" source: dockerfile: | ARG DTK FROM ${DTK} as builder ARG KVER WORKDIR /build/ RUN git clone https://github.com/openshift-psap/simple-kmod.git WORKDIR /build/simple-kmod RUN make all install KVER=${KVER} FROM registry.redhat.io/ubi8/ubi-minimal ARG KVER # Required for installing `modprobe` RUN microdnf install kmod COPY --from=builder /lib/modules/${KVER}/simple-kmod.ko /lib/modules/${KVER}/ COPY --from=builder /lib/modules/${KVER}/simple-procfs-kmod.ko /lib/modules/${KVER}/ RUN depmod ${KVER} strategy: dockerStrategy: buildArgs: - name: KMODVER value: DEMO # $ oc adm release info quay.io/openshift-release-dev/ocp-release:<cluster version>-x86_64 --image-for=driver-toolkit - name: DTK value: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:34864ccd2f4b6e385705a730864c04a40908e57acede44457a783d739e377cae - name: KVER value: 4.18.0-372.26.1.el8_6.x86_64 output: to: kind: ImageStreamTag name: simple-kmod-driver-container:demoSubstitute the correct driver toolkit image for the OpenShift Container Platform version you are running in place of “DRIVER_TOOLKIT_IMAGE” with the following commands.
$ OCP_VERSION=$(oc get clusterversion/version -ojsonpath={.status.desired.version})$ DRIVER_TOOLKIT_IMAGE=$(oc adm release info $OCP_VERSION --image-for=driver-toolkit)$ sed "s#DRIVER_TOOLKIT_IMAGE#${DRIVER_TOOLKIT_IMAGE}#" 0000-buildconfig.yaml.template > 0000-buildconfig.yamlCreate the image stream and build config with
$ oc create -f 0000-buildconfig.yamlAfter the builder pod completes successfully, deploy the driver container image as a
.DaemonSetThe driver container must run with the privileged security context in order to load the kernel modules on the host. The following YAML file contains the RBAC rules and the
for running the driver container. Save this YAML asDaemonSet.1000-drivercontainer.yamlapiVersion: v1 kind: ServiceAccount metadata: name: simple-kmod-driver-container --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: simple-kmod-driver-container rules: - apiGroups: - security.openshift.io resources: - securitycontextconstraints verbs: - use resourceNames: - privileged --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: simple-kmod-driver-container roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: simple-kmod-driver-container subjects: - kind: ServiceAccount name: simple-kmod-driver-container userNames: - system:serviceaccount:simple-kmod-demo:simple-kmod-driver-container --- apiVersion: apps/v1 kind: DaemonSet metadata: name: simple-kmod-driver-container spec: selector: matchLabels: app: simple-kmod-driver-container template: metadata: labels: app: simple-kmod-driver-container spec: serviceAccount: simple-kmod-driver-container serviceAccountName: simple-kmod-driver-container containers: - image: image-registry.openshift-image-registry.svc:5000/simple-kmod-demo/simple-kmod-driver-container:demo name: simple-kmod-driver-container imagePullPolicy: Always command: [sleep, infinity] lifecycle: postStart: exec: command: ["modprobe", "-v", "-a" , "simple-kmod", "simple-procfs-kmod"] preStop: exec: command: ["modprobe", "-r", "-a" , "simple-kmod", "simple-procfs-kmod"] securityContext: privileged: true nodeSelector: node-role.kubernetes.io/worker: ""Create the RBAC rules and daemon set:
$ oc create -f 1000-drivercontainer.yaml
After the pods are running on the worker nodes, verify that the
kernel module is loaded successfully on the host machines withsimple_kmod.lsmodVerify that the pods are running:
$ oc get pod -n simple-kmod-demoExample output
NAME READY STATUS RESTARTS AGE simple-kmod-driver-build-1-build 0/1 Completed 0 6m simple-kmod-driver-container-b22fd 1/1 Running 0 40s simple-kmod-driver-container-jz9vn 1/1 Running 0 40s simple-kmod-driver-container-p45cc 1/1 Running 0 40sExecute the
command in the driver container pod:lsmod$ oc exec -it pod/simple-kmod-driver-container-p45cc -- lsmod | grep simpleExample output
simple_procfs_kmod 16384 0 simple_kmod 16384 0
Chapter 3. Node Feature Discovery Operator Copiar enlaceEnlace copiado en el portapapeles!
Learn about the Node Feature Discovery (NFD) Operator and how you can use it to expose node-level information by orchestrating Node Feature Discovery, a Kubernetes add-on for detecting hardware features and system configuration.
The Node Feature Discovery Operator (NFD) manages the detection of hardware features and configuration in an OpenShift Container Platform cluster by labeling the nodes with hardware-specific information. NFD labels the host with node-specific attributes, such as PCI cards, kernel, operating system version, and so on.
The NFD Operator can be found on the Operator Hub by searching for “Node Feature Discovery”.
3.1. Installing the Node Feature Discovery Operator Copiar enlaceEnlace copiado en el portapapeles!
The Node Feature Discovery (NFD) Operator orchestrates all resources needed to run the NFD daemon set. As a cluster administrator, you can install the NFD Operator by using the OpenShift Container Platform CLI or the web console.
3.1.1. Installing the NFD Operator using the CLI Copiar enlaceEnlace copiado en el portapapeles!
As a cluster administrator, you can install the NFD Operator using the CLI.
Prerequisites
- An OpenShift Container Platform cluster
-
Install the OpenShift CLI ().
oc -
Log in as a user with privileges.
cluster-admin
Procedure
Create a namespace for the NFD Operator.
Create the following
custom resource (CR) that defines theNamespacenamespace, and then save the YAML in theopenshift-nfdfile. Setnfd-namespace.yamltocluster-monitoring."true"apiVersion: v1 kind: Namespace metadata: name: openshift-nfd labels: name: openshift-nfd openshift.io/cluster-monitoring: "true"Create the namespace by running the following command:
$ oc create -f nfd-namespace.yaml
Install the NFD Operator in the namespace you created in the previous step by creating the following objects:
Create the following
CR and save the YAML in theOperatorGroupfile:nfd-operatorgroup.yamlapiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: generateName: openshift-nfd- name: openshift-nfd namespace: openshift-nfd spec: targetNamespaces: - openshift-nfdCreate the
CR by running the following command:OperatorGroup$ oc create -f nfd-operatorgroup.yamlCreate the following
CR and save the YAML in theSubscriptionfile:nfd-sub.yamlExample Subscription
apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: nfd namespace: openshift-nfd spec: channel: "stable" installPlanApproval: Automatic name: nfd source: redhat-operators sourceNamespace: openshift-marketplaceCreate the subscription object by running the following command:
$ oc create -f nfd-sub.yamlChange to the
project:openshift-nfd$ oc project openshift-nfd
Verification
To verify that the Operator deployment is successful, run:
$ oc get podsExample output
NAME READY STATUS RESTARTS AGE nfd-controller-manager-7f86ccfb58-vgr4x 2/2 Running 0 10mA successful deployment shows a
status.Running
3.1.2. Installing the NFD Operator using the web console Copiar enlaceEnlace copiado en el portapapeles!
As a cluster administrator, you can install the NFD Operator using the web console.
Procedure
- In the OpenShift Container Platform web console, click Operators → OperatorHub.
- Choose Node Feature Discovery from the list of available Operators, and then click Install.
- On the Install Operator page, select A specific namespace on the cluster, and then click Install. You do not need to create a namespace because it is created for you.
Verification
To verify that the NFD Operator installed successfully:
- Navigate to the Operators → Installed Operators page.
Ensure that Node Feature Discovery is listed in the openshift-nfd project with a Status of InstallSucceeded.
NoteDuring installation an Operator might display a Failed status. If the installation later succeeds with an InstallSucceeded message, you can ignore the Failed message.
Troubleshooting
If the Operator does not appear as installed, troubleshoot further:
- Navigate to the Operators → Installed Operators page and inspect the Operator Subscriptions and Install Plans tabs for any failure or errors under Status.
-
Navigate to the Workloads → Pods page and check the logs for pods in the project.
openshift-nfd
3.2. Using the Node Feature Discovery Operator Copiar enlaceEnlace copiado en el portapapeles!
The Node Feature Discovery (NFD) Operator orchestrates all resources needed to run the Node-Feature-Discovery daemon set by watching for a
NodeFeatureDiscovery
NodeFeatureDiscovery
nfd-worker-conf
As a cluster administrator, you can create a
NodeFeatureDiscovery
oc
3.2.1. Creating a NodeFeatureDiscovery CR by using the CLI Copiar enlaceEnlace copiado en el portapapeles!
As a cluster administrator, you can create a
NodeFeatureDiscovery
oc
Prerequisites
- You have access to an OpenShift Container Platform cluster
-
You installed the OpenShift CLI ().
oc -
You logged in as a user with privileges.
cluster-admin - You installed the NFD Operator.
Procedure
Create a
CR:NodeFeatureDiscoveryExample
NodeFeatureDiscoveryCRapiVersion: nfd.openshift.io/v1 kind: NodeFeatureDiscovery metadata: name: nfd-instance namespace: openshift-nfd spec: instance: "" # instance is empty by default topologyupdater: false # False by default operand: image: registry.redhat.io/openshift4/ose-node-feature-discovery:v4.12 imagePullPolicy: Always workerConfig: configData: | core: # labelWhiteList: # noPublish: false sleepInterval: 60s # sources: [all] # klog: # addDirHeader: false # alsologtostderr: false # logBacktraceAt: # logtostderr: true # skipHeaders: false # stderrthreshold: 2 # v: 0 # vmodule: ## NOTE: the following options are not dynamically run-time configurable ## and require a nfd-worker restart to take effect after being changed # logDir: # logFile: # logFileMaxSize: 1800 # skipLogHeaders: false sources: cpu: cpuid: # NOTE: whitelist has priority over blacklist attributeBlacklist: - "BMI1" - "BMI2" - "CLMUL" - "CMOV" - "CX16" - "ERMS" - "F16C" - "HTT" - "LZCNT" - "MMX" - "MMXEXT" - "NX" - "POPCNT" - "RDRAND" - "RDSEED" - "RDTSCP" - "SGX" - "SSE" - "SSE2" - "SSE3" - "SSE4.1" - "SSE4.2" - "SSSE3" attributeWhitelist: kernel: kconfigFile: "/path/to/kconfig" configOpts: - "NO_HZ" - "X86" - "DMI" pci: deviceClassWhitelist: - "0200" - "03" - "12" deviceLabelFields: - "class" customConfig: configData: | - name: "more.kernel.features" matchOn: - loadedKMod: ["example_kmod3"]Create the
CR by running the following command:NodeFeatureDiscovery$ oc apply -f <filename>
Verification
Check that the
CR was created by running the following command:NodeFeatureDiscovery$ oc get podsExample output
NAME READY STATUS RESTARTS AGE nfd-controller-manager-7f86ccfb58-vgr4x 2/2 Running 0 11m nfd-master-hcn64 1/1 Running 0 60s nfd-master-lnnxx 1/1 Running 0 60s nfd-master-mp6hr 1/1 Running 0 60s nfd-worker-vgcz9 1/1 Running 0 60s nfd-worker-xqbws 1/1 Running 0 60sA successful deployment shows a
status.Running
3.2.2. Creating a NodeFeatureDiscovery CR by using the CLI in a disconnected environment Copiar enlaceEnlace copiado en el portapapeles!
As a cluster administrator, you can create a
NodeFeatureDiscovery
oc
Prerequisites
- You have access to an OpenShift Container Platform cluster
-
You installed the OpenShift CLI ().
oc -
You logged in as a user with privileges.
cluster-admin - You installed the NFD Operator.
- You have access to a mirror registry with the required images.
-
You installed the CLI tool.
skopeo
Procedure
Determine the digest of the registry image:
Run the following command:
$ skopeo inspect docker://registry.redhat.io/openshift4/ose-node-feature-discovery:<openshift_version>Example command
$ skopeo inspect docker://registry.redhat.io/openshift4/ose-node-feature-discovery:v4.12Inspect the output to identify the image digest:
Example output
{ ... "Digest": "sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", ... }
Use the
CLI tool to copy the image fromskopeoto your mirror registry, by running the following command:registry.redhat.ioskopeo copy docker://registry.redhat.io/openshift4/ose-node-feature-discovery@<image_digest> docker://<mirror_registry>/openshift4/ose-node-feature-discovery@<image_digest>Example command
skopeo copy docker://registry.redhat.io/openshift4/ose-node-feature-discovery@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef docker://<your-mirror-registry>/openshift4/ose-node-feature-discovery@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdefCreate a
CR:NodeFeatureDiscoveryExample
NodeFeatureDiscoveryCRapiVersion: nfd.openshift.io/v1 kind: NodeFeatureDiscovery metadata: name: nfd-instance spec: operand: image: <mirror_registry>/openshift4/ose-node-feature-discovery@<image_digest> imagePullPolicy: Always workerConfig: configData: | core: # labelWhiteList: # noPublish: false sleepInterval: 60s # sources: [all] # klog: # addDirHeader: false # alsologtostderr: false # logBacktraceAt: # logtostderr: true # skipHeaders: false # stderrthreshold: 2 # v: 0 # vmodule: ## NOTE: the following options are not dynamically run-time configurable ## and require a nfd-worker restart to take effect after being changed # logDir: # logFile: # logFileMaxSize: 1800 # skipLogHeaders: false sources: cpu: cpuid: # NOTE: whitelist has priority over blacklist attributeBlacklist: - "BMI1" - "BMI2" - "CLMUL" - "CMOV" - "CX16" - "ERMS" - "F16C" - "HTT" - "LZCNT" - "MMX" - "MMXEXT" - "NX" - "POPCNT" - "RDRAND" - "RDSEED" - "RDTSCP" - "SGX" - "SSE" - "SSE2" - "SSE3" - "SSE4.1" - "SSE4.2" - "SSSE3" attributeWhitelist: kernel: kconfigFile: "/path/to/kconfig" configOpts: - "NO_HZ" - "X86" - "DMI" pci: deviceClassWhitelist: - "0200" - "03" - "12" deviceLabelFields: - "class" customConfig: configData: | - name: "more.kernel.features" matchOn: - loadedKMod: ["example_kmod3"]Create the
CR by running the following command:NodeFeatureDiscovery$ oc apply -f <filename>
Verification
Check the status of the
CR by running the following command:NodeFeatureDiscovery$ oc get nodefeaturediscovery nfd-instance -o yamlCheck that the pods are running without
errors by running the following command:ImagePullBackOff$ oc get pods -n <nfd_namespace>
3.2.3. Creating a NodeFeatureDiscovery CR by using the web console Copiar enlaceEnlace copiado en el portapapeles!
As a cluster administrator, you can create a
NodeFeatureDiscovery
Prerequisites
- You have access to an OpenShift Container Platform cluster
-
You logged in as a user with privileges.
cluster-admin - You installed the NFD Operator.
Procedure
- Navigate to the Operators → Installed Operators page.
- In the Node Feature Discovery section, under Provided APIs, click Create instance.
-
Edit the values of the CR.
NodeFeatureDiscovery - Click Create.
3.3. Configuring the Node Feature Discovery Operator Copiar enlaceEnlace copiado en el portapapeles!
3.3.1. core Copiar enlaceEnlace copiado en el portapapeles!
The
core
core.sleepInterval
core.sleepInterval
This value is overridden by the deprecated
--sleep-interval
Example usage
core:
sleepInterval: 60s
The default value is
60s
core.sources
core.sources
all
This value is overridden by the deprecated
--sources
Default:
[all]
Example usage
core:
sources:
- system
- custom
core.labelWhiteList
core.labelWhiteList
The regular expression is only matched against the basename part of the label, the part of the name after '/'. The label prefix, or namespace, is omitted.
This value is overridden by the deprecated
--label-whitelist
Default:
null
Example usage
core:
labelWhiteList: '^cpu-cpuid'
core.noPublish
Setting
core.noPublish
true
nfd-master
nfd-worker
nfd-master
This value is overridden by the
--no-publish
Example:
Example usage
core:
noPublish: true
The default value is
false
core.klog
The following options specify the logger configuration, most of which can be dynamically adjusted at run-time.
The logger options can also be specified using command-line flags, which take precedence over any corresponding config file options.
core.klog.addDirHeader
If set to
true
core.klog.addDirHeader
Default:
false
Run-time configurable: yes
core.klog.alsologtostderr
Log to standard error as well as files.
Default:
false
Run-time configurable: yes
core.klog.logBacktraceAt
When logging hits line file:N, emit a stack trace.
Default: empty
Run-time configurable: yes
core.klog.logDir
If non-empty, write log files in this directory.
Default: empty
Run-time configurable: no
core.klog.logFile
If not empty, use this log file.
Default: empty
Run-time configurable: no
core.klog.logFileMaxSize
core.klog.logFileMaxSize
0
Default:
1800
Run-time configurable: no
core.klog.logtostderr
Log to standard error instead of files
Default:
true
Run-time configurable: yes
core.klog.skipHeaders
If
core.klog.skipHeaders
true
Default:
false
Run-time configurable: yes
core.klog.skipLogHeaders
If
core.klog.skipLogHeaders
true
Default:
false
Run-time configurable: no
core.klog.stderrthreshold
Logs at or above this threshold go to stderr.
Default:
2
Run-time configurable: yes
core.klog.v
core.klog.v
Default:
0
Run-time configurable: yes
core.klog.vmodule
core.klog.vmodule
pattern=N
Default: empty
Run-time configurable: yes
3.3.2. sources Copiar enlaceEnlace copiado en el portapapeles!
The
sources
sources.cpu.cpuid.attributeBlacklist
Prevent publishing
cpuid
This value is overridden by
sources.cpu.cpuid.attributeWhitelist
Default:
[BMI1, BMI2, CLMUL, CMOV, CX16, ERMS, F16C, HTT, LZCNT, MMX, MMXEXT, NX, POPCNT, RDRAND, RDSEED, RDTSCP, SGX, SGXLC, SSE, SSE2, SSE3, SSE4.1, SSE4.2, SSSE3]
Example usage
sources:
cpu:
cpuid:
attributeBlacklist: [MMX, MMXEXT]
sources.cpu.cpuid.attributeWhitelist
Only publish the
cpuid
sources.cpu.cpuid.attributeWhitelist
sources.cpu.cpuid.attributeBlacklist
Default: empty
Example usage
sources:
cpu:
cpuid:
attributeWhitelist: [AVX512BW, AVX512CD, AVX512DQ, AVX512F, AVX512VL]
sources.kernel.kconfigFile
sources.kernel.kconfigFile
Default: empty
Example usage
sources:
kernel:
kconfigFile: "/path/to/kconfig"
sources.kernel.configOpts
sources.kernel.configOpts
Default:
[NO_HZ, NO_HZ_IDLE, NO_HZ_FULL, PREEMPT]
Example usage
sources:
kernel:
configOpts: [NO_HZ, X86, DMI]
sources.pci.deviceClassWhitelist
sources.pci.deviceClassWhitelist
03
0300
deviceLabelFields
Default:
["03", "0b40", "12"]
Example usage
sources:
pci:
deviceClassWhitelist: ["0200", "03"]
sources.pci.deviceLabelFields
sources.pci.deviceLabelFields
class
vendor
device
subsystem_vendor
subsystem_device
Default:
[class, vendor]
Example usage
sources:
pci:
deviceLabelFields: [class, vendor, device]
With the example config above, NFD would publish labels such as
feature.node.kubernetes.io/pci-<class-id>_<vendor-id>_<device-id>.present=true
sources.usb.deviceClassWhitelist
sources.usb.deviceClassWhitelist
deviceLabelFields
Default:
["0e", "ef", "fe", "ff"]
Example usage
sources:
usb:
deviceClassWhitelist: ["ef", "ff"]
sources.usb.deviceLabelFields
sources.usb.deviceLabelFields
class
vendor
device
Default:
[class, vendor, device]
Example usage
sources:
pci:
deviceLabelFields: [class, vendor]
With the example config above, NFD would publish labels like:
feature.node.kubernetes.io/usb-<class-id>_<vendor-id>.present=true
sources.custom
sources.custom
Default: empty
Example usage
source:
custom:
- name: "my.custom.feature"
matchOn:
- loadedKMod: ["e1000e"]
- pciId:
class: ["0200"]
vendor: ["8086"]
3.4. About the NodeFeatureRule custom resource Copiar enlaceEnlace copiado en el portapapeles!
NodeFeatureRule
NodeFeatureDiscovery
NodeFeatureRule
3.5. Using the NodeFeatureRule custom resource Copiar enlaceEnlace copiado en el portapapeles!
Create a
NodeFeatureRule
Procedure
Create a custom resource file named
that contains the following text:nodefeaturerule.yamlapiVersion: nfd.openshift.io/v1 kind: NodeFeatureRule metadata: name: example-rule spec: rules: - name: "example rule" labels: "example-custom-feature": "true" # Label is created if all of the rules below match matchFeatures: # Match if "veth" kernel module is loaded - feature: kernel.loadedmodule matchExpressions: veth: {op: Exists} # Match if any PCI device with vendor 8086 exists in the system - feature: pci.device matchExpressions: vendor: {op: In, value: ["8086"]}This custom resource specifies that labelling occurs when the
module is loaded and any PCI device with vendor codevethexists in the cluster.8086Apply the
file to your cluster by running the following command:nodefeaturerule.yaml$ oc apply -f https://raw.githubusercontent.com/kubernetes-sigs/node-feature-discovery/v0.13.6/examples/nodefeaturerule.yamlThe example applies the feature label on nodes with the
module loaded and any PCI device with vendor codevethexists.8086NoteA relabeling delay of up to 1 minute might occur.
3.6. Using the NFD Topology Updater Copiar enlaceEnlace copiado en el portapapeles!
The Node Feature Discovery (NFD) Topology Updater is a daemon responsible for examining allocated resources on a worker node. It accounts for resources that are available to be allocated to new pod on a per-zone basis, where a zone can be a Non-Uniform Memory Access (NUMA) node. The NFD Topology Updater communicates the information to nfd-master, which creates a
NodeResourceTopology
To enable the Topology Updater workers in NFD, set the
topologyupdater
true
NodeFeatureDiscovery
3.6.1. NodeResourceTopology CR Copiar enlaceEnlace copiado en el portapapeles!
When run with NFD Topology Updater, NFD creates custom resource instances corresponding to the node resource hardware topology, such as:
apiVersion: topology.node.k8s.io/v1alpha1
kind: NodeResourceTopology
metadata:
name: node1
topologyPolicies: ["SingleNUMANodeContainerLevel"]
zones:
- name: node-0
type: Node
resources:
- name: cpu
capacity: 20
allocatable: 16
available: 10
- name: vendor/nic1
capacity: 3
allocatable: 3
available: 3
- name: node-1
type: Node
resources:
- name: cpu
capacity: 30
allocatable: 30
available: 15
- name: vendor/nic2
capacity: 6
allocatable: 6
available: 6
- name: node-2
type: Node
resources:
- name: cpu
capacity: 30
allocatable: 30
available: 15
- name: vendor/nic1
capacity: 3
allocatable: 3
available: 3
3.6.2. NFD Topology Updater command-line flags Copiar enlaceEnlace copiado en el portapapeles!
To view available command-line flags, run the
nfd-topology-updater -help
$ podman run gcr.io/k8s-staging-nfd/node-feature-discovery:master nfd-topology-updater -help
-ca-file
The
-ca-file
-cert-file
Default: empty
The
-ca-file
-cert-file
-key-file
Example
$ nfd-topology-updater -ca-file=/opt/nfd/ca.crt -cert-file=/opt/nfd/updater.crt -key-file=/opt/nfd/updater.key
-cert-file
The
-cert-file
-ca-file
-key-file flags
Default: empty
The
-cert-file
-ca-file
-key-file
Example
$ nfd-topology-updater -cert-file=/opt/nfd/updater.crt -key-file=/opt/nfd/updater.key -ca-file=/opt/nfd/ca.crt
-h, -help
Print usage and exit.
-key-file
The
-key-file
-ca-file
-cert-file
-cert-file
Default: empty
The
-key-file
-ca-file
-cert-file
Example
$ nfd-topology-updater -key-file=/opt/nfd/updater.key -cert-file=/opt/nfd/updater.crt -ca-file=/opt/nfd/ca.crt
-kubelet-config-file
The
-kubelet-config-file
Default:
/host-var/lib/kubelet/config.yaml
Example
$ nfd-topology-updater -kubelet-config-file=/var/lib/kubelet/config.yaml
-no-publish
The
-no-publish
Default:
false
Example
$ nfd-topology-updater -no-publish
3.6.2.1. -oneshot Copiar enlaceEnlace copiado en el portapapeles!
The
-oneshot
Default:
false
Example
$ nfd-topology-updater -oneshot -no-publish
-podresources-socket
The
-podresources-socket
Default:
/host-var/liblib/kubelet/pod-resources/kubelet.sock
Example
$ nfd-topology-updater -podresources-socket=/var/lib/kubelet/pod-resources/kubelet.sock
-server
The
-server
Default:
localhost:8080
Example
$ nfd-topology-updater -server=nfd-master.nfd.svc.cluster.local:443
-server-name-override
The
-server-name-override
Default: empty
Example
$ nfd-topology-updater -server-name-override=localhost
-sleep-interval
The
-sleep-interval
Default:
60s
Example
$ nfd-topology-updater -sleep-interval=1h
-version
Print version and exit.
-watch-namespace
The
-watch-namespace
*
Default:
*
Example
$ nfd-topology-updater -watch-namespace=rte
Chapter 4. Kernel Module Management Operator Copiar enlaceEnlace copiado en el portapapeles!
Learn about the Kernel Module Management (KMM) Operator and how you can use it to deploy out-of-tree kernel modules and device plugins on OpenShift Container Platform clusters.
4.1. About the Kernel Module Management Operator Copiar enlaceEnlace copiado en el portapapeles!
The Kernel Module Management (KMM) Operator manages, builds, signs, and deploys out-of-tree kernel modules and device plugins on OpenShift Container Platform clusters.
KMM adds a new
Module
Module
ModuleLoader
KMM is designed to accommodate multiple kernel versions at once for any kernel module, allowing for seamless node upgrades and reduced application downtime.
4.2. Installing the Kernel Module Management Operator Copiar enlaceEnlace copiado en el portapapeles!
As a cluster administrator, you can install the Kernel Module Management (KMM) Operator by using the OpenShift CLI or the web console.
The KMM Operator is supported on OpenShift Container Platform 4.12 and later. Installing KMM on version 4.11 does not require specific additional steps. For details on installing KMM on version 4.10 and earlier, see the section "Installing the Kernel Module Management Operator on earlier versions of OpenShift Container Platform".
4.2.1. Installing the Kernel Module Management Operator using the web console Copiar enlaceEnlace copiado en el portapapeles!
As a cluster administrator, you can install the Kernel Module Management (KMM) Operator using the OpenShift Container Platform web console.
Procedure
- Log in to the OpenShift Container Platform web console.
Install the Kernel Module Management Operator:
- In the OpenShift Container Platform web console, click Operators → OperatorHub.
- Select Kernel Module Management Operator from the list of available Operators, and then click Install.
- On the Install Operator page, select the Installation mode as A specific namespace on the cluster.
-
From the Installed Namespace list, select the namespace.
openshift-kmm - Click Install.
Verification
To verify that KMM Operator installed successfully:
- Navigate to the Operators → Installed Operators page.
Ensure that Kernel Module Management Operator is listed in the openshift-kmm project with a Status of InstallSucceeded.
NoteDuring installation, an Operator might display a Failed status. If the installation later succeeds with an InstallSucceeded message, you can ignore the Failed message.
Troubleshooting
To troubleshoot issues with Operator installation:
- Navigate to the Operators → Installed Operators page and inspect the Operator Subscriptions and Install Plans tabs for any failure or errors under Status.
-
Navigate to the Workloads → Pods page and check the logs for pods in the project.
openshift-kmm
4.2.2. Installing the Kernel Module Management Operator by using the CLI Copiar enlaceEnlace copiado en el portapapeles!
As a cluster administrator, you can install the Kernel Module Management (KMM) Operator by using the OpenShift CLI.
Prerequisites
- You have a running OpenShift Container Platform cluster.
-
You installed the OpenShift CLI ().
oc -
You are logged into the OpenShift CLI as a user with privileges.
cluster-admin
Procedure
Install KMM in the
namespace:openshift-kmmCreate the following
CR and save the YAML file, for example,Namespace:kmm-namespace.yamlapiVersion: v1 kind: Namespace metadata: name: openshift-kmmCreate the following
CR and save the YAML file, for example,OperatorGroup:kmm-op-group.yamlapiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: kernel-module-management namespace: openshift-kmmCreate the following
CR and save the YAML file, for example,Subscription:kmm-sub.yamlapiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: kernel-module-management namespace: openshift-kmm spec: channel: release-1.0 installPlanApproval: Automatic name: kernel-module-management source: redhat-operators sourceNamespace: openshift-marketplace startingCSV: kernel-module-management.v1.0.0Create the subscription object by running the following command:
$ oc create -f kmm-sub.yaml
Verification
To verify that the Operator deployment is successful, run the following command:
$ oc get -n openshift-kmm deployments.apps kmm-operator-controller-managerExample output
NAME READY UP-TO-DATE AVAILABLE AGE kmm-operator-controller-manager 1/1 1 1 97sThe Operator is available.
4.2.3. Installing the Kernel Module Management Operator on earlier versions of OpenShift Container Platform Copiar enlaceEnlace copiado en el portapapeles!
The KMM Operator is supported on OpenShift Container Platform 4.12 and later. For version 4.10 and earlier, you must create a new
SecurityContextConstraint
ServiceAccount
Prerequisites
- You have a running OpenShift Container Platform cluster.
-
You installed the OpenShift CLI ().
oc -
You are logged into the OpenShift CLI as a user with privileges.
cluster-admin
Procedure
Install KMM in the
namespace:openshift-kmmCreate the following
CR and save the YAML file, for example,Namespacefile:kmm-namespace.yamlapiVersion: v1 kind: Namespace metadata: name: openshift-kmmCreate the following
object and save the YAML file, for example,SecurityContextConstraint:kmm-security-constraint.yamlallowHostDirVolumePlugin: false allowHostIPC: false allowHostNetwork: false allowHostPID: false allowHostPorts: false allowPrivilegeEscalation: false allowPrivilegedContainer: false allowedCapabilities: - NET_BIND_SERVICE apiVersion: security.openshift.io/v1 defaultAddCapabilities: null fsGroup: type: MustRunAs groups: [] kind: SecurityContextConstraints metadata: name: restricted-v2 priority: null readOnlyRootFilesystem: false requiredDropCapabilities: - ALL runAsUser: type: MustRunAsRange seLinuxContext: type: MustRunAs seccompProfiles: - runtime/default supplementalGroups: type: RunAsAny users: [] volumes: - configMap - downwardAPI - emptyDir - persistentVolumeClaim - projected - secretBind the
object to the Operator’sSecurityContextConstraintby running the following commands:ServiceAccount$ oc apply -f kmm-security-constraint.yaml$ oc adm policy add-scc-to-user kmm-security-constraint -z kmm-operator-controller-manager -n openshift-kmmCreate the following
CR and save the YAML file, for example,OperatorGroup:kmm-op-group.yamlapiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: kernel-module-management namespace: openshift-kmmCreate the following
CR and save the YAML file, for example,Subscription:kmm-sub.yamlapiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: kernel-module-management namespace: openshift-kmm spec: channel: release-1.0 installPlanApproval: Automatic name: kernel-module-management source: redhat-operators sourceNamespace: openshift-marketplace startingCSV: kernel-module-management.v1.0.0Create the subscription object by running the following command:
$ oc create -f kmm-sub.yaml
Verification
To verify that the Operator deployment is successful, run the following command:
$ oc get -n openshift-kmm deployments.apps kmm-operator-controller-managerExample output
NAME READY UP-TO-DATE AVAILABLE AGE kmm-operator-controller-manager 1/1 1 1 97sThe Operator is available.
4.3. Kernel module deployment Copiar enlaceEnlace copiado en el portapapeles!
For each
Module
DaemonSet
-
One ModuleLoader per compatible kernel version running in the cluster.
DaemonSet -
One device plugin , if configured.
DaemonSet
The module loader daemon set resources run ModuleLoader images to load kernel modules. A module loader image is an OCI image that contains the
.ko
modprobe
sleep
When the module loader pod is created, the pod runs
modprobe
ExecPreStop
modprobe -r
If the
.spec.devicePlugin
Module
-
Nodes that match the of the
.spec.selectorresource.Module -
Nodes with the kernel module loaded (where the module loader pod is in the condition).
Ready
4.3.1. The Module custom resource definition Copiar enlaceEnlace copiado en el portapapeles!
The
Module
Module
The compatible versions for a
Module
.spec.moduleLoader.container.kernelMappings
literal
regexp
The reconciliation loop for the
Module
-
List all nodes matching .
.spec.selector - Build a set of all kernel versions running on those nodes.
For each kernel version:
-
Go through and find the appropriate container image name. If the kernel mapping has
.spec.moduleLoader.container.kernelMappingsorbuilddefined and the container image does not already exist, run the build, the signing job, or both, as needed.sign - Create a module loader daemon set with the container image determined in the previous step.
-
If is defined, create a device plugin daemon set using the configuration specified under
.spec.devicePlugin..spec.devicePlugin.container
-
Go through
Run
on:garbage-collect- Existing daemon set resources targeting kernel versions that are not run by any node in the cluster.
- Successful build jobs.
- Successful signing jobs.
4.3.2. Security and permissions Copiar enlaceEnlace copiado en el portapapeles!
Loading kernel modules is a highly sensitive operation. After they are loaded, kernel modules have all possible permissions to do any kind of operation on the node.
4.3.2.1. ServiceAccounts and SecurityContextConstraints Copiar enlaceEnlace copiado en el portapapeles!
Kernel Module Management (KMM) creates a privileged workload to load the kernel modules on nodes. That workload needs
ServiceAccounts
privileged
SecurityContextConstraint
The authorization model for that workload depends on the namespace of the
Module
-
If the or
.spec.moduleLoader.serviceAccountNamefields are set, they are always used..spec.devicePlugin.serviceAccountName If those fields are not set, then:
-
If the resource is created in the operator’s namespace (
Moduleby default), then KMM uses its default, powerfulopenshift-kmmto run the daemon sets.ServiceAccounts -
If the resource is created in any other namespace, then KMM runs the daemon sets as the namespace’s
Moduledefault. TheServiceAccountresource cannot run a privileged workload unless you manually enable it to use theModuleSCC.privileged
-
If the
openshift-kmm
When setting up RBAC permissions, remember that any user or
ServiceAccount
Module
openshift-kmm
To allow any
ServiceAccount
privileged
$ oc adm policy add-scc-to-user privileged -z "${serviceAccountName}" [ -n "${namespace}" ]
4.3.2.2. Pod security standards Copiar enlaceEnlace copiado en el portapapeles!
OpenShift runs a synchronization mechanism that sets the namespace Pod Security level automatically based on the security contexts in use. No action is needed.
4.3.3. Example Module CR Copiar enlaceEnlace copiado en el portapapeles!
The following is an annotated
Module
apiVersion: kmm.sigs.x-k8s.io/v1beta1
kind: Module
metadata:
name: <my_kmod>
spec:
moduleLoader:
container:
modprobe:
moduleName: <my_kmod>
dirName: /opt
firmwarePath: /firmware
parameters:
- param=1
kernelMappings:
- literal: 6.0.15-300.fc37.x86_64
containerImage: some.registry/org/my-kmod:6.0.15-300.fc37.x86_64
- regexp: '^.+\fc37\.x86_64$'
containerImage: "some.other.registry/org/<my_kmod>:${KERNEL_FULL_VERSION}"
- regexp: '^.+$'
containerImage: "some.registry/org/<my_kmod>:${KERNEL_FULL_VERSION}"
build:
buildArgs:
- name: ARG_NAME
value: <some_value>
secrets:
- name: <some_kubernetes_secret>
baseImageRegistryTLS:
insecure: false
insecureSkipTLSVerify: false
dockerfileConfigMap:
name: <my_kmod_dockerfile>
sign:
certSecret:
name: <cert_secret>
keySecret:
name: <key_secret>
filesToSign:
- /opt/lib/modules/${KERNEL_FULL_VERSION}/<my_kmod>.ko
registryTLS:
insecure: false
insecureSkipTLSVerify: false
serviceAccountName: <sa_module_loader>
devicePlugin:
container:
image: some.registry/org/device-plugin:latest
env:
- name: MY_DEVICE_PLUGIN_ENV_VAR
value: SOME_VALUE
volumeMounts:
- mountPath: /some/mountPath
name: <device_plugin_volume>
volumes:
- name: <device_plugin_volume>
configMap:
name: <some_configmap>
serviceAccountName: <sa_device_plugin>
imageRepoSecret:
name: <secret_name>
selector:
node-role.kubernetes.io/worker: ""
- 1 1 1
- Required.
- 2
- Optional.
- 3
- Optional: Copies
/firmware/*into/var/lib/firmware/on the node. - 4
- Optional.
- 5
- At least one kernel item is required.
- 6
- For each node running a kernel matching the regular expression, KMM creates a
DaemonSetresource running the image specified incontainerImagewith${KERNEL_FULL_VERSION}replaced with the kernel version. - 7
- For any other kernel, build the image using the Dockerfile in the
my-kmodConfigMap. - 8
- Optional.
- 9
- Optional: A value for
some-kubernetes-secretcan be obtained from the build environment at/run/secrets/some-kubernetes-secret. - 10
- Optional: Avoid using this parameter. If set to
true, the build is allowed to pull the image in the DockerfileFROMinstruction using plain HTTP. - 11
- Optional: Avoid using this parameter. If set to
true, the build will skip any TLS server certificate validation when pulling the image in the DockerfileFROMinstruction using plain HTTP. - 12
- Required.
- 13
- Required: A secret holding the public secureboot key with the key 'cert'.
- 14
- Required: A secret holding the private secureboot key with the key 'key'.
- 15
- Optional: Avoid using this parameter. If set to
true, KMM will be allowed to check if the container image already exists using plain HTTP. - 16
- Optional: Avoid using this parameter. If set to
true, KMM will skip any TLS server certificate validation when checking if the container image already exists. - 17
- Optional.
- 18
- Optional.
- 19
- Required: If the device plugin section is present.
- 20
- Optional.
- 21
- Optional.
- 22
- Optional.
- 23
- Optional: Used to pull module loader and device plugin images.
4.4. Using a ModuleLoader image Copiar enlaceEnlace copiado en el portapapeles!
Kernel Module Management (KMM) works with purpose-built module loader images. These are standard OCI images that must satisfy the following requirements:
-
files must be located in
.ko./opt/lib/modules/${KERNEL_VERSION} -
and
modprobebinaries must be defined in thesleepvariable.$PATH
4.4.1. Running depmod Copiar enlaceEnlace copiado en el portapapeles!
If your module loader image contains several kernel modules and if one of the modules depends on another module, it is best practice to run
depmod
You must have a Red Hat subscription to download the
kernel-devel
Procedure
-
To generate and
modules.depfiles for a specific kernel version, run.map.depmod -b /opt ${KERNEL_VERSION}
4.4.1.1. Example Dockerfile Copiar enlaceEnlace copiado en el portapapeles!
If you are building your image on OpenShift Container Platform, consider using the Driver Tool Kit (DTK).
For further information, see using an entitled build.
apiVersion: v1
kind: ConfigMap
metadata:
name: kmm-ci-dockerfile
data:
dockerfile: |
ARG DTK_AUTO
FROM ${DTK_AUTO} as builder
ARG KERNEL_VERSION
WORKDIR /usr/src
RUN ["git", "clone", "https://github.com/rh-ecosystem-edge/kernel-module-management.git"]
WORKDIR /usr/src/kernel-module-management/ci/kmm-kmod
RUN KERNEL_SRC_DIR=/lib/modules/${KERNEL_VERSION}/build make all
FROM registry.redhat.io/ubi8/ubi-minimal
ARG KERNEL_VERSION
RUN microdnf install kmod
COPY --from=builder /usr/src/kernel-module-management/ci/kmm-kmod/kmm_ci_a.ko /opt/lib/modules/${KERNEL_VERSION}/
COPY --from=builder /usr/src/kernel-module-management/ci/kmm-kmod/kmm_ci_b.ko /opt/lib/modules/${KERNEL_VERSION}/
RUN depmod -b /opt ${KERNEL_VERSION}
4.4.2. Building in the cluster Copiar enlaceEnlace copiado en el portapapeles!
KMM can build module loader images in the cluster. Follow these guidelines:
-
Provide build instructions using the section of a kernel mapping.
build -
Copy the Dockerfile for your container image into a resource, under the
ConfigMapkey.dockerfile -
Ensure that the is located in the same namespace as the
ConfigMap.Module
KMM checks if the image name specified in the
containerImage
Otherwise, KMM creates a
Build
Module
# ...
- regexp: '^.+$'
containerImage: "some.registry/org/<my_kmod>:${KERNEL_FULL_VERSION}"
build:
buildArgs:
- name: ARG_NAME
value: <some_value>
secrets:
- name: <some_kubernetes_secret>
baseImageRegistryTLS:
insecure: false
insecureSkipTLSVerify: false
dockerfileConfigMap:
name: <my_kmod_dockerfile>
registryTLS:
insecure: false
insecureSkipTLSVerify: false
- 1
- Optional.
- 2
- Optional.
- 3
- Will be mounted in the build pod as
/run/secrets/some-kubernetes-secret. - 4
- Optional: Avoid using this parameter. If set to
true, the build will be allowed to pull the image in the DockerfileFROMinstruction using plain HTTP. - 5
- Optional: Avoid using this parameter. If set to
true, the build will skip any TLS server certificate validation when pulling the image in the DockerfileFROMinstruction using plain HTTP. - 6
- Required.
- 7
- Optional: Avoid using this parameter. If set to
true, KMM will be allowed to check if the container image already exists using plain HTTP. - 8
- Optional: Avoid using this parameter. If set to
true, KMM will skip any TLS server certificate validation when checking if the container image already exists.
4.4.3. Using the Driver Toolkit Copiar enlaceEnlace copiado en el portapapeles!
The Driver Toolkit (DTK) is a convenient base image for building build module loader images. It contains tools and libraries for the OpenShift version currently running in the cluster.
Procedure
Use DTK as the first stage of a multi-stage Dockerfile.
- Build the kernel modules.
-
Copy the files into a smaller end-user image such as
.koubi-minimal. To leverage DTK in your in-cluster build, use the
build argument. The value is automatically set by KMM when creating theDTK_AUTOresource. See the following example.BuildARG DTK_AUTO FROM ${DTK_AUTO} as builder ARG KERNEL_VERSION WORKDIR /usr/src RUN ["git", "clone", "https://github.com/rh-ecosystem-edge/kernel-module-management.git"] WORKDIR /usr/src/kernel-module-management/ci/kmm-kmod RUN KERNEL_SRC_DIR=/lib/modules/${KERNEL_VERSION}/build make all FROM registry.redhat.io/ubi8/ubi-minimal ARG KERNEL_VERSION RUN microdnf install kmod COPY --from=builder /usr/src/kernel-module-management/ci/kmm-kmod/kmm_ci_a.ko /opt/lib/modules/${KERNEL_VERSION}/ COPY --from=builder /usr/src/kernel-module-management/ci/kmm-kmod/kmm_ci_b.ko /opt/lib/modules/${KERNEL_VERSION}/ RUN depmod -b /opt ${KERNEL_VERSION}
4.5. Using signing with Kernel Module Management (KMM) Copiar enlaceEnlace copiado en el portapapeles!
On a Secure Boot enabled system, all kernel modules (kmods) must be signed with a public/private key-pair enrolled into the Machine Owner’s Key (MOK) database. Drivers distributed as part of a distribution should already be signed by the distribution’s private key, but for kernel modules build out-of-tree, KMM supports signing kernel modules using the
sign
For more details on using Secure Boot, see Generating a public and private key pair
Prerequisites
- A public private key pair in the correct (DER) format.
- At least one secure-boot enabled node with the public key enrolled in its MOK database.
- Either a pre-built driver container image, or the source code and Dockerfile needed to build one in-cluster.
4.6. Adding the keys for secureboot Copiar enlaceEnlace copiado en el portapapeles!
To use KMM Kernel Module Management (KMM) to sign kernel modules, a certificate and private key are required. For details on how to create these, see Generating a public and private key pair.
For details on how to extract the public and private key pair, see Signing kernel modules with the private key. Use steps 1 through 4 to extract the keys into files.
Procedure
Create the
file that contains the certificate and thesb_cert.cerfile that contains the private key:sb_cert.priv$ openssl req -x509 -new -nodes -utf8 -sha256 -days 36500 -batch -config configuration_file.config -outform DER -out my_signing_key_pub.der -keyout my_signing_key.privAdd the files by using one of the following methods:
Add the files as secrets directly:
$ oc create secret generic my-signing-key --from-file=key=<my_signing_key.priv>$ oc create secret generic my-signing-key-pub --from-file=cert=<my_signing_key_pub.der>Add the files by base64 encoding them:
$ cat sb_cert.priv | base64 -w 0 > my_signing_key2.base64$ cat sb_cert.cer | base64 -w 0 > my_signing_key_pub.base64
Add the encoded text to a YAML file:
apiVersion: v1 kind: Secret metadata: name: my-signing-key-pub namespace: default1 type: Opaque data: cert: <base64_encoded_secureboot_public_key> --- apiVersion: v1 kind: Secret metadata: name: my-signing-key namespace: default2 type: Opaque data: key: <base64_encoded_secureboot_private_key>Apply the YAML file:
$ oc apply -f <yaml_filename>
4.6.1. Checking the keys Copiar enlaceEnlace copiado en el portapapeles!
After you have added the keys, you must check them to ensure they are set correctly.
Procedure
Check to ensure the public key secret is set correctly:
$ oc get secret -o yaml <certificate secret name> | awk '/cert/{print $2; exit}' | base64 -d | openssl x509 -inform der -textThis should display a certificate with a Serial Number, Issuer, Subject, and more.
Check to ensure the private key secret is set correctly:
$ oc get secret -o yaml <private key secret name> | awk '/key/{print $2; exit}' | base64 -dThis should display the key enclosed in the
and-----BEGIN PRIVATE KEY-----lines.-----END PRIVATE KEY-----
4.7. Signing a pre-built driver container Copiar enlaceEnlace copiado en el portapapeles!
Use this procedure if you have a pre-built image, such as an image either distributed by a hardware vendor or built elsewhere.
The following YAML file adds the public/private key-pair as secrets with the required key names -
key
cert
unsignedImage
filesToSign
containerImage
Kernel Module Management (KMM) should then deploy the DaemonSet that loads the signed kmods onto all the nodes that match the selector. The driver containers should run successfully on any nodes that have the public key in their MOK database, and any nodes that are not secure-boot enabled, which ignore the signature. They should fail to load on any that have secure-boot enabled but do not have that key in their MOK database.
Prerequisites
-
The and
keySecretsecrets have been created.certSecret
Procedure
Apply the YAML file:
--- apiVersion: kmm.sigs.x-k8s.io/v1beta1 kind: Module metadata: name: example-module spec: moduleLoader: serviceAccountName: default container: modprobe:1 moduleName: '<your module name>' kernelMappings: # the kmods will be deployed on all nodes in the cluster with a kernel that matches the regexp - regexp: '^.*\.x86_64$' # the container to produce containing the signed kmods containerImage: <image name e.g. quay.io/myuser/my-driver:<kernelversion>-signed> sign: # the image containing the unsigned kmods (we need this because we are not building the kmods within the cluster) unsignedImage: <image name e.g. quay.io/myuser/my-driver:<kernelversion> > keySecret: # a secret holding the private secureboot key with the key 'key' name: <private key secret name> certSecret: # a secret holding the public secureboot key with the key 'cert' name: <certificate secret name> filesToSign: # full path within the unsignedImage container to the kmod(s) to sign - /opt/lib/modules/4.18.0-348.2.1.el8_5.x86_64/kmm_ci_a.ko imageRepoSecret: # the name of a secret containing credentials to pull unsignedImage and push containerImage to the registry name: repo-pull-secret selector: kubernetes.io/arch: amd64
- 1
modprobe- The name of the kmod to load.
4.8. Building and signing a ModuleLoader container image Copiar enlaceEnlace copiado en el portapapeles!
Use this procedure if you have source code and must build your image first.
The following YAML file builds a new container image using the source code from the repository. The image produced is saved back in the registry with a temporary name, and this temporary image is then signed using the parameters in the
sign
The temporary image name is based on the final image name and is set to be
<containerImage>:<tag>-<namespace>_<module name>_kmm_unsigned
For example, using the following YAML file, Kernel Module Management (KMM) builds an image named
example.org/repository/minimal-driver:final-default_example-module_kmm_unsigned
example.org/repository/minimal-driver:final
DaemonSet
After it is signed, the temporary image can be safely deleted from the registry. It will be rebuilt, if needed.
Prerequisites
-
The and
keySecretsecrets have been created.certSecret
Procedure
Apply the YAML file:
--- apiVersion: v1 kind: ConfigMap metadata: name: example-module-dockerfile namespace: default1 data: dockerfile: | ARG DTK_AUTO ARG KERNEL_VERSION FROM ${DTK_AUTO} as builder WORKDIR /build/ RUN git clone -b main --single-branch https://github.com/rh-ecosystem-edge/kernel-module-management.git WORKDIR kernel-module-management/ci/kmm-kmod/ RUN make FROM registry.access.redhat.com/ubi8/ubi:latest ARG KERNEL_VERSION RUN yum -y install kmod && yum clean all RUN mkdir -p /opt/lib/modules/${KERNEL_VERSION} COPY --from=builder /build/kernel-module-management/ci/kmm-kmod/*.ko /opt/lib/modules/${KERNEL_VERSION}/ RUN /usr/sbin/depmod -b /opt --- apiVersion: kmm.sigs.x-k8s.io/v1beta1 kind: Module metadata: name: example-module namespace: default2 spec: moduleLoader: serviceAccountName: default3 container: modprobe: moduleName: simple_kmod kernelMappings: - regexp: '^.*\.x86_64$' containerImage: < the name of the final driver container to produce> build: dockerfileConfigMap: name: example-module-dockerfile sign: keySecret: name: <private key secret name> certSecret: name: <certificate secret name> filesToSign: - /opt/lib/modules/4.18.0-348.2.1.el8_5.x86_64/kmm_ci_a.ko imageRepoSecret:4 name: repo-pull-secret selector: # top-level selector kubernetes.io/arch: amd64
- 1 2
namespace- Replacedefaultwith a valid namespace.- 3
serviceAccountName- The defaultserviceAccountNamedoes not have the required permissions to run a module that is privileged. For information on creating a service account, see "Creating service accounts" in the "Additional resources" of this section.- 4
imageRepoSecret- Used asimagePullSecretsin theDaemonSetobject and to pull and push for the build and sign features.
Additional resources
For information on creating a service account, see Creating service accounts.
4.9. Debugging and troubleshooting Copiar enlaceEnlace copiado en el portapapeles!
If the kmods in your driver container are not signed or are signed with the wrong key, then the container can enter a
PostStartHookError
CrashLoopBackOff
oc describe
modprobe: ERROR: could not insert '<your_kmod_name>': Required key not available
4.10. KMM firmware support Copiar enlaceEnlace copiado en el portapapeles!
Kernel modules sometimes need to load firmware files from the file system. KMM supports copying firmware files from the ModuleLoader image to the node’s file system.
The contents of
.spec.moduleLoader.container.modprobe.firmwarePath
/var/lib/firmware
modprobe
All files and empty directories are removed from that location before running the
modprobe -r
4.10.1. Configuring the lookup path on nodes Copiar enlaceEnlace copiado en el portapapeles!
On OpenShift Container Platform nodes, the set of default lookup paths for firmwares does not include the
/var/lib/firmware
Procedure
Use the Machine Config Operator to create a
custom resource (CR) that contains theMachineConfigpath:/var/lib/firmwareapiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: labels: machineconfiguration.openshift.io/role: worker1 name: 99-worker-kernel-args-firmware-path spec: kernelArguments: - 'firmware_class.path=/var/lib/firmware'- 1
- You can configure the label based on your needs. In the case of single-node OpenShift, use either
control-paneormasterobjects.
-
By applying the CR, the nodes are automatically rebooted.
MachineConfig
4.10.2. Building a ModuleLoader image Copiar enlaceEnlace copiado en el portapapeles!
Procedure
In addition to building the kernel module itself, include the binary firmware in the builder image:
FROM registry.redhat.io/ubi8/ubi-minimal as builder # Build the kmod RUN ["mkdir", "/firmware"] RUN ["curl", "-o", "/firmware/firmware.bin", "https://artifacts.example.com/firmware.bin"] FROM registry.redhat.io/ubi8/ubi-minimal # Copy the kmod, install modprobe, run depmod COPY --from=builder /firmware /firmware
4.10.3. Tuning the Module resource Copiar enlaceEnlace copiado en el portapapeles!
Procedure
Set
in the.spec.moduleLoader.container.modprobe.firmwarePathcustom resource (CR):ModuleapiVersion: kmm.sigs.x-k8s.io/v1beta1 kind: Module metadata: name: my-kmod spec: moduleLoader: container: modprobe: moduleName: my-kmod # Required firmwarePath: /firmware1 - 1
- Optional: Copies
/firmware/*into/var/lib/firmware/on the node.
4.11. Troubleshooting KMM Copiar enlaceEnlace copiado en el portapapeles!
When troubleshooting KMM installation issues, you can monitor logs to determine at which stage issues occur. Then, retrieve diagnostic data relevant to that stage.
4.11.1. Using the must-gather tool Copiar enlaceEnlace copiado en el portapapeles!
The
oc adm must-gather
4.11.1.1. Gathering data for KMM Copiar enlaceEnlace copiado en el portapapeles!
Procedure
Gather the data for the KMM Operator controller manager:
Set the
variable:MUST_GATHER_IMAGE$ export MUST_GATHER_IMAGE=$(oc get deployment -n openshift-kmm kmm-operator-controller-manager -ojsonpath='{.spec.template.spec.containers[?(@.name=="manager")].env[?(@.name=="RELATED_IMAGES_MUST_GATHER")].value}')NoteUse the
switch to specify a namespace if you installed KMM in a custom namespace.-n <namespace>Run the
tool:must-gather$ oc adm must-gather --image="${MUST_GATHER_IMAGE}" -- /usr/bin/gather
View the Operator logs:
$ oc logs -fn openshift-kmm deployments/kmm-operator-controller-managerExample 4.1. Example output
I0228 09:36:37.352405 1 request.go:682] Waited for 1.001998746s due to client-side throttling, not priority and fairness, request: GET:https://172.30.0.1:443/apis/machine.openshift.io/v1beta1?timeout=32s I0228 09:36:40.767060 1 listener.go:44] kmm/controller-runtime/metrics "msg"="Metrics server is starting to listen" "addr"="127.0.0.1:8080" I0228 09:36:40.769483 1 main.go:234] kmm/setup "msg"="starting manager" I0228 09:36:40.769907 1 internal.go:366] kmm "msg"="Starting server" "addr"={"IP":"127.0.0.1","Port":8080,"Zone":""} "kind"="metrics" "path"="/metrics" I0228 09:36:40.770025 1 internal.go:366] kmm "msg"="Starting server" "addr"={"IP":"::","Port":8081,"Zone":""} "kind"="health probe" I0228 09:36:40.770128 1 leaderelection.go:248] attempting to acquire leader lease openshift-kmm/kmm.sigs.x-k8s.io... I0228 09:36:40.784396 1 leaderelection.go:258] successfully acquired lease openshift-kmm/kmm.sigs.x-k8s.io I0228 09:36:40.784876 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="Module" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="Module" "source"="kind source: *v1beta1.Module" I0228 09:36:40.784925 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="Module" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="Module" "source"="kind source: *v1.DaemonSet" I0228 09:36:40.784968 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="Module" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="Module" "source"="kind source: *v1.Build" I0228 09:36:40.785001 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="Module" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="Module" "source"="kind source: *v1.Job" I0228 09:36:40.785025 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="Module" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="Module" "source"="kind source: *v1.Node" I0228 09:36:40.785039 1 controller.go:193] kmm "msg"="Starting Controller" "controller"="Module" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="Module" I0228 09:36:40.785458 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="PodNodeModule" "controllerGroup"="" "controllerKind"="Pod" "source"="kind source: *v1.Pod" I0228 09:36:40.786947 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="PreflightValidation" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="PreflightValidation" "source"="kind source: *v1beta1.PreflightValidation" I0228 09:36:40.787406 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="PreflightValidation" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="PreflightValidation" "source"="kind source: *v1.Build" I0228 09:36:40.787474 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="PreflightValidation" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="PreflightValidation" "source"="kind source: *v1.Job" I0228 09:36:40.787488 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="PreflightValidation" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="PreflightValidation" "source"="kind source: *v1beta1.Module" I0228 09:36:40.787603 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="NodeKernel" "controllerGroup"="" "controllerKind"="Node" "source"="kind source: *v1.Node" I0228 09:36:40.787634 1 controller.go:193] kmm "msg"="Starting Controller" "controller"="NodeKernel" "controllerGroup"="" "controllerKind"="Node" I0228 09:36:40.787680 1 controller.go:193] kmm "msg"="Starting Controller" "controller"="PreflightValidation" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="PreflightValidation" I0228 09:36:40.785607 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="imagestream" "controllerGroup"="image.openshift.io" "controllerKind"="ImageStream" "source"="kind source: *v1.ImageStream" I0228 09:36:40.787822 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="preflightvalidationocp" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="PreflightValidationOCP" "source"="kind source: *v1beta1.PreflightValidationOCP" I0228 09:36:40.787853 1 controller.go:193] kmm "msg"="Starting Controller" "controller"="imagestream" "controllerGroup"="image.openshift.io" "controllerKind"="ImageStream" I0228 09:36:40.787879 1 controller.go:185] kmm "msg"="Starting EventSource" "controller"="preflightvalidationocp" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="PreflightValidationOCP" "source"="kind source: *v1beta1.PreflightValidation" I0228 09:36:40.787905 1 controller.go:193] kmm "msg"="Starting Controller" "controller"="preflightvalidationocp" "controllerGroup"="kmm.sigs.x-k8s.io" "controllerKind"="PreflightValidationOCP" I0228 09:36:40.786489 1 controller.go:193] kmm "msg"="Starting Controller" "controller"="PodNodeModule" "controllerGroup"="" "controllerKind"="Pod"
4.11.1.2. Gathering data for KMM-Hub Copiar enlaceEnlace copiado en el portapapeles!
Procedure
Gather the data for the KMM Operator hub controller manager:
Set the
variable:MUST_GATHER_IMAGE$ export MUST_GATHER_IMAGE=$(oc get deployment -n openshift-kmm-hub kmm-operator-hub-controller-manager -ojsonpath='{.spec.template.spec.containers[?(@.name=="manager")].env[?(@.name=="RELATED_IMAGES_MUST_GATHER")].value}')NoteUse the
switch to specify a namespace if you installed KMM in a custom namespace.-n <namespace>Run the
tool:must-gather$ oc adm must-gather --image="${MUST_GATHER_IMAGE}" -- /usr/bin/gather -u
View the Operator logs:
$ oc logs -fn openshift-kmm-hub deployments/kmm-operator-hub-controller-managerExample 4.2. Example output
I0417 11:34:08.807472 1 request.go:682] Waited for 1.023403273s due to client-side throttling, not priority and fairness, request: GET:https://172.30.0.1:443/apis/tuned.openshift.io/v1?timeout=32s I0417 11:34:12.373413 1 listener.go:44] kmm-hub/controller-runtime/metrics "msg"="Metrics server is starting to listen" "addr"="127.0.0.1:8080" I0417 11:34:12.376253 1 main.go:150] kmm-hub/setup "msg"="Adding controller" "name"="ManagedClusterModule" I0417 11:34:12.376621 1 main.go:186] kmm-hub/setup "msg"="starting manager" I0417 11:34:12.377690 1 leaderelection.go:248] attempting to acquire leader lease openshift-kmm-hub/kmm-hub.sigs.x-k8s.io... I0417 11:34:12.378078 1 internal.go:366] kmm-hub "msg"="Starting server" "addr"={"IP":"127.0.0.1","Port":8080,"Zone":""} "kind"="metrics" "path"="/metrics" I0417 11:34:12.378222 1 internal.go:366] kmm-hub "msg"="Starting server" "addr"={"IP":"::","Port":8081,"Zone":""} "kind"="health probe" I0417 11:34:12.395703 1 leaderelection.go:258] successfully acquired lease openshift-kmm-hub/kmm-hub.sigs.x-k8s.io I0417 11:34:12.396334 1 controller.go:185] kmm-hub "msg"="Starting EventSource" "controller"="ManagedClusterModule" "controllerGroup"="hub.kmm.sigs.x-k8s.io" "controllerKind"="ManagedClusterModule" "source"="kind source: *v1beta1.ManagedClusterModule" I0417 11:34:12.396403 1 controller.go:185] kmm-hub "msg"="Starting EventSource" "controller"="ManagedClusterModule" "controllerGroup"="hub.kmm.sigs.x-k8s.io" "controllerKind"="ManagedClusterModule" "source"="kind source: *v1.ManifestWork" I0417 11:34:12.396430 1 controller.go:185] kmm-hub "msg"="Starting EventSource" "controller"="ManagedClusterModule" "controllerGroup"="hub.kmm.sigs.x-k8s.io" "controllerKind"="ManagedClusterModule" "source"="kind source: *v1.Build" I0417 11:34:12.396469 1 controller.go:185] kmm-hub "msg"="Starting EventSource" "controller"="ManagedClusterModule" "controllerGroup"="hub.kmm.sigs.x-k8s.io" "controllerKind"="ManagedClusterModule" "source"="kind source: *v1.Job" I0417 11:34:12.396522 1 controller.go:185] kmm-hub "msg"="Starting EventSource" "controller"="ManagedClusterModule" "controllerGroup"="hub.kmm.sigs.x-k8s.io" "controllerKind"="ManagedClusterModule" "source"="kind source: *v1.ManagedCluster" I0417 11:34:12.396543 1 controller.go:193] kmm-hub "msg"="Starting Controller" "controller"="ManagedClusterModule" "controllerGroup"="hub.kmm.sigs.x-k8s.io" "controllerKind"="ManagedClusterModule" I0417 11:34:12.397175 1 controller.go:185] kmm-hub "msg"="Starting EventSource" "controller"="imagestream" "controllerGroup"="image.openshift.io" "controllerKind"="ImageStream" "source"="kind source: *v1.ImageStream" I0417 11:34:12.397221 1 controller.go:193] kmm-hub "msg"="Starting Controller" "controller"="imagestream" "controllerGroup"="image.openshift.io" "controllerKind"="ImageStream" I0417 11:34:12.498335 1 filter.go:196] kmm-hub "msg"="Listing all ManagedClusterModules" "managedcluster"="local-cluster" I0417 11:34:12.498570 1 filter.go:205] kmm-hub "msg"="Listed ManagedClusterModules" "count"=0 "managedcluster"="local-cluster" I0417 11:34:12.498629 1 filter.go:238] kmm-hub "msg"="Adding reconciliation requests" "count"=0 "managedcluster"="local-cluster" I0417 11:34:12.498687 1 filter.go:196] kmm-hub "msg"="Listing all ManagedClusterModules" "managedcluster"="sno1-0" I0417 11:34:12.498750 1 filter.go:205] kmm-hub "msg"="Listed ManagedClusterModules" "count"=0 "managedcluster"="sno1-0" I0417 11:34:12.498801 1 filter.go:238] kmm-hub "msg"="Adding reconciliation requests" "count"=0 "managedcluster"="sno1-0" I0417 11:34:12.501947 1 controller.go:227] kmm-hub "msg"="Starting workers" "controller"="imagestream" "controllerGroup"="image.openshift.io" "controllerKind"="ImageStream" "worker count"=1 I0417 11:34:12.501948 1 controller.go:227] kmm-hub "msg"="Starting workers" "controller"="ManagedClusterModule" "controllerGroup"="hub.kmm.sigs.x-k8s.io" "controllerKind"="ManagedClusterModule" "worker count"=1 I0417 11:34:12.502285 1 imagestream_reconciler.go:50] kmm-hub "msg"="registered imagestream info mapping" "ImageStream"={"name":"driver-toolkit","namespace":"openshift"} "controller"="imagestream" "controllerGroup"="image.openshift.io" "controllerKind"="ImageStream" "dtkImage"="quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:df42b4785a7a662b30da53bdb0d206120cf4d24b45674227b16051ba4b7c3934" "name"="driver-toolkit" "namespace"="openshift" "osImageVersion"="412.86.202302211547-0" "reconcileID"="e709ff0a-5664-4007-8270-49b5dff8bae9"
4.12. KMM hub and spoke Copiar enlaceEnlace copiado en el portapapeles!
In hub and spoke scenarios, many spoke clusters are connected to a central, powerful hub cluster. Kernel Module Management (KMM) depends on Red Hat Advanced Cluster Management (RHACM) to operate in hub and spoke environments.
KMM is compatible with hub and spoke environments through decoupling KMM features. A
ManagedClusterModule
Module
In hub and spoke setups, spokes are focused, resource-constrained clusters that are centrally managed by a hub cluster. Spokes run the single-cluster edition of KMM, with those resource-intensive features disabled. To adapt KMM to this environment, you should reduce the workload running on the spokes to the minimum, while the hub takes care of the expensive tasks.
Building kernel module images and signing the
.ko
DaemonSets
4.12.1. KMM-Hub Copiar enlaceEnlace copiado en el portapapeles!
The KMM project provides KMM-Hub, an edition of KMM dedicated to hub clusters. KMM-Hub monitors all kernel versions running on the spokes and determines the nodes on the cluster that should receive a kernel module.
KMM-Hub runs all compute-intensive tasks such as image builds and kmod signing, and prepares the trimmed-down
Module
KMM-Hub cannot be used to load kernel modules on the hub cluster. Install the regular edition of KMM to load kernel modules.
4.12.2. Installing KMM-Hub Copiar enlaceEnlace copiado en el portapapeles!
You can use one of the following methods to install KMM-Hub:
- Using the Operator Lifecycle Manager (OLM)
- Creating KMM resources
4.12.2.1. Installing KMM-Hub using the Operator Lifecycle Manager Copiar enlaceEnlace copiado en el portapapeles!
Use the Operators section of the OpenShift console to install KMM-Hub.
4.12.2.2. Installing KMM-Hub by creating KMM resources Copiar enlaceEnlace copiado en el portapapeles!
Procedure
-
If you want to install KMM-Hub programmatically, you can use the following resources to create the ,
NamespaceandOperatorGroupresources:Subscription
---
apiVersion: v1
kind: Namespace
metadata:
name: openshift-kmm-hub
---
apiVersion: operators.coreos.com/v1
kind: OperatorGroup
metadata:
name: kernel-module-management-hub
namespace: openshift-kmm-hub
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: kernel-module-management-hub
namespace: openshift-kmm-hub
spec:
channel: stable
installPlanApproval: Automatic
name: kernel-module-management-hub
source: redhat-operators
sourceNamespace: openshift-marketplace
4.12.3. Using the ManagedClusterModule CRD Copiar enlaceEnlace copiado en el portapapeles!
Use the
ManagedClusterModule
Module
apiVersion: hub.kmm.sigs.x-k8s.io/v1beta1
kind: ManagedClusterModule
metadata:
name: <my-mcm>
# No namespace, because this resource is cluster-scoped.
spec:
moduleSpec:
selector:
node-wants-my-mcm: 'true'
spokeNamespace: <some-namespace>
selector:
wants-my-mcm: 'true'
If build or signing instructions are present in
.spec.moduleSpec
When the
.spec.selector matches
ManagedCluster
ManifestWork
ManifestWork
Module
build
sign
containerImage
4.12.4. Running KMM on the spoke Copiar enlaceEnlace copiado en el portapapeles!
After installing KMM on the spoke, no further action is required. Create a
ManagedClusterModule
Procedure
You can install KMM on the spokes cluster through a RHACM
Policy
Policy
Module
Use the following RHACM policy to install KMM on spoke clusters:
--- apiVersion: policy.open-cluster-management.io/v1 kind: Policy metadata: name: install-kmm spec: remediationAction: enforce disabled: false policy-templates: - objectDefinition: apiVersion: policy.open-cluster-management.io/v1 kind: ConfigurationPolicy metadata: name: install-kmm spec: severity: high object-templates: - complianceType: mustonlyhave objectDefinition: apiVersion: v1 kind: Namespace metadata: name: openshift-kmm - complianceType: mustonlyhave objectDefinition: apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: kmm namespace: openshift-kmm spec: upgradeStrategy: Default - complianceType: mustonlyhave objectDefinition: apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: kernel-module-management namespace: openshift-kmm spec: channel: stable config: env: - name: KMM_MANAGED value: "1" installPlanApproval: Automatic name: kernel-module-management source: redhat-operators sourceNamespace: openshift-marketplace - complianceType: mustonlyhave objectDefinition: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: kmm-module-manager rules: - apiGroups: [kmm.sigs.x-k8s.io] resources: [modules] verbs: [create, delete, get, list, patch, update, watch] - complianceType: mustonlyhave objectDefinition: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: klusterlet-kmm subjects: - kind: ServiceAccount name: klusterlet-work-sa namespace: open-cluster-management-agent roleRef: kind: ClusterRole name: kmm-module-manager apiGroup: rbac.authorization.k8s.io --- apiVersion: apps.open-cluster-management.io/v1 kind: PlacementRule metadata: name: all-managed-clusters spec: clusterSelector:1 matchExpressions: [] --- apiVersion: policy.open-cluster-management.io/v1 kind: PlacementBinding metadata: name: install-kmm placementRef: apiGroup: apps.open-cluster-management.io kind: PlacementRule name: all-managed-clusters subjects: - apiGroup: policy.open-cluster-management.io kind: Policy name: install-kmm- 1
- The
spec.clusterSelectorfield can be customized to target select clusters only.
Legal Notice
Copiar enlaceEnlace copiado en el portapapeles!
Copyright © Red Hat
OpenShift documentation is licensed under the Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0).
Modified versions must remove all Red Hat trademarks.
Portions adapted from https://github.com/kubernetes-incubator/service-catalog/ with modifications by Red Hat.
Red Hat, Red Hat Enterprise Linux, the Red Hat logo, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of the OpenJS Foundation.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation’s permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.