node-feature-discovery を使って Kubernetes の Node にいろいろ label を付けてみよう
Kubernetes は様々な label
を使うことで Pod
等の様々なリソースを効率よく管理することが出来ます。
Kubernetes の Node
も同様に様々な label
を付けることが可能です。利用者からすればリソースを Node
に配置する時に、意図した Node
に配置したいケースもあると思います。その際に Node
に適切な label
が設定されていて欲しいですよね。
利用者にとっては、例えば「特定の CPU の命令セットが実行できる Node に Pod を配置したい」なんて要望があるかもしれません(AVX2 や FMA3 等)。もしくは「 CPU の model や stepping を選択して配置したい」なんてケースもあるかもしれません。
Kubernetes はデフォルトでいくつかの label
を Node
に付与してくれますが、さすがにこのような CPU の細かい情報までは自動で付与してくれません。クラスター管理者が Node
をセットアップする際に付与してあげたりしないといけません。管理者側からすると、いちいち物理的な情報を調べて、それを label
として付与するのは手間ですよね。
Node feature discovery for Kubernetes
そこで登場するのが Node feature discovery for Kubernetes です(長いので 以下 NFD と略します)。
NFD は Node
のハードウェア的な情報を discovery して label
として付与してくれるやつです(後述しますが、こいつの実力はそれだけではない・・!)
クラスター管理者としては、利用者のニーズにはなるべく応えてあげたいところです。NFD を使うことでその手助けになるのではないでしょうか。
NFD を起動させると下記のような label
が Node
に付与されることが確認できると思います(後述する仕組みを使った label
も付与されてます)。
NFD が discovery できるものは CPU や kernel だけではなく、PCIや USB といった物も対応しています。詳しくは README を御覧ください。
NFD のアーキテクチャ
NFD は nfd-master
と nfd-worker
によって構成されています。 nfd-worker
はその名の通り各 Node
で動き、discovery を行います。その結果を nfd-master
に送信し、 nfd-master
は Kubernetes の APIに対して実際の label
の更新処理をします。
この nfd-master
と nfd-worker
による役割分担されたアーキテクチャにより、例えば Node
の数がすごく多くなったとしても Kubernetes の API に対してリクエストが大量に発生しないような仕組みになっていますね。
nfd-master
と nfd-worker
間は grpc で通信されている点もモダンな感じでいいですね。
任意の script を実行し、結果を label に付ける
実は NFD には shell や python のような任意の script を実行し、その結果を Node
の label
として付与してくれる便利機能(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-worker
の Pod
に対して host 側の /proc
を mount して参照できるようにした為です。
nfd-worker
は /etc/kubernetes/node-feature-discovery/source.d/
に配置された script を実行します。 nfd-worker
の Pod
内に 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
として見せてあげてください。