4.3. Déploiement du module du noyau

Pour chaque ressource Module, Kernel Module Management (KMM) peut créer un certain nombre de ressources DaemonSet:

  • Un ModuleLoader DaemonSet par version de noyau compatible fonctionnant dans le cluster.
  • Un plugin d'appareil DaemonSet, s'il est configuré.

Les ressources du démon de chargement de modules exécutent des images ModuleLoader pour charger les modules du noyau. Une image de chargeur de modules est une image OCI qui contient les fichiers .ko et les binaires modprobe et sleep.

Lorsque le module loader pod est créé, il exécute modprobe pour insérer le module spécifié dans le noyau. Il entre ensuite dans un état de veille jusqu'à ce qu'il soit terminé. À ce moment-là, le crochet ExecPreStop exécute modprobe -r pour décharger le module du noyau.

Si l'attribut .spec.devicePlugin est configuré dans une ressource Module, KMM crée un ensemble de démons de plugins de périphériques dans le cluster. Ce jeu de démons cible :

  • Nœuds correspondant au site .spec.selector de la ressource Module.
  • Nœuds avec le module du noyau chargé (où le module loader pod est dans l'état Ready ).

4.3.1. La définition de la ressource personnalisée du module

La définition de ressource personnalisée (CRD) Module représente un module de noyau qui peut être chargé sur tous les nœuds du cluster ou sur certains d'entre eux, par l'intermédiaire d'une image de chargeur de module. Une ressource personnalisée Module (CR) spécifie une ou plusieurs versions du noyau avec lesquelles elle est compatible, ainsi qu'un sélecteur de nœud.

Les versions compatibles d'une ressource Module sont répertoriées sous .spec.moduleLoader.container.kernelMappings. Un mappage de noyau peut soit correspondre à une version literal, soit utiliser regexp pour correspondre à plusieurs d'entre elles en même temps.

La boucle de rapprochement pour la ressource Module se déroule comme suit :

  1. Liste de tous les nœuds correspondant à .spec.selector.
  2. Construire un ensemble de toutes les versions du noyau fonctionnant sur ces nœuds.
  3. Pour chaque version du noyau :

    1. Parcourez .spec.moduleLoader.container.kernelMappings et trouvez le nom de l'image de conteneur appropriée. Si le mappage du noyau est défini par build ou sign et que l'image du conteneur n'existe pas encore, exécutez la compilation, le travail de signature, ou les deux, selon les besoins.
    2. Créez un daemon de chargement de modules avec l'image du conteneur déterminée à l'étape précédente.
    3. Si .spec.devicePlugin est défini, créez un ensemble de démons d'extension de périphérique en utilisant la configuration spécifiée sous .spec.devicePlugin.container.
  4. Lancer garbage-collect sur :

    1. Les ressources du jeu de démons existant ciblent les versions du noyau qui ne sont exécutées par aucun nœud de la grappe.
    2. Des emplois réussis dans le domaine de la construction.
    3. Des signatures réussies.

4.3.2. Sécurité et autorisations

Important

Le chargement des modules du noyau est une opération très sensible. Une fois chargés, les modules du noyau disposent de toutes les autorisations possibles pour effectuer n'importe quel type d'opération sur le nœud.

4.3.2.1. ServiceAccounts et SecurityContextConstraints

Kernel Module Management (KMM) crée une charge de travail privilégiée pour charger les modules du noyau sur les nœuds. Cette charge de travail doit être ServiceAccounts autorisée à utiliser la ressource privileged SecurityContextConstraint (SCC).

Le modèle d'autorisation pour cette charge de travail dépend de l'espace de noms de la ressource Module, ainsi que de sa spécification.

  • Si les champs .spec.moduleLoader.serviceAccountName ou .spec.devicePlugin.serviceAccountName sont définis, ils sont toujours utilisés.
  • Si ces champs ne sont pas renseignés, alors :

    • Si la ressource Module est créée dans l'espace de noms de l'opérateur (openshift-kmm par défaut), KMM utilise alors sa ressource par défaut, ServiceAccounts, pour exécuter les ensembles de démons.
    • Si la ressource Module est créée dans un autre espace de noms, KMM exécute les ensembles de démons en tant que default ServiceAccount de l'espace de noms. La ressource Module ne peut pas exécuter une charge de travail privilégiée à moins que vous ne l'autorisiez manuellement à utiliser le SCC privileged.
Important

openshift-kmm est un espace de noms de confiance.

Lors de la configuration des autorisations RBAC, n'oubliez pas que tout utilisateur ou ServiceAccount créant une ressource Module dans l'espace de noms openshift-kmm entraîne l'exécution automatique par KMM de charges de travail privilégiées sur potentiellement tous les nœuds de la grappe.

Pour permettre à n'importe quel site ServiceAccount d'utiliser le SCC privileged et donc d'exécuter des pods de chargement de modules ou de plugins de périphériques, utilisez la commande suivante :

$ oc adm policy add-scc-to-user privileged -z "${serviceAccountName}" [ -n "${namespace}" ]

4.3.2.2. Normes de sécurité des pods

OpenShift exécute un mécanisme de synchronisation qui définit automatiquement le niveau de sécurité de l'espace de noms Pod Security en fonction des contextes de sécurité utilisés. Aucune action n'est nécessaire.

4.3.3. Exemple de module CR

Voici un exemple de Module annoté :

apiVersion: kmm.sigs.x-k8s.io/v1beta1
kind: Module
metadata:
  name: <my_kmod>
spec:
  moduleLoader:
    container:
      modprobe:
        moduleName: <my_kmod> 1
        dirName: /opt 2
        firmwarePath: /firmware 3
        parameters:  4
          - param=1
      kernelMappings:  5
        - 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
          containerImage: "some.other.registry/org/<my_kmod>:${KERNEL_FULL_VERSION}"
        - regexp: '^.+$' 7
          containerImage: "some.registry/org/<my_kmod>:${KERNEL_FULL_VERSION}"
          build:
            buildArgs:  8
              - name: ARG_NAME
                value: <some_value>
            secrets:
              - name: <some_kubernetes_secret>  9
            baseImageRegistryTLS: 10
              insecure: false
              insecureSkipTLSVerify: false 11
            dockerfileConfigMap:  12
              name: <my_kmod_dockerfile>
          sign:
            certSecret:
              name: <cert_secret>  13
            keySecret:
              name: <key_secret>  14
            filesToSign:
              - /opt/lib/modules/${KERNEL_FULL_VERSION}/<my_kmod>.ko
          registryTLS: 15
            insecure: false 16
            insecureSkipTLSVerify: false
    serviceAccountName: <sa_module_loader>  17
  devicePlugin:  18
    container:
      image: some.registry/org/device-plugin:latest  19
      env:
        - name: MY_DEVICE_PLUGIN_ENV_VAR
          value: SOME_VALUE
      volumeMounts:  20
        - mountPath: /some/mountPath
          name: <device_plugin_volume>
    volumes:  21
      - name: <device_plugin_volume>
        configMap:
          name: <some_configmap>
    serviceAccountName: <sa_device_plugin> 22
  imageRepoSecret:  23
    name: <secret_name>
  selector:
    node-role.kubernetes.io/worker: ""
1 1 1
Required.
2
En option.
3
Facultatif : Copie /firmware/* dans /var/lib/firmware/ sur le nœud.
4
En option.
5
Au moins un élément du noyau est requis.
6
Pour chaque nœud exécutant un noyau correspondant à l'expression régulière, KMM crée une ressource DaemonSet exécutant l'image spécifiée dans containerImage, ${KERNEL_FULL_VERSION} étant remplacé par la version du noyau.
7
Pour tout autre noyau, construisez l'image en utilisant le fichier Docker dans le ConfigMap de my-kmod.
8
En option.
9
Facultatif : Une valeur pour some-kubernetes-secret peut être obtenue à partir de l'environnement de construction à l'adresse /run/secrets/some-kubernetes-secret.
10
Facultatif : Évitez d'utiliser ce paramètre. Si ce paramètre vaut true, la compilation est autorisée à extraire l'image dans l'instruction Dockerfile FROM en utilisant le protocole HTTP.
11
Facultatif : Évitez d'utiliser ce paramètre. S'il vaut true, la compilation ignorera toute validation de certificat de serveur TLS lors de l'extraction de l'image dans l'instruction Dockerfile FROM à l'aide d'un simple HTTP.
12
Required.
13
Nécessaire : Un secret contenant la clé publique secureboot avec la clé "cert".
14
Nécessaire : Un secret contenant la clé privée de démarrage sécurisé avec la clé "key".
15
Facultatif : Évitez d'utiliser ce paramètre. S'il vaut true, KMM sera autorisé à vérifier si l'image du conteneur existe déjà en utilisant le protocole HTTP ordinaire.
16
Facultatif : Évitez d'utiliser ce paramètre. S'il est défini sur true, KMM ignorera toute validation de certificat de serveur TLS lors de la vérification de l'existence de l'image du conteneur.
17
En option.
18
En option.
19
Obligatoire : Si la section plugin de l'appareil est présente.
20
En option.
21
En option.
22
En option.
23
Facultatif : Utilisé pour extraire les images du chargeur de module et du plugin de périphérique.