葬送のフリーレンが2クール連続で歓喜しています。Pluginライブラリを作って公開したので紹介します。リポジトリとCrates.iorscniという名前でGithub及びCrates.ioに公開しています。ご興味のある方は使ってみてください。バグ報告お待ちしています。crateがなかったからです。Rustの実装もあるにはあるのですが、2年ほど前に開発が止まってしまっていました。Pluginを実装していて、このプロジェクトのためにしかたなく自作することにしました。最初はcrateとして公開することはあまり考えていませんでしたが、複数プロジェクトに分けて開発しており、外部crateとして切り出してcrates.ioから利用できたほうが都合がよかったので公開することにしました。CNIについては知っていて、rscniの使い方をさくっと知りたい方はRsCNIに飛んでください。Interfaceの略でコンテナのネットワークを設定するプラグインのための仕様とそのライブラリです。window)に情報がまとまっています。CNIはあくまで仕様なので実際のCNIプラグインの実装は各プロジェクトによって様々です。CNIが共通のインターフェースを提供することで、利用者は自身のユースケースに一番合ったCNIプラグインの実装を利用、もしくは自身で実装することができます。代表的なCNIプラグインの実装は以下のようなものがあります。本記事では現在最も一般的なCNIプラグインの利用先であろうKubernetesでの利用を前提として話を進めます。実行形態CNIプラグインは実行可能なバイナリファイルとして各Kubernetesノードに配置されます。通常、各種プラグインは/opt/cni/binに配置されます。kindで作成したクラスターのノードには以下のように配置されています。ptp12345678これらのプラグインをどのように呼び出せばよいかを記述したファイルが同様に/etc/cni/net.dに配置されます。kindの例では以下のようなファイルが配置されていました。]}123456789101112131415161718192021222324252627282930313233Pod作成時にこの設定を見てkubeletがCNIプラグインを実行します。以上のように実行可能なバイナリを配置し、設定に記述することで任意のCNIプラグインを実行させることができます。window)に定義されています。いくつかのバージョンがあり、現在リリースされている最新バージョンはv1.0.0です。詳細な仕様は原文を参照していただくとして、ここでは簡単に説明します。この仕様書には以下のことが定義されています。ネットワーク設定ファイルシステム管理者が定義するネットワーク設定ファイルは上述した/etc/cni/net.dに配置されたファイルです。window)に詳細が記述されています。plugins以下に実行したいプラグインの設定を定義します。window)を参照してください。CNIプラグインはその役割から以下の2つのカテゴリに分けられます。Interfaceコンテナ内のネットワークインターフェスを作成、設定するChainedすでに作成されたネットワークインターフェースなどに対して任意の操作を行うこの2種類のプラグインをつなげて実行することでコンテナのネットワークを設定していきます。Chainingです。パラメーターCNIプラグインの実行時パラメーターは環境変数として渡されます。以下のキーで値を取得して実行時に値を利用します。CNI_COMMANDCNI_CONTAINERIDCNI_NETNSCNI_IFNAMECNI_ARGSCNI_PATHその他に、任意のデータを標準入力からJSON形式で受け取ります。Versionの4つのコマンドが定義されています。どのコマンドを実行するかはCNI_COMMAND環境変数から取得します。window)が利用できます。Specificationと同一リポジトリで開発されているライブラリです。cmdCheck)を渡すことでCNIプラグインとして振る舞えるように実装します。string)1詳しくは以下を参照してください。window)rscniはこのインターフェースを参考にして同じ書き味で書けるように実装しました。以下がrscniの処理のエントリーポイントとなる構造体です。Dispatcher,}12345678この構造体に以下のように定義されたCmdFn型を満たす関数を渡します。Error>;1全体像は以下のような感じです。使ってみる参考実装として、rscni-debugという与えられた引数をファイルに出力するだけのCNIプラグインをrscniを使って実装しました。window)ところどころ省略していますが、このような形で書くことができます。})}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071では動かしてみます。examples/にMakefileを用意していますので以下のように試すことができます。ここではkindでKubernetesクラスターを作成して、ノード上にビルドしたrscni-debugとそれを実行するように変更した設定ファイルをコピーしています。{"cniVersion":"0.3.1","name":"kindnet","type":"rscni-debug","prevResult":{"interfaces":[{"name":"veth3e00fda7","mac":"de:ba:bf:29:5a:80"},{"name":"eth0","mac":"fa:6f:76:59:25:82","sandbox":"/var/run/netns/cni-8e9dfbc7-eaff-12a8-925e-4b280eb12d67"}],"ips":[{"interface":1,"address":"10.244.0.3/24","gateway":"10.244.0.1"}],"routes":[{"dst":"0.0.0.0/0"}],"dns":{}},"cniOutput":"/tmp/cni"}--------------------1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556作成したクラスター上Podが作成されると、このようにファイルが作成され、中身に呼び出し時の引数の値を出力していることがわかります。まとめrscniというRustのCNIプラグイン開発用ライブラリを作成して公開しました。Go言語のライブラリを参考にして実装しました。ライブラリとして使えるようになったので個人的に使っていこうと思います。RustでCNIプラグインを実装することはほぼないと思いますが、使ってみてください。