4.3. カーネルモジュールのデプロイ

Module リソースごとに、カーネルモジュール管理 (KMM) は多数の DaemonSet リソースを作成できます。

  • クラスターで実行されている互換性のあるカーネルバージョンごとに 1 つの ModuleLoader DaemonSet
  • 1 つのデバイスプラグイン DaemonSet (設定されている場合)。

モジュールローダーデーモンは、カーネルモジュールをロードするために ModuleLoader イメージを実行するリソースを設定します。モジュールローダーイメージは、.ko ファイルと modprobe および sleep バイナリーの両方を含む OCI イメージです。

モジュールローダー Pod が作成されると、Pod は modprobe を実行して、指定されたモジュールをカーネルに挿入します。その後、終了するまでスリープ状態になります。その場合、ExecPreStop フックは modprobe -r を実行してカーネルモジュールをアンロードします。

モジュール リソースで .spec.devicePlugin 属性が設定されている場合、KMM はクラスター内に デバイスプラグイン デーモンセットを作成します。このデーモンセットは、以下を対象とします。

  • Module リソースの .spec.selector に一致するノード。
  • カーネルモジュールがロードされたノード (モジュールローダー Pod が Ready 状態にある場合)。

4.3.1. Module カスタムリソース定義

Module のカスタムリソース定義 (CRD) は、モジュールローダーイメージを介してクラスター内のすべてのノードまたは選択したノードにロードできるカーネルモジュールを表します。Module カスタムリソース (CR) は、互換性のある 1 つ以上のカーネルバージョンとノードセレクターを指定します。

Module リソースの互換性のあるバージョンは、.spec.moduleLoader.container.kernelMappings の下にリストされています。カーネルマッピングは、literal バージョンと一致するか、regexp を使用してそれらの多くを同時に一致させることができます。

Module リソースの調整ループでは、次の手順が実行されます。

  1. .spec.selector に一致するすべてのノードをリスト表示します。
  2. それらのノードで実行されているすべてのカーネルバージョンのセットを構築します。
  3. 各カーネルバージョンで以下を実行します。

    1. .spec.moduleLoader.container.kernelMappings を調べて、適切なコンテナーイメージ名を見つけます。カーネルマッピングに build または sign が定義されていて、コンテナーイメージがまだ存在しない場合は、必要に応じてビルド、署名ジョブ、またはその両方を実行します。
    2. 前の手順で決定したコンテナーイメージを使用して、モジュールローダーデーモンセットを作成します。
    3. .spec.devicePlugin が定義されている場合は、.spec.devicePlugin.container で指定された設定を使用して、デバイスプラグインデーモンセットを作成します。
  4. 以下で garbage-collect を実行します。

    1. クラスター内のどのノードでも実行されていないカーネルバージョンをターゲットとする既存のデーモンセットリソース。
    2. 成功したビルドジョブ。
    3. 成功した署名ジョブ。

4.3.2. セキュリティーおよびパーミッション

重要

カーネルモジュールのロードは、非常に機密性の高い操作です。それらがロードされると、カーネルモジュールには、ノード上であらゆる種類の操作を実行するためのすべての可能な権限が付与されます。

4.3.2.1. ServiceAccounts および SecurityContextConstraints

カーネルモジュール管理 (KMM) は、カーネルモジュールをノードにロードするための特権ワークロードを作成します。そのワークロードには、privileged SecurityContextConstraint (SCC) リソースの使用を許可された ServiceAccounts が必要です。

そのワークロードの承認モデルは、Module リソースの namespace とその仕様によって異なります。

  • .spec.moduleLoader.serviceAccountName または .spec.devicePlugin.serviceAccountName フィールドが設定されている場合は常に使用されます。
  • これらのフィールドが設定されていない場合:

    • Module リソースが Operator の namespace (デフォルトでは openshift-kmm) に作成される場合、KMM はそのデフォルトの強力な ServiceAccounts を使用してデーモンセットを実行します。
    • Module リソースが他の namespace で作成された場合、KMM はデーモンセットを namespace の default ServiceAccount として実行します。Module リソースは、privileged SCC の使用を手動で有効にしない限り、特権ワークロードを実行できません。
重要

openshift-kmm は信頼できる namespace です。

RBAC 権限を設定するときは、ユーザーまたは ServiceAccount がopenshift-kmm namespace で Module リソースを作成すると、KMM がクラスター内のすべてのノードで特権ワークロードを自動的に実行することに注意してください。

ServiceAccountprivileged SCC を使用できるようにして、モジュールローダーまたはデバイスプラグイン Pod を実行できるようにするには、次のコマンドを使用します。

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

4.3.2.2. Pod のセキュリティー基準

OpenShift は、使用中のセキュリティーコンテキストに基づいて namespace Pod セキュリティーレベルを自動的に設定する同期メカニズムを実行します。アクションは不要です。

4.3.3. モジュール CR の例

以下は、アノテーション付きの Module の例です。

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
必須。
2
オプション。
3
オプション: /firmware/* をノード上の /var/lib/firmware/ にコピーします。
4
オプション。
5
少なくとも 1 つのカーネル項目が必要です。
6
正規表現に一致するカーネルを実行しているノードごとに、KMM は ${KERNEL_FULL_VERSION} をカーネルバージョンに置き換えて、containerImage で指定されたイメージを実行する DaemonSet リソースを作成します。
7
その他のカーネルの場合は、my-kmod ConfigMap の Dockerfile を使用してイメージをビルドします。
8
オプション。
9
オプション: some-kubernetes-secret の値 は、/run/secrets/some-kubernetes-secret のビルド環境から取得できます。
10
オプション: このパラメーターは使用しないでください。true に設定すると、ビルドはプレーン HTTP を使用して Dockerfile FROM 命令のイメージをプルできます。
11
オプション: このパラメーターは使用しないでください。true に設定すると、プレーン HTTP を使用して Dockerfile FROM 命令でイメージをプルするときに、ビルドは TLS サーバー証明書の検証をスキップします。
12
必須。
13
必須: 鍵 cert を持つ公開セキュアブート鍵を保持するシークレット。
14
必須: 'key' という鍵が含まれるセキュアブート秘密鍵を保持するシークレット。
15
オプション: このパラメーターは使用しないでください。true に設定すると、KMM はプレーン HTTP を使用してコンテナーイメージがすでに存在するかどうかを確認できます。
16
オプション: このパラメーターは使用しないでください。true に設定すると、コンテナーイメージがすでに存在するかどうかを確認するときに、KMM は TLS サーバー証明書の検証をスキップします。
17
オプション。
18
オプション。
19
必須: デバイスプラグインセクションが存在する場合。
20
オプション。
21
オプション。
22
オプション。
23
オプション: モジュールローダーとデバイスプラグインイメージをプルするために使用されます。