4.4. 内核模块部署
对于每个 Module 资源,内核模块管理 (KMM) 可以创建多个 DaemonSet 资源:
-
集群中运行的每个兼容内核版本有一个 ModuleLoader
DaemonSet。 -
一个设备插件
DaemonSet(如果已配置)。
模块加载守护进程设置资源运行 ModuleLoader 镜像来加载内核模块。模块加载程序镜像是一个 OCI 镜像,其中包含 .ko 文件和 modprobe 和 sleep 二进制文件。
创建模块加载程序 pod 时,pod 会运行 modprobe 将指定的模块插入到内核中。然后,它会进入睡眠状态,直到终止为止。发生这种情况时,ExecPreStop hook 将运行 modprobe -r 来卸载内核模块。
如果在 Module 资源中配置了 .spec.devicePlugin 属性,KMM 会在集群中创建 设备插件 守护进程。该守护进程集目标:
-
与
Module资源的.spec.selector匹配的节点。 -
加载内核模块的节点(模块加载程序 pod 处于
Ready条件)。
4.4.1. 模块自定义资源定义 复制链接链接已复制到粘贴板!
Module 自定义资源定义 (CRD) 代表可通过模块加载程序镜像在所有或选择集群中载入的内核模块。Module 自定义资源 (CR) 指定一个或多个兼容它的内核版本,以及一个节点选择器。
Module 资源的兼容版本列在 .spec.moduleLoader.container.kernelMappings 下。内核映射可以与 literal 版本匹配,也可以使用 regexp 同时匹配其中的许多版本。
Module 资源的协调循环运行以下命令:
-
列出与
.spec.selector匹配的所有节点。 - 构建在这些节点上运行的所有内核版本。
对于每个内核版本:
-
进入
.spec.moduleLoader.container.kernelMappings,并找到适当的容器镜像名称。如果内核映射定义了build或sign,且容器镜像尚不存在,请根据需要运行构建、签名作业或两者。 - 使用上一步中确定的容器镜像创建模块加载程序守护进程集。
-
如果定义了
.spec.devicePlugin,请使用.spec.devicePlugin.container中指定的配置创建一个设备插件守护进程集。
-
进入
在以下运行
garbage-collect:- 针对于集群中的任何节点都没有运行的内核版本的现有守护进程集。
- 成功的构建作业。
- 成功签名作业。
4.4.2. 在内核模块之间设置软依赖项 复制链接链接已复制到粘贴板!
有些配置要求以特定顺序加载多个内核模块才能正常工作,即使模块不会直接依赖于通过符号相互依赖。它们称为软依赖项。depmod 通常不知道这些依赖项,它们不会出现在它生成的文件中。例如,如果 mod_a 有一个软依赖项 mod_b,modprobe mod_a 不会加载 mod_b。
您可以使用 modulesLoadingOrder 字段在 Module 自定义资源定义(CRD)中声明软依赖项来解决这些情况。
# ...
spec:
moduleLoader:
container:
modprobe:
moduleName: mod_a
dirName: /opt
firmwarePath: /firmware
parameters:
- param=1
modulesLoadingOrder:
- mod_a
- mod_b
在以上配置中:
-
加载顺序是
mod_b,然后是mod_a。 -
卸载顺序是
mod_a,然后是mod_b。
列表中的第一个值(最后加载)必须与 moduleName 等效。
4.4.3. 安全和权限 复制链接链接已复制到粘贴板!
加载内核模块是一个高度敏感的操作。加载后,内核模块具有在节点上执行任何类型的操作的所有可能权限。
4.4.3.1. ServiceAccounts 和 SecurityContextConstraints 复制链接链接已复制到粘贴板!
内核模块管理 (KMM) 创建一个特权工作负载,以在节点上加载内核模块。该工作负载需要 ServiceAccounts 被允许来使用 privileged SecurityContextConstraint (SCC) 资源。
该工作负载的授权模型取决于 Module 资源的命名空间及其 spec。
-
如果设置了
.spec.moduleLoader.serviceAccountName或.spec.devicePlugin.serviceAccountName字段,则始终使用它们。 如果没有设置这些字段,则:
-
如果在 Operator 命名空间中创建了
Module资源(默认为openshift-kmm),则 KMM 使用它的默认的、功能强大的ServiceAccount来运行守护进程集。 -
如果在任何其他命名空间中创建了
Module资源,则 KMM 会运行护进程集作为命名空间的defaultServiceAccount运行。Module资源无法运行特权工作负载,除非您手动启用它以使用privilegedSCC。
-
如果在 Operator 命名空间中创建了
openshift-kmm 是一个可信命名空间。
在设置 RBAC 权限时,请记住在 openshift-kmm 命名空间中创建 Module 资源的任何用户或 ServiceAccount 都会导致 KMM 在集群中的任何节点上运行特权工作负载。
要允许任何 ServiceAccount 使用 privileged SCC,因此要运行模块加载程序或设备插件 pod,请使用以下命令:
$ oc adm policy add-scc-to-user privileged -z "${serviceAccountName}" [ -n "${namespace}" ]
4.4.3.2. Pod 安全标准 复制链接链接已复制到粘贴板!
OpenShift 运行一个同步机制,它根据使用的安全上下文自动设置命名空间 Pod 安全级别。不需要操作。