KubernetesはOCI, CRI, CNI, SMI, CSI, CDI, NRIこれだけを理解すればいいから簡単に学習できます

**Kubernetes**では、コンテナやその周辺機能を扱うために、さまざまな標準インターフェース（～**I**と省略されるもの）が使われています。これらは、コンテナの実行基盤を柔軟かつプラグイン可能にするための仕組みで、それぞれ異なる目的と役割を担っています。ここでは **OCI**, **CRI**, **CNI**, **SMI**, **CSI**, **CDI**, **NRI** について、概要と目的、Kubernetesにおける役割、相互の関連性、実践例を分かりやすく説明します。

## OCI (Open Container Initiative: オープンコンテナ・イニシアティブ)

**概要と目的:** OCIはコンテナの**標準仕様を策定するためのオープンな業界団体**です ([Open Container Initiative](https://opencontainers.org/#:~:text=The%20Open%20Container%20Initiative%20is,around%20container%20formats%20and%20runtimes))。2015年にDocker社やCoreOS社などが中心となって発足し、コンテナの**イメージフォーマット**や**ランタイム仕様**のオープン標準を定めています ([Kubernetes — Open Standards (OCI, CRI, CNI, CSI, SMI, CPI ...](https://medium.com/devops-mojo/kubernetes-open-standards-oci-cri-cni-csi-smi-cpi-overview-what-is-k8s-open-standards-introduction-a860905af6f7#:~:text=Kubernetes%20%E2%80%94%20Open%20Standards%20,It))。OCIの目的は、コンテナイメージやコンテナ実行エンジンがベンダーロックインなく**互換性**を保てるようにすることです ([Kubernetes — Open Standards (OCI, CRI, CNI, CSI, SMI, CPI ...](https://medium.com/devops-mojo/kubernetes-open-standards-oci-cri-cni-csi-smi-cpi-overview-what-is-k8s-open-standards-introduction-a860905af6f7#:~:text=Kubernetes%20%E2%80%94%20Open%20Standards%20,It))。例えばOCIが定めた**OCIイメージ仕様**や**OCIランタイム仕様**に従えば、あるツールでビルドしたコンテナイメージを別のランタイムでも問題なく実行できます。

**Kubernetesにおける役割:** Kubernetes自体はOCIの実装ではありませんが、OCIによって定義された**コンテナイメージ**や**ランタイム**の標準を間接的に利用しています。例えば、Kubernetesで使用する代表的なコンテナランタイムである**containerd**や**CRI-O**はOCI仕様に準拠しており、OCI準拠のイメージ（DockerやPodmanで作成されたOCI対応イメージ）をKubernetesのPodとして実行できます ([Open Container Initiative](https://opencontainers.org/#:~:text=The%20Open%20Container%20Initiative%20is,around%20container%20formats%20and%20runtimes)) ([Kubernetes — Open Standards (OCI, CRI, CNI, CSI, SMI, CPI ...](https://medium.com/devops-mojo/kubernetes-open-standards-oci-cri-cni-csi-smi-cpi-overview-what-is-k8s-open-standards-introduction-a860905af6f7#:~:text=Kubernetes%20%E2%80%94%20Open%20Standards%20,It))。つまり、OCIのおかげで**「どのツールで作ったコンテナでも、Kubernetes上で動く」**という互換性が保たれています。

**他システムとの関連:** OCIは後述するCRIやCNIなどとは直接連携するものではなく、**土台となる標準**を提供する存在です。CRIを介してKubernetesが利用するコンテナランタイム（例: Dockerやcontainerd）は内部でOCIランタイム（例: runc）を使ってコンテナを起動します。したがって、OCIは**CRIやCSIなど他のインターフェースを下支えする基盤**と言えます。

**実践的な活用例:** 開発者がDockerでコンテナイメージをビルドする際、`docker build`で作られるイメージはOCIイメージ仕様に沿っています。これにより、そのイメージをKubernetesクラスタにデプロイするとき、クラスタ上のcontainerdやCRI-Oが問題なく読み込んでコンテナを起動できます。また、OCIランタイム仕様準拠の**runc**などが各Node上でPod内コンテナを実行することで、異なる環境間でも一貫してコンテナを取り扱えます。

## CRI (Container Runtime Interface: コンテナランタイム・インターフェース)

**概要と目的:** CRIはKubernetesが**コンテナランタイムを操作するための標準インターフェース**です。具体的には、各Node上で動く **kubelet**（Kubernetesエージェント） が、コンテナを実行・停止などする際に使う**プラグインAPI**を提供します ([Container Runtime Interface Explained | by David Mosyan - Medium](https://medium.com/@dmosyan/container-runtime-interface-explained-1c3c5af07eaf#:~:text=Medium%20medium,to%20recompile%20the%20cluster%20components))。CRIが策定される以前、kubeletはDockerなど特定のランタイムと密結合していました。しかしCRIによって、**Docker以外のランタイム（例: containerd, CRI-O 等）もkubeletに簡単に接続できる**ようになりました ([Container Runtime Interface Explained | by David Mosyan - Medium](https://medium.com/@dmosyan/container-runtime-interface-explained-1c3c5af07eaf#:~:text=Medium%20medium,to%20recompile%20the%20cluster%20components))。要するに、CRIの目的は**「Kubernetesが様々なコンテナ実行エンジンを統一的に扱えるようにする」**ことです ([Container Runtime Interface Explained | by David Mosyan - Medium](https://medium.com/@dmosyan/container-runtime-interface-explained-1c3c5af07eaf#:~:text=Medium%20medium,to%20recompile%20the%20cluster%20components))。

**Kubernetesにおける役割:** kubeletはCRIを通じてコンテナランタイムに対し、「このコンテナを起動して」「このPodを終了して」といった操作命令を送ります ([Container Runtime Interface (CRI): Past, Present, and Future](https://www.aquasec.com/cloud-native-academy/container-security/container-runtime-interface/#:~:text=Future%20www,a%20software%20driver%2C%20which))。CRIはgRPCという仕組みで定義されており、コンテナランタイム側はCRIサーバ（ランタイムShimとも呼ばれます）を実装します ([Container Runtime Interface (CRI): Past, Present, and Future](https://www.aquasec.com/cloud-native-academy/container-security/container-runtime-interface/#:~:text=Future%20www,a%20software%20driver%2C%20which))。例えば**containerd**や**CRI-O**はCRIに対応したサーバ実装を持っており、**kubeletからの指示を受け取って実際のコンテナ操作を行います** ([Container Runtime Interface (CRI): Past, Present, and Future](https://www.aquasec.com/cloud-native-academy/container-security/container-runtime-interface/#:~:text=Future%20www,a%20software%20driver%2C%20which))。Kubernetes v1.24以降ではDockershimの廃止により、**Dockerも内部的にcontainerd経由でCRI対応**となりました。これによりKubernetesはどのランタイムでも同じようにPodを動かせます。

**他システムとの関連:** CRIはOCIと連携する部分があります。CRI対応ランタイム（例: containerd）は、コンテナを起動する際に**OCIランタイム**（runcなど）を呼び出します ([Container Runtime Interface (CRI): Past, Present, and Future](https://www.aquasec.com/cloud-native-academy/container-security/container-runtime-interface/#:~:text=Future%20www,a%20software%20driver%2C%20which))。つまり**Kubernetes (kubelet)** → **CRI** → **コンテナランタイム (例えばcontainerd)** → **OCIランタイム (runc)** という流れでコンテナが起動されます。また、ネットワークやストレージ周りではCRIから**CNIプラグイン**や**CSIプラグイン**が呼び出される場面もあります（Pod作成時にネットワーク設定やボリュームマウントを行うため） ([List of CNI plugins used in kubernetes - DevOpsSchool.com](https://www.devopsschool.com/blog/list-of-cni-plugins-used-in-kubernetes/#:~:text=Container%20Network%20Interface%20,uses%20CNI%20plugins%20to)) ([Container storage 101: What is CSI and how does it work?](https://www.computerweekly.com/feature/Container-storage-101-What-is-CSI-and-how-does-it-work#:~:text=CSI%20is%20the%20container%20storage,to%20expose%20their%20products))。CRIは全体の中心に位置し、他のインターフェースと協調してPodの環境を構築します。

**実践的な活用例:** **Minikube**や**Kind**などでKubernetesクラスタを構築する際、デフォルトでDockerではなくcontainerdがコンテナ実行に使われることがあります。しかしユーザは特に意識せずに`kubectl run`や`kubectl apply`でPodを作成できます。これは、**CRI経由でkubeletがcontainerdを扱っている**ためです。同じマニフェストでも、裏側のランタイムを差し替える（例えばCRI-Oに変更する）ことが可能で、クラスタを構築し直すことなく様々なランタイムを試せます。

## CNI (Container Network Interface: コンテナネットワーク・インターフェース)

**概要と目的:** CNIは**コンテナのネットワーク接続を設定するための標準インターフェース**です ([40 Days Of Kubernetes (32/40) - DEV Community](https://dev.to/sina14/40-days-of-kubernetes-3240-2d23#:~:text=Container%20Network%20Interface%20,plugins%20to%20manage%20network))。具体的には、コンテナ（Pod）が起動する際にその**ネットワークインターフェースにIPアドレスを割り当てたり、ルーティングを設定したり**するプラグインの仕組みを定めています ([40 Days Of Kubernetes (32/40) - DEV Community](https://dev.to/sina14/40-days-of-kubernetes-3240-2d23#:~:text=Container%20Network%20Interface%20,plugins%20to%20manage%20network))。CNI自体は**Cloud Native Computing Foundation (CNCF)**のプロジェクトで、プラグインの仕様とライブラリから成り、さまざまなベンダーが独自のネットワークプラグインを作れるようにするのが目的です ([GitHub - containernetworking/cni: Container Network Interface](https://github.com/containernetworking/cni#:~:text=GitHub%20,writing%20plugins%20to%20configure))。要は、CNIによって**「コンテナのネットワーク周りをどの実装でも同じ手順で構成できる」**ようになります。

**Kubernetesにおける役割:** Kubernetesではデフォルトのネットワーク実装を持たず、CNIプラグインにネットワーク設定を委ねています ([40 Days Of Kubernetes (32/40) - DEV Community](https://dev.to/sina14/40-days-of-kubernetes-3240-2d23#:~:text=Container%20Network%20Interface%20,plugins%20to%20manage%20network))。各Node上でkubelet（またはCRI内のコンポーネント）は、Pod起動時に**CNIプラグイン**を呼び出してそのPod用のネットワークをセットアップします ([List of CNI plugins used in kubernetes - DevOpsSchool.com](https://www.devopsschool.com/blog/list-of-cni-plugins-used-in-kubernetes/#:~:text=Container%20Network%20Interface%20,uses%20CNI%20plugins%20to))。例えば、**Flannel**や**Calico**、**Weave Net**といったCNI対応プラグインをクラスタに導入すると、それがPod間通信やネットワークポリシーの適用を担います。CNIのおかげで、**Kubernetesはさまざまなネットワーク方式（オーバーレイネットワーク、ルーティングベース、SDNなど）に対応**できるようになっています ([List of CNI plugins used in kubernetes - DevOpsSchool.com](https://www.devopsschool.com/blog/list-of-cni-plugins-used-in-kubernetes/#:~:text=Container%20Network%20Interface%20,uses%20CNI%20plugins%20to))。

**他システムとの関連:** CNIは主にKubernetesのネットワーク部分を担当し、CRIやOCIとは異なる領域ですが、Podのライフサイクルで連携します。Podを起動する際、CRIでコンテナが作られると直後に**CNIプラグイン**が動き、そのコンテナに対してネットワークインターフェースの設定を行います ([List of CNI plugins used in kubernetes - DevOpsSchool.com](https://www.devopsschool.com/blog/list-of-cni-plugins-used-in-kubernetes/#:~:text=Container%20Network%20Interface%20,uses%20CNI%20plugins%20to))。また、サービスメッシュ（後述のSMI）を使う場合でも、基本となるPodネットワークはCNIプラグインが管理します。つまり、**CRI→（コンテナ生成）→CNI→（ネットワーク設定）**という順序で協調してPodがセットアップされます。

**実践的な活用例:** Kubernetesクラスタ構築時に「どのCNIプラグインを使うか」を選択する場面があります。例えばシンプルな構成なら**Flannel**を使って各PodにIPを割り当て、ノード間をVXLANで繋ぐことができます。より高度なネットワークポリシー制御が必要な場合は**Calico**を導入し、CNI経由でPod間通信にファイアウォールルールを適用できます。クラウド環境では、AWSの**Amazon VPC CNI**プラグインのように各PodにクラウドのVPC内IPを直接割り当てるものもあり、システム要件に応じて差し替え可能です。

## SMI (Service Mesh Interface: サービスメッシュ・インターフェース)

**概要と目的:** SMIは**サービスメッシュ向けの標準インターフェース仕様**です。サービスメッシュとは、マイクロサービス間の通信をプロキシ経由で管理し、**トラフィック制御**や**観測**、**セキュリティ**を提供する手法です。SMIは各種サービスメッシュ（IstioやLinkerdなど）の共通の機能について、**ベンダーニュートラルなAPI（KubernetesのCRD群）**を定義することを目的としています ([smi-spec/SPEC_LATEST_STABLE.md at main - GitHub](https://github.com/servicemeshinterface/smi-spec/blob/main/SPEC_LATEST_STABLE.md#:~:text=smi,be%20implemented%20by%20a))。つまり、サービスメッシュ固有のカスタムリソースではなく、SMIが提供する標準リソースを使えば、裏側の実装が異なっても**一貫したやり方でメッシュ機能を利用できる**ようにするのが狙いです ([A standard interface for service meshes on Kubernetes - SMI](https://smi-spec.io/blog/#:~:text=Service%20Mesh%20Interface%20,common%20service%20mesh%20use%20cases))。

SMIは、GAMMA (Gateway API for Mesh Management and Administration)に移行しました。https://gateway-api.sigs.k8s.io/mesh/gamma/

**Kubernetesにおける役割:** SMI自体はKubernetesのコア機能ではなく、**CNCFの標準仕様**として追加で導入するものです。SMIを使う場合、クラスタには**SMI対応のサービスメッシュ実装**（例えば Linkerd や Consul Connect など）がデプロイされます。開発者はKubernetes上で**TrafficSplit**（トラフィックの分割ルール）や**TrafficTarget**（アクセス制御）などSMIで定義されたカスタムリソースを作成し、サービスメッシュに対してポリシーを適用できます ([Hello Service Mesh Interface (SMI) - Microsoft Open Source](https://opensource.microsoft.com/blog/2019/05/21/service-mesh-interface-smi-release/#:~:text=Hello%20Service%20Mesh%20Interface%20,common%20mesh%20use%20cases))。サービスメッシュ側（例: Linkerd）はそのSMIリソースを解釈して実際の挙動（特定サービスへの通信を50%別バージョンにルーティングする等）を実現します。Kubernetesは単にCRDとしてSMIリソースを保持し、コントロールプレーンとして各メッシュ実装と連携する形です。

**他システムとの関連:** SMIは上述の他のインターフェース（CRI/CNI/CSIなど）とは層が異なります。CRI/CNI/CSI/CDI/NRIが主に**Podやコンテナの実行基盤**に関わるのに対し、SMIは**サービス（アプリケーション）間の通信レベル**に関わります。ただし、SMIを利用する際もその**基盤としてはKubernetes上でPodが動いている**必要があり、CNIによるネットワークやOCIコンテナ上でサービスメッシュ用プロキシ（例: Envoy）が稼働しています。まとめると、SMIは**アプリケーションレイヤー**で他のインターフェース群（インフラレイヤー）の上に構築され、相互補完的にクラスタ全体の機能を拡張します。

**実践的な活用例:** たとえば、**Linkerd**を用いているクラスタで**Canaryリリース**（新バージョンへの段階的な切り替え）を行いたい場合、SMIの**TrafficSplit**リソースを定義してトラフィックの何割を新バージョンに流すか指定できます。LinkerdはSMIをサポートしているため、その設定に従って自動的にトラフィックを分配します。後日、サービスメッシュ実装をIstioに替えたくなっても、IstioのSMI Adapterを導入すれば**同じTrafficSplit定義**で動作させることができます。これにより、サービスメッシュの切り替えによる設定変更を最小限に抑えられます ([A standard interface for service meshes on Kubernetes - SMI](https://smi-spec.io/blog/#:~:text=Service%20Mesh%20Interface%20,common%20service%20mesh%20use%20cases))。

## CSI (Container Storage Interface: コンテナストレージ・インターフェース)

**概要と目的:** CSIは**コンテナオーケストレーターとストレージシステム間の標準インターフェース**です ([Container Storage Interface: The Foundation of K8s Storage](https://bluexp.netapp.com/blog/cvo-blg-container-storage-interface-the-foundation-of-k8s-storage#:~:text=Container%20Storage%20Interface%3A%20The%20Foundation,CO%29))。コンテナ環境で外部のディスクやストレージを使う場合、各プラットフォーム（KubernetesやMesosなど）ごとに専用のストレージドライバを作成する必要がありました。CSIはそれを解決するため、**統一されたストレージプラグインの仕組み**を提供します ([Container Storage Interface: The Foundation of K8s Storage](https://bluexp.netapp.com/blog/cvo-blg-container-storage-interface-the-foundation-of-k8s-storage#:~:text=Container%20Storage%20Interface%3A%20The%20Foundation,CO%29))。ストレージベンダーはCSI仕様に沿った**プラグイン（CSIドライバ）**を実装することで、自社のストレージを様々なコンテナ基盤に接続できます ([Container storage 101: What is CSI and how does it work?](https://www.computerweekly.com/feature/Container-storage-101-What-is-CSI-and-how-does-it-work#:~:text=CSI%20is%20the%20container%20storage,to%20expose%20their%20products))。目的は**「ストレージのプラグインを一回作れば、どのコンテナ基盤でも使える」**ようにすることです ([Container storage 101: What is CSI and how does it work?](https://www.computerweekly.com/feature/Container-storage-101-What-is-CSI-and-how-does-it-work#:~:text=CSI%20is%20the%20container%20storage,to%20expose%20their%20products))。

**Kubernetesにおける役割:** KubernetesではCSI導入以前、in-tree（クラスター内部組み込み）のボリュームプラグインしか使えず、クラスタをアップデートする度にストレージドライバをビルドインする必要がありました。CSI対応後は、**外部ストレージプロバイダのドライバを動的にデプロイ可能**になりました ([Container Storage Interface: The Foundation of K8s Storage](https://bluexp.netapp.com/blog/cvo-blg-container-storage-interface-the-foundation-of-k8s-storage#:~:text=Container%20Storage%20Interface%3A%20The%20Foundation,CO%29))。たとえばAWSのEBSやGoogle CloudのPersistent Disk、NetAppのストレージなども、それぞれCSIドライバをKubernetesにデプロイすれば、**PersistentVolumeClaim**を通じてボリュームを動的プロビジョニングできます。KubernetesはCSIプラグインを介して「ボリュームを作成して」「アタッチして」「マウントして」といったリクエストを送り、ストレージ側はそれに応じて操作します ([Container Storage Interface: The Foundation of K8s Storage](https://bluexp.netapp.com/blog/cvo-blg-container-storage-interface-the-foundation-of-k8s-storage#:~:text=Container%20Storage%20Interface%3A%20The%20Foundation,CO%29))。CSIによって**Kubernetesのストレージ拡張はプラグイン方式**となり、多種多様なストレージに対応できるようになりました。

**他システムとの関連:** CSIはCRIやCNIと同様にKubernetesの主要コンポーネント（kubeletやコントローラ）がプラグインを呼び出す点で共通しています。Podがスケジュールされると、必要な永続ボリュームについてKubernetesコントローラが**CSIコントローラプラグイン**にボリューム作成を要求します。また、Node上ではkubeletが**CSIノードプラグイン**を呼び出してボリュームをアタッチ・マウントします。つまり、**スケジューラ/コントローラ**→CSI（プロビジョニング)と、**kubelet**→CSI（マウント)という二方向でCRI/CNIと連携しつつPodのストレージを準備します。OCIとの直接的な関係はありませんが、コンテナ内から見ればOCIイメージ上のアプリがCSIで提供されたストレージを利用するといった形で**最終的に連携**しています。

**実践的な活用例:** 実運用では、クラウド上のブロックストレージを利用したいケースでCSIが活躍します。例えば**AWS EBS CSIドライバー**をクラスタにデプロイしておけば、開発者はPersistentVolumeClaim (PVC)を作成するだけで、自動的に対応するEBSボリュームがプロビジョンされてPodにアタッチされます。オンプレミスでも、CephやNFS用のCSIプラグインを使うことで、ストレージ管理をKubernetes経由で一元化できます。また、CSIスナップショット機能を使ってボリュームのバックアップを取るような発展的な機能も、CSI統一仕様の上で各ベンダーが提供しています。

## CDI (Container Device Interface: コンテナデバイス・インターフェース)

**概要と目的:** CDIは**コンテナランタイムにおける特殊デバイス利用のための標準仕様**です ([cncf-tags/container-device-interface - CDI - GitHub](https://github.com/cncf-tags/container-device-interface#:~:text=CDI%20,a%20device%20as%20a))。コンテナでGPUやFPGA、特殊なネットワークインターフェースなどの**サードパーティ製デバイスを扱う**際、各デバイスごとに個別対応するのは複雑です。CDIはこれを抽象化し、OCI対応のコンテナランタイム（例: containerdやCRI-O）が標準的な方法でデバイスをコンテナに組み込めるようにします ([cncf-tags/container-device-interface - CDI - GitHub](https://github.com/cncf-tags/container-device-interface#:~:text=CDI%20,a%20device%20as%20a))。具体的には、デバイスごとの設定（環境変数やマウントするデバイスファイル等）をまとめた**デバイスプロファイル**を定義し、ランタイムがコンテナ起動時にそれを読み取って設定を反映できるようにします ([cncf-tags/container-device-interface - CDI - GitHub](https://github.com/cncf-tags/container-device-interface#:~:text=CDI%20,a%20device%20as%20a))。目的は**「GPU等の特殊ハードウェアを、プラグインで簡単にコンテナに提供する」**ことにあります。

**Kubernetesにおける役割:** Kubernetesでは、GPUなど特殊デバイスの割り当てに**デバイスプラグイン**機構があります。CDIはこのデバイスプラグイン機構と連携して動作します。例えばNVIDIAのGPUの場合、NVIDIA社提供のデバイスプラグインがNode上でGPUを検出し、Pod要求に応じてその情報を**CDI仕様のデバイスプロファイル**としてコンテナランタイムに渡します ([Container Device Interface Support in the GPU Operator](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/cdi.html#:~:text=Container%20Device%20Interface%20Support%20in,standardizes%20access%20to%20complex))。containerdやCRI-OはCDIサポートにより、そのプロファイルに沿ってコンテナを起動し、GPUデバイスファイルをコンテナ内に正しくマウントしたり必要なドライバをロードしたりします。これにより、Kubernetes上のPodは特別な設定をしなくても**GPUやその他デバイスを利用可能なコンテナ**として起動できます。

**他システムとの関連:** CDIはCRIと密接に関連しています。CRI対応ランタイム（containerdなど）の**更に内部の仕組み**としてCDIが組み込まれており、CRI経由でPod作成要求を受けたときにCDIの情報を考慮してコンテナをセットアップします。OCIランタイム（runcなど）レベルでは、CDIによって生成された設定がコンテナの`config.json`（OCIランタイム仕様の設定ファイル）に反映され、デバイスが追加されます。したがって、**CRI → （CDIを考慮した）コンテナランタイム → OCIランタイム**という流れで連携しています。また、CDIはNRI（後述）とも補完関係にあり、CDIがデバイス固有設定の標準化を提供する一方、NRIはより汎用的な拡張ポイントを提供します。

**実践的な活用例:** 機械学習のワークロードで**GPUを使うPod**をデプロイする場合を考えましょう。まずKubernetesノードにNVIDIAのデバイスプラグインをデプロイすると、ノード上のGPU情報が検出され、リソースとして`nvidia.com/gpu`が使えるようになります。ユーザがそのリソースを要求するPodを作成すると、containerdがPod起動時に**CDI仕様のファイル**からGPUデバイス設定を読み込み、コンテナに必要な`/dev/nvidia0`などのデバイスファイルやドライバ設定を注入します。結果として、Pod内のコンテナはGPUにアクセスでき、TensorFlowなどのアプリケーションがGPUを利用した計算を行えます。同様に、SR-IOV対応ネットワークデバイスやFPGAも、CDI対応プラグインを介してシームレスにコンテナへ提供できます。

## NRI (Node Resource Interface: ノードリソース・インターフェース)

**概要と目的:** NRIは**コンテナランタイムにカスタムな拡張処理を組み込むためのフレームワーク**です ([CRI-O v1.26.0](https://cri-o.github.io/cri-o/v1.26.0.html#:~:text=NRI%20plugins%20can%20register%20to,This))。簡単に言うと、OCI互換のコンテナランタイムに対し、プラグイン的に**「コンテナの詳細設定を動的に書き換える処理」**や**「ライフサイクルイベント時の追加処理」**を挿入できる仕組みです ([CRI-O v1.26.0](https://cri-o.github.io/cri-o/v1.26.0.html#:~:text=NRI%20plugins%20can%20register%20to,This))。たとえば、コンテナ起動直前に特定のcgroup制御を追加したり、コンテナ停止後にリソースのクリーンアップを行ったりするカスタムロジックをプラグインとして実装できます ([CRI-O v1.26.0](https://cri-o.github.io/cri-o/v1.26.0.html#:~:text=NRI%20plugins%20can%20register%20to,This))。NRIの目的は、KubernetesのスケジューラやCRIだけでは細かく制御しきれない**ノード上のリソース管理**や**コンテナ設定の最適化**を、拡張可能にすることです。

**Kubernetesにおける役割:** NRI自体はKubernetesの公式コンポーネントというより、containerdやCRI-Oなど**コンテナランタイム側の拡張ポイント**ですが、結果的にKubernetesの動作に影響を与えます。NRIプラグインはコンテナランタイムに登録され、Podのコンテナが**作成されるタイミング**や**開始されるタイミング**などにフックして呼び出されます ([CRI-O v1.26.0](https://cri-o.github.io/cri-o/v1.26.0.html#:~:text=NRI%20plugins%20can%20register%20to,This))。これを利用して例えば、PodごとにCPUやメモリの割当を微調整したり、NUMAノードへのバインドを自動化したりできます。Kubernetesのスケジューリング決定後、実際にコンテナを起動する段階でNRIプラグインが介入し、**ポリシーに応じた詳細なリソース設定**を適用することで、デフォルトでは実現しにくい最適化を施します。

**他システムとの関連:** NRIはCRIの補助的な位置づけです。CRIが標準APIを提供する一方、NRIは各種ポリシー適用の**カスタムフック**を提供します。NRIプラグインはOCI互換ランタイムで動くため、OCI仕様に準拠したコンテナ設定をプログラム的に書き換えることも可能です ([CRI-O v1.26.0](https://cri-o.github.io/cri-o/v1.26.0.html#:~:text=NRI%20plugins%20can%20register%20to,This))。たとえばCDIが特定デバイスの設定を標準化するのに対し、NRIは**デバイス以外も含めたあらゆるコンテナ設定**（環境変数の挿入やセキュリティ設定の変更など）のフックポイントを提供できます。結果として、**CRI+NRI+OCIランタイム**という形で、KubernetesのPod実行時に高度なカスタマイズ処理が挿入できる仕組みが完成します。

**実践的な活用例:** 金融や通信キャリア向けのワークロードでは、Podごとにきめ細かなリソース管理（例えば**CPUコアのピン留め**や**メモリアロケーション制御**）が求められることがあります。そんな場合、**NRIプラグイン**としてカスタムスケジューリングロジックを実装し、特定のラベルを持つPodについては起動時に自動でそのPodのコンテナを特定のCPUソケットに割り当てる、といった処理を組み込めます。また、将来的にWebAssemblyランタイムをKubernetes上で扱う際など、既存のCRIにはない初期処理をNRIで追加する、といった応用も議論されています ([CRI-O v1.26.0](https://cri-o.github.io/cri-o/v1.26.0.html#:~:text=NRI%20plugins%20can%20register%20to,This))。NRIはまだ新しく発展中の仕組みですが、高度な最適化が必要なシナリオで徐々に利用が進んでいます。

## これらインターフェースの相互関係と全体像

上記の各インターフェースはそれぞれ異なる役割を持ちますが、**Kubernetes上では連携してPodやサービスを支える基盤**を構成しています。大まかな関係性をまとめると次の通りです。

- **OCI**はコンテナの共通フォーマット・実行方法を定める**土台**であり、CRIや各ランタイムがOCI標準のコンテナイメージ・ランタイムを利用することで互換性を維持します ([Open Container Initiative](https://opencontainers.org/#:~:text=The%20Open%20Container%20Initiative%20is,around%20container%20formats%20and%20runtimes))。
- **CRI**はKubernetes (kubelet)とコンテナランタイムを繋ぐ**中核インターフェース**で、OCI準拠の複数ランタイムを差し替え可能にします ([Container Runtime Interface Explained | by David Mosyan - Medium](https://medium.com/@dmosyan/container-runtime-interface-explained-1c3c5af07eaf#:~:text=Medium%20medium,to%20recompile%20the%20cluster%20components))。CRIを軸にして、その下でOCIランタイムによるコンテナ実行が行われ、また周辺のCNI/CSIプラグインを呼び出します。
- **CNI**と**CSI**はそれぞれネットワークとストレージの**プラグインインターフェース**で、CRIと協調してPodにネットワーク接続やボリュームを提供します ([List of CNI plugins used in kubernetes - DevOpsSchool.com](https://www.devopsschool.com/blog/list-of-cni-plugins-used-in-kubernetes/#:~:text=Container%20Network%20Interface%20,uses%20CNI%20plugins%20to)) ([Container Storage Interface: The Foundation of K8s Storage](https://bluexp.netapp.com/blog/cvo-blg-container-storage-interface-the-foundation-of-k8s-storage#:~:text=Container%20Storage%20Interface%3A%20The%20Foundation,CO%29))。これによりネットワーク実装やストレージ実装を環境に合わせて選択できます。
- **SMI**はアプリケーション層（サービスメッシュ）の**統一インターフェース**で、Kubernetes上のサービス間通信を抽象化します。他のインターフェースとはレイヤーが異なり、**ユーザー側の利便性**（サービスメッシュの切替容易さ）を高める役割です ([A standard interface for service meshes on Kubernetes - SMI](https://smi-spec.io/blog/#:~:text=Service%20Mesh%20Interface%20,common%20service%20mesh%20use%20cases))。
- **CDI**と**NRI**はCRI/コンテナランタイムを拡張する新しい仕組みで、**ハードウェア資源**（GPU等）や**リソース管理の高度化**に対応します。CDIは特定デバイス用設定の標準化、NRIは汎用的なカスタム処理のフック提供と、アプローチは異なりますがどちらも**Kubernetesの柔軟性をさらに拡張する**ものです ([cncf-tags/container-device-interface - CDI - GitHub](https://github.com/cncf-tags/container-device-interface#:~:text=CDI%20,a%20device%20as%20a)) ([CRI-O v1.26.0](https://cri-o.github.io/cri-o/v1.26.0.html#:~:text=NRI%20plugins%20can%20register%20to,This))。

すべてを統合すると、**「OCI標準に従ったコンテナイメージ」を**、Kubernetesが **「CRI経由でOCI対応ランタイムに渡し」** てPodとして起動します。その際に **「CNIプラグインでネットワークを付与」** し、必要なら **「CSIプラグインでストレージを接続」** します。さらに特殊な要件があれば **「CDIで特殊デバイスを割り当て」** たり、 **「NRIで追加のリソース調整」** を行います。上位では必要に応じて **「SMI経由でサービスメッシュ制御」** が動作し、アプリ間通信が管理されます。これらがそれぞれ独立したプラグイン可能部品になっているおかげで、Kubernetesは様々な環境やニーズに合わせて柔軟に拡張・適応できているのです。

## まとめ: 実践での活用

初心者から中級者の立場で押さえておきたいポイントとしては、**Kubernetesは単一の巨大なモノリシックシステムではなく、OCI/CRI/CNI/CSI/SMIなど多数の標準仕様に支えられたプラットフォーム**だということです。それぞれのインターフェースを理解すると、例えば「自分のクラスタではDockerではなく別のコンテナランタイムを使いたい」「このクラスタに新しいストレージ機能を追加したい」「GPUや特殊デバイスを使いたい」といった場合に、**どの部分を設定・追加すればよいか**が見えてきます。また、トラブルシューティングの際にも「ネットワーク周りの不具合はCNI設定を確認しよう」「ストレージがマウントできないならCSIドライバのログを見よう」というように、原因を切り分けやすくなります。Kubernetesを実践で使う上でも、ここで紹介したOCI, CRI, CNI, SMI, CSI, CDI, NRIの概念を理解しておくことは、クラスタの構成要素を把握し適切に活用するうえで大いに役立つでしょう。