From 4c036cb5c0c14bbebafb7228205cc07377913649 Mon Sep 17 00:00:00 2001 From: JoeAldinger Date: Mon, 3 Aug 2026 10:40:48 -0400 Subject: [PATCH] OSDOCS-18372: DITA callouts for KMM modules Co-authored-by: Cursor --- .../kmm-adding-the-keys-for-secureboot.adoc | 7 +- ...kmm-building-and-signing-a-kmod-image.adoc | 17 +-- modules/kmm-building-in-cluster.adoc | 35 +++--- ...-configuring-the-lookup-path-on-nodes.adoc | 5 +- modules/kmm-day1-machineconfigpool.adoc | 11 +- modules/kmm-example-module-cr.adoc | 102 +++++++++--------- modules/kmm-hub-running-kmm-on-the-spoke.adoc | 11 +- ...mm-hub-using-the-managedclustermodule.adoc | 20 ++-- ...kmm-signing-kmods-in-a-prebuilt-image.adoc | 15 +-- modules/kmm-tuning-the-module-resource.adoc | 7 +- 10 files changed, 126 insertions(+), 104 deletions(-) diff --git a/modules/kmm-adding-the-keys-for-secureboot.adoc b/modules/kmm-adding-the-keys-for-secureboot.adoc index fab5ef19bcae..f3763f160784 100644 --- a/modules/kmm-adding-the-keys-for-secureboot.adoc +++ b/modules/kmm-adding-the-keys-for-secureboot.adoc @@ -53,7 +53,7 @@ apiVersion: v1 kind: Secret metadata: name: my-signing-key-pub - namespace: default <1> + namespace: default type: Opaque data: cert: @@ -63,12 +63,13 @@ apiVersion: v1 kind: Secret metadata: name: my-signing-key - namespace: default <1> + namespace: default type: Opaque data: key: ---- -<1> `namespace` - Replace `default` with a valid namespace. ++ +Replace `default` with a valid namespace. . Apply the YAML file: + diff --git a/modules/kmm-building-and-signing-a-kmod-image.adoc b/modules/kmm-building-and-signing-a-kmod-image.adoc index 6d54727ff05f..6059659359cb 100644 --- a/modules/kmm-building-and-signing-a-kmod-image.adoc +++ b/modules/kmm-building-and-signing-a-kmod-image.adoc @@ -31,7 +31,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: example-module-dockerfile - namespace: <1> + namespace: data: dockerfile: | ARG DTK_AUTO @@ -52,10 +52,10 @@ apiVersion: kmm.sigs.x-k8s.io/v1beta1 kind: Module metadata: name: example-module - namespace: <1> + namespace: spec: moduleLoader: - serviceAccountName: default <2> + serviceAccountName: default container: modprobe: moduleName: simple_kmod @@ -72,11 +72,14 @@ spec: name: filesToSign: - /opt/lib/modules/4.18.0-348.2.1.el8_5.x86_64/kmm_ci_a.ko - imageRepoSecret: <3> + imageRepoSecret: name: repo-pull-secret selector: # top-level selector kubernetes.io/arch: amd64 ---- -<1> Replace `default` with a valid namespace. -<2> The default `serviceAccountName` does 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. -<3> Used as `imagePullSecrets` in the `DaemonSet` object and to pull and push for the build and sign features. ++ +where: ++ +`metadata.namespace`:: Specifies replacing `default` with a valid namespace. +`spec.moduleLoader.serviceAccountName`:: Specifies that the default does 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. +`spec.imageRepoSecret`:: Specifies that it is used as `imagePullSecrets` in the `DaemonSet` object and to pull and push for the build and sign features. diff --git a/modules/kmm-building-in-cluster.adoc b/modules/kmm-building-in-cluster.adoc index cc7d73e43d83..b784eacb9bff 100644 --- a/modules/kmm-building-in-cluster.adoc +++ b/modules/kmm-building-in-cluster.adoc @@ -23,27 +23,30 @@ Otherwise, KMM creates a `Build` resource to build your image. After the image i - regexp: '^.+$' containerImage: "some.registry/org/:${KERNEL_FULL_VERSION}" build: - buildArgs: <1> + buildArgs: - name: ARG_NAME value: - secrets: <2> - - name: <3> + secrets: + - name: baseImageRegistryTLS: - insecure: false <4> - insecureSkipTLSVerify: false <5> - dockerfileConfigMap: <6> + insecure: false + insecureSkipTLSVerify: false + dockerfileConfigMap: name: registryTLS: - insecure: false <7> - insecureSkipTLSVerify: false <8> + 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 Dockerfile `FROM` instruction 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 Dockerfile `FROM` instruction 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. ++ +where: ++ +`spec.moduleLoader.container.kernelMappings.build.buildArgs`:: Specifies build arguments. This field is optional. +`spec.moduleLoader.container.kernelMappings.build.secrets`:: Specifies secrets. This field is optional. +`spec.moduleLoader.container.kernelMappings.build.secrets.name`:: Specifies that it will be mounted in the build pod as `/run/secrets/some-kubernetes-secret`. +`spec.moduleLoader.container.kernelMappings.build.baseImageRegistryTLS.insecure`:: Specifies that the build will be allowed to pull the image in the Dockerfile `FROM` instruction using plain HTTP when set to `true`. Avoid using this parameter. This parameter is optional. +`spec.moduleLoader.container.kernelMappings.build.baseImageRegistryTLS.insecureSkipTLSVerify`:: Specifies that the build will skip any TLS server certificate validation when pulling the image in the Dockerfile `FROM` instruction using plain HTTP when set to `true`. Avoid using this parameter. This parameter is optional. +`spec.moduleLoader.container.kernelMappings.build.dockerfileConfigMap`:: Specifies the Dockerfile ConfigMap. This field is required. +`spec.moduleLoader.container.kernelMappings.registryTLS.insecure`:: Specifies that KMM will be allowed to check if the container image already exists using plain HTTP when set to `true`. Avoid using this parameter. This parameter is optional. +`spec.moduleLoader.container.kernelMappings.registryTLS.insecureSkipTLSVerify`:: Specifies that KMM will skip any TLS server certificate validation when checking if the container image already exists when set to `true`. Avoid using this parameter. This parameter is optional. Successful build pods are garbage collected immediately, unless the `job.gcDelay` parameter is set in the Operator configuration. Failed build pods are always preserved and must be deleted manually by the administrator for the build to be restarted. diff --git a/modules/kmm-configuring-the-lookup-path-on-nodes.adoc b/modules/kmm-configuring-the-lookup-path-on-nodes.adoc index 40eb09c121e9..9d023c8afc18 100644 --- a/modules/kmm-configuring-the-lookup-path-on-nodes.adoc +++ b/modules/kmm-configuring-the-lookup-path-on-nodes.adoc @@ -18,13 +18,14 @@ apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: labels: - machineconfiguration.openshift.io/role: worker <1> + machineconfiguration.openshift.io/role: worker 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 {sno}, use either `control-pane` or `master` objects. ++ +You can configure the label based on your needs. In the case of {sno}, use either `control-pane` or `master` objects. . By applying the `MachineConfig` CR, the nodes are automatically rebooted. diff --git a/modules/kmm-day1-machineconfigpool.adoc b/modules/kmm-day1-machineconfigpool.adoc index cc7867f3aefd..e28fb027c156 100644 --- a/modules/kmm-day1-machineconfigpool.adoc +++ b/modules/kmm-day1-machineconfigpool.adoc @@ -14,17 +14,20 @@ kind: MachineConfigPool metadata: name: sfc spec: - machineConfigSelector: <1> + machineConfigSelector: matchExpressions: - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker, sfc]} - nodeSelector: <2> + nodeSelector: matchLabels: node-role.kubernetes.io/sfc: "" paused: false maxUnavailable: 1 ---- -<1> Matches the labels in the MachineConfig. -<2> Matches the labels on the node. ++ +where: ++ +`spec.machineConfigSelector`:: Specifies that it matches the labels in the MachineConfig. +`spec.nodeSelector`:: Specifies that it matches the labels on the node. There are predefined `MachineConfigPools` in the OCP cluster: diff --git a/modules/kmm-example-module-cr.adoc b/modules/kmm-example-module-cr.adoc index 21b279dc6e3b..e593b2c07e4a 100644 --- a/modules/kmm-example-module-cr.adoc +++ b/modules/kmm-example-module-cr.adoc @@ -19,85 +19,85 @@ spec: moduleLoader: container: modprobe: - moduleName: <1> - dirName: /opt <2> - firmwarePath: /firmware <3> - parameters: <4> + moduleName: + dirName: /opt + firmwarePath: /firmware + parameters: - param=1 - kernelMappings: <5> + 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$' <6> + - regexp: '^.+\fc37\.x86_64$' containerImage: "some.other.registry/org/:${KERNEL_FULL_VERSION}" - - regexp: '^.+$' <7> - containerImage: "some.registry/org/:${KERNEL_FULL_VERSION}" <8> + - regexp: '^.+$' + containerImage: "some.registry/org/:${KERNEL_FULL_VERSION}" build: - buildArgs: <9> + buildArgs: - name: ARG_NAME value: secrets: - - name: <10> - baseImageRegistryTLS: <11> + - name: + baseImageRegistryTLS: insecure: false - insecureSkipTLSVerify: false <12> - dockerfileConfigMap: <13> + insecureSkipTLSVerify: false + dockerfileConfigMap: name: sign: certSecret: - name: <14> + name: keySecret: - name: <15> + name: filesToSign: - /opt/lib/modules/${KERNEL_FULL_VERSION}/.ko - registryTLS: <16> - insecure: false <17> + registryTLS: + insecure: false insecureSkipTLSVerify: false - serviceAccountName: <18> - devicePlugin: <19> + serviceAccountName: + devicePlugin: container: - image: some.registry/org/device-plugin:latest <20> + image: some.registry/org/device-plugin:latest env: - name: MY_DEVICE_PLUGIN_ENV_VAR value: SOME_VALUE - volumeMounts: <21> + volumeMounts: - mountPath: /some/mountPath name: - volumes: <22> + volumes: - name: configMap: name: - serviceAccountName: <23> - imageRepoSecret: <24> + serviceAccountName: + imageRepoSecret: name: selector: node-role.kubernetes.io/worker: "" ---- -<1> Required. -<2> Optional. -<3> Optional: Copies the contents of this path into the path specified in `worker.setFirmwareClassPath` (which is preset to `/var/lib/firmware`) of the `kmm-operator-manager-config` config map. This action occurs before `modprobe` is called to insert the kernel module. -<4> Optional. -<5> At least one kernel item is required. -<6> For each node running a kernel matching the regular expression, KMM checks if you have included a tag or a digest. If you have not specified a tag or digest in the container image, then the validation webhook returns an error and does not apply the module. -<7> For any other kernel, build the image using the Dockerfile in the `my-kmod` ConfigMap. -<8> The container image that holds the customer's kmods. This container should contain the `cp` binary. -<9> Optional. -<10> Optional: A value for `some-kubernetes-secret` can be obtained from the build environment at `/run/secrets/some-kubernetes-secret`. -<11> This field has no effect. When building kmod images or signing kmods within a kmod image, -you might sometimes need to pull base images from a registry that serves a certificate signed by an -untrusted Certificate Authority (CA). In order for KMM to trust that CA, it must also trust the new CA -by replacing the cluster's CA bundle. ++ +where: ++ +`spec.moduleLoader.container.modprobe.moduleName`:: Specifies that this field is required. +`spec.moduleLoader.container.modprobe.dirName`:: Specifies that this field is optional. +`spec.moduleLoader.container.modprobe.firmwarePath`:: Specifies that the contents of this path are copied into the path specified in `worker.setFirmwareClassPath` (which is preset to `/var/lib/firmware`) of the `kmm-operator-manager-config` config map. This action occurs before `modprobe` is called to insert the kernel module. This field is optional. +`spec.moduleLoader.container.modprobe.parameters`:: Specifies that this field is optional. +`spec.moduleLoader.container.kernelMappings`:: Specifies that at least one kernel item is required. +`spec.moduleLoader.container.kernelMappings.regexp`:: Specifies that for each node running a kernel matching the regular expression, KMM checks if you have included a tag or a digest. If you have not specified a tag or digest in the container image, then the validation webhook returns an error and does not apply the module. +`spec.moduleLoader.container.kernelMappings.regexp`:: Specifies that for any other kernel, build the image using the Dockerfile in the `my-kmod` ConfigMap. +`spec.moduleLoader.container.kernelMappings.containerImage`:: Specifies the container image that holds the customer's kmods. This container should contain the `cp` binary. +`spec.moduleLoader.container.kernelMappings.build.buildArgs`:: Specifies that this field is optional. +`spec.moduleLoader.container.kernelMappings.build.secrets`:: Specifies that a value for `some-kubernetes-secret` can be obtained from the build environment at `/run/secrets/some-kubernetes-secret`. This field is optional. +`spec.moduleLoader.container.kernelMappings.build.baseImageRegistryTLS`:: Specifies that this field has no effect. When building kmod images or signing kmods within a kmod image, you might sometimes need to pull base images from a registry that serves a certificate signed by an untrusted Certificate Authority (CA). In order for KMM to trust that CA, it must also trust the new CA by replacing the cluster's CA bundle. + See "Additional resources" to learn how to replace the cluster's CA bundle. -<12> Optional: Avoid using this parameter. If set to `true`, the build skips any TLS server certificate validation when pulling the image in the Dockerfile `FROM` instruction using plain HTTP. -<13> Required. -<14> Required: A secret holding the public secureboot key with the key 'cert'. -<15> Required: A secret holding the private secureboot key with the key 'key'. -<16> Optional: Avoid using this parameter. If set to `true`, KMM is allowed to check if the container image already exists using plain HTTP. -<17> Optional: Avoid using this parameter. If set to `true`, KMM skips any TLS server certificate validation when checking if the container image already exists. -<18> Optional. -<19> Optional. -<20> Required: If the device plugin section is present. -<21> Optional. -<22> Optional. -<23> Optional. -<24> Optional: Used to pull module loader and device plugin images. +`spec.moduleLoader.container.kernelMappings.build.baseImageRegistryTLS.insecureSkipTLSVerify`:: Specifies to avoid using this parameter. If set to `true`, the build skips any TLS server certificate validation when pulling the image in the Dockerfile `FROM` instruction using plain HTTP. This parameter is optional. +`spec.moduleLoader.container.kernelMappings.build.dockerfileConfigMap`:: Specifies that this field is required. +`spec.moduleLoader.container.kernelMappings.sign.certSecret`:: Specifies a secret holding the public secureboot key with the key 'cert'. +`spec.moduleLoader.container.kernelMappings.sign.keySecret`:: Specifies a secret holding the private secureboot key with the key 'key'. +`spec.moduleLoader.container.kernelMappings.registryTLS`:: Specifies to avoid using this parameter. If set to `true`, KMM is allowed to check if the container image already exists using plain HTTP. This parameter is optional. +`spec.moduleLoader.container.kernelMappings.registryTLS.insecure`:: Specifies to avoid using this parameter. If set to `true`, KMM skips any TLS server certificate validation when checking if the container image already exists. This parameter is optional. +`spec.moduleLoader.serviceAccountName`:: Specifies that this field is optional. +`spec.devicePlugin`:: Specifies that this field is optional. +`spec.devicePlugin.container.image`:: Specifies that this field is required if the device plugin section is present. +`spec.devicePlugin.container.volumeMounts`:: Specifies that this field is optional. +`spec.devicePlugin.volumes`:: Specifies that this field is optional. +`spec.devicePlugin.serviceAccountName`:: Specifies that this field is optional. +`spec.imageRepoSecret`:: Specifies that this field is used to pull module loader and device plugin images. This field is optional. diff --git a/modules/kmm-hub-running-kmm-on-the-spoke.adoc b/modules/kmm-hub-running-kmm-on-the-spoke.adoc index f68cc2cffbd3..bae0aca4f121 100644 --- a/modules/kmm-hub-running-kmm-on-the-spoke.adoc +++ b/modules/kmm-hub-running-kmm-on-the-spoke.adoc @@ -60,7 +60,7 @@ spec: channel: stable config: env: - - name: KMM_MANAGED <1> + - name: KMM_MANAGED value: "1" installPlanApproval: Automatic name: kernel-module-management @@ -96,7 +96,7 @@ kind: PlacementRule metadata: name: all-managed-clusters spec: - clusterSelector: <2> + clusterSelector: matchExpressions: [] --- apiVersion: policy.open-cluster-management.io/v1 @@ -112,5 +112,8 @@ subjects: kind: Policy name: install-kmm ---- -<1> This environment variable is required when running KMM on a spoke cluster. -<2> The `spec.clusterSelector` field can be customized to target select clusters only. ++ +where: ++ +`spec.policy-templates.objectDefinition.spec.object-templates.objectDefinition.spec.config.env.name`:: Specifies that this environment variable is required when running KMM on a spoke cluster. +`spec.clusterSelector`:: Specifies that this field can be customized to target select clusters only. diff --git a/modules/kmm-hub-using-the-managedclustermodule.adoc b/modules/kmm-hub-using-the-managedclustermodule.adoc index f9fff29e2abc..37c2bb3941d7 100644 --- a/modules/kmm-hub-using-the-managedclustermodule.adoc +++ b/modules/kmm-hub-using-the-managedclustermodule.adoc @@ -17,20 +17,22 @@ metadata: name: # No namespace, because this resource is cluster-scoped. spec: - moduleSpec: <1> - selector: <2> + moduleSpec: + selector: node-wants-my-mcm: 'true' - spokeNamespace: <3> + spokeNamespace: - selector: <4> + selector: wants-my-mcm: 'true' ---- -<1> `moduleSpec`: Contains `moduleLoader` and `devicePlugin` sections, similar to a `Module` resource. - -<2> Selects nodes within the `ManagedCluster`. -<3> Specifies in which namespace the `Module` should be created. -<4> Selects `ManagedCluster` objects. ++ +where: ++ +`spec.moduleSpec`:: Specifies the `moduleLoader` and `devicePlugin` sections, similar to a `Module` resource. +`spec.moduleSpec.selector`:: Specifies nodes within the `ManagedCluster`. +`spec.spokeNamespace`:: Specifies in which namespace the `Module` should be created. +`spec.selector`:: Specifies `ManagedCluster` objects. If build or signing instructions are present in `.spec.moduleSpec`, those pods are run on the hub cluster in the operator's namespace. diff --git a/modules/kmm-signing-kmods-in-a-prebuilt-image.adoc b/modules/kmm-signing-kmods-in-a-prebuilt-image.adoc index cf66148609bd..0eb91e09f158 100644 --- a/modules/kmm-signing-kmods-in-a-prebuilt-image.adoc +++ b/modules/kmm-signing-kmods-in-a-prebuilt-image.adoc @@ -31,16 +31,16 @@ spec: moduleLoader: serviceAccountName: default container: - modprobe: <1> + modprobe: moduleName: '' 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: <2> + containerImage: sign: # the image containing the unsigned kmods (we need this because we are not building the kmods within the cluster) - unsignedImage: <3> + unsignedImage: keySecret: # a secret holding the private secureboot key with the key 'key' name: certSecret: # a secret holding the public secureboot key with the key 'cert' @@ -53,6 +53,9 @@ spec: selector: kubernetes.io/arch: amd64 ---- -<1> The name of the kmod to load. -<2> The name of the container image. For example, `quay.io/myuser/my-driver: The name of the unsigned image. For example, `quay.io/myuser/my-driver: + firmwarePath: /firmware ---- -<1> Optional: Copies `/firmware/*` into `/var/lib/firmware/` on the node. ++ +where: ++ +`spec.moduleLoader.container.modprobe.firmwarePath`:: Specifies that `/firmware/*` is copied into `/var/lib/firmware/` on the node. This field is optional.