node-feature-discovery を使って Kubernetes の Node にいろいろ label を付けてみよう

どちらかというとクラスター管理者向け

makocchi
7 min readJul 15, 2020
discovery

Kubernetes は様々な label を使うことで Pod 等の様々なリソースを効率よく管理することが出来ます。

Kubernetes の Node も同様に様々な label を付けることが可能です。利用者からすればリソースを Node に配置する時に、意図した Node に配置したいケースもあると思います。その際に Node に適切な label が設定されていて欲しいですよね。

利用者にとっては、例えば「特定の CPU の命令セットが実行できる Node に Pod を配置したい」なんて要望があるかもしれません(AVX2 や FMA3 等)。もしくは「 CPU の model や stepping を選択して配置したい」なんてケースもあるかもしれません。

Kubernetes はデフォルトでいくつかの labelNode に付与してくれますが、さすがにこのような CPU の細かい情報までは自動で付与してくれません。クラスター管理者が Node をセットアップする際に付与してあげたりしないといけません。管理者側からすると、いちいち物理的な情報を調べて、それを label として付与するのは手間ですよね。

Node feature discovery for Kubernetes

そこで登場するのが Node feature discovery for Kubernetes です(長いので 以下 NFD と略します)。

NFD は Nodeのハードウェア的な情報を discovery して label として付与してくれるやつです(後述しますが、こいつの実力はそれだけではない・・!)

クラスター管理者としては、利用者のニーズにはなるべく応えてあげたいところです。NFD を使うことでその手助けになるのではないでしょうか。

NFD を起動させると下記のような labelNode に付与されることが確認できると思います(後述する仕組みを使った labelも付与されてます)。

sample labels

NFD が discovery できるものは CPU や kernel だけではなく、PCIや USB といった物も対応しています。詳しくは README を御覧ください。

NFD のアーキテクチャ

NFD は nfd-masternfd-worker によって構成されています。 nfd-worker はその名の通り各 Node で動き、discovery を行います。その結果を nfd-master に送信し、 nfd-master は Kubernetes の APIに対して実際の label の更新処理をします。

この nfd-masternfd-worker による役割分担されたアーキテクチャにより、例えば Node の数がすごく多くなったとしても Kubernetes の API に対してリクエストが大量に発生しないような仕組みになっていますね。

nfd-masternfd-worker 間は grpc で通信されている点もモダンな感じでいいですね。

任意の script を実行し、結果を label に付ける

実は NFD には shell や python のような任意の script を実行し、その結果を Nodelabel として付与してくれる便利機能(Feature Detector Hooks)があります。つまり、discovery の仕組みを自作することができるということです。

script を実行し、その出力結果(stdout)を NFD に読み込ませる方式と、ファイルを NFD に読み込ませる方式の 2 つの方法があります。ファイルを読み込ませる場合は別途 cron 等で該当ファイルを定期的に生成するとかしておくといいかもしれませんね。

さっそくやってみよう

例として Node の特定の sysctl の値を label として付与してみましょう。今回は script 方式でいきます。

まずは script を用意する必要があります。例として my-script という名前で作ります。

script は結果を特定の形式で出力する必要があります。とは言ってもすごく単純です。 KEY=VALUE で 1 行ずつ出力するだけです。(ファイルで読み込ませる場合もこの形式です)

sysctl ですので、例えば下記のように出力すればいいことになります。

NFD は上記の結果を読み込むと下記のような label を付与します。

feature.node.kubernetes.io/my-script- という prefix で label が付与されます。script 名も label に含まれることになりますね。

しかしこれも実は上書きして自由に label を生成することができます。先程の sysctl の結果を表示する時に KEY の頭に / を付けると label/ 以下を上書きすることができます。

script の出力結果を上記のように調整すれば、もっとそれっぽい label にすることが可能です。結果として下記のような label になります。

feature.node.kubernetes.io自体も上書きすることが可能です。 makocchi.dev/KEY=VALUE のように出力することで、そのまま label として付与されます。

如何に分かりやすい label にするか、管理者の腕の見せ所ですね。

参考までに sysctl の script を貼り付けておきます。

ちなみにこの script は /host-proc が存在することが前提になっています。理由としては nfd-worker が DaemonSet で動くことを想定しており、 nfd-workerPodに対して host 側の /proc を mount して参照できるようにした為です。

nfd-worker/etc/kubernetes/node-feature-discovery/source.d/ に配置された script を実行します。 nfd-workerPod内に script を配置してもいいですが、わざわざ image を作るのは面倒くさいですよね。 Node 側の該当ディレクトリを nfd-worker に mount して見せてあげる方がいいでしょう。もしくは ConfigMapを使って Pod 内に配置する方法でもいいと思います。

ちなみに script ではなくファイルを読み込ませて label を生成する場合には /etc/kubernetes/node-feature-discovery/features.d/に配置することで読み込まれます。

まとめ

NFD の機能を紹介させて頂きました。クラスター管理者からすればこういった便利なものはどんどん入れていきたいですね。でもこのような system 側で動くコンテナを無闇に動かすと、利用者が使うことができるリソースが多少減ることにはなるので、やりすぎに注意です。

ここでは紹介しませんでしたが、discovery された値に様々なルールを適用して label を付けるといった複雑なこともできるようになっています。(例えば kernel module A と B が読み込まれていたら my.kernel.feature=true にする等)

NFD は実は結構昔からあったんですね(v0.1.0 の release が 2016年)・・知らなった。

みなさんがどのような discovery を作るのか、是非気になりますのでこんなの作ったよ!とかあれば是非教えてくださいね。

おまけ

cpuinfo を discovery する scriptも置いておきます。

/proc/cpuinfo/host-proc/cpuinfo として見せてあげてください。

--

--

makocchi

Makoto Hasegawa | kubernetes | CKA(#CKA-1700–0150–0100) | CKAD(CKAD-1800–0005–0100) | docker | container | OpenStack