Raspberry Pi で Kubernetes を使う場合の Tips

サーバー
スポンサーリンク

Raspberry Pi で Kubernetes を使う場合に知っておくと役立つ情報を紹介したいと思います.

スポンサーリンク

使用機材

今だと,普通に使うなら使用機材は次の二択となります.

  • Raspberry Pi 4 Model B
  • Raspberry Pi Compute Module 4

メモリ

4GB 以上がオススメです.

メモリは 2GB でも動きはすると思いますが,Python プログラムを動かす Pod を1つ配置しているノードでも,下記のように 2GB 近く消費するためです.

沢山 Pod を配置しているから,と思われるかもですが動いている Pod はこんな感じで,必要最低限です.

「unit-cooler-actuator-*」は IO-Link 通信および GPIO 制御を行う Python プログラムを動かしているものです.「node-exporter-*」と「promtail-*」はそれぞれ Prometheus によるシステム監視と Promtail によるログ収集を行うものです.無くても良いとは思いますが,実用性を考えると配置したくなると思います.

SD カード容量

必要用容量の観点から 16GB 以上の容量を準備するのがオススメです.

8GB でもなんとか動かせるのですが,実際に 8GB で運用すると下記のようにディスクの使用量が 95% を越えてくるので(/dev/mmcblk0p2 の行),結構厳しいです.ノードの DiskPressure が True になって,Pod が意図通りに配置されなくなることが起りがちです.

小さい容量のデバイスを使う場合の対処

しかし,少ない容量のデバイスを使わざるを得ない場合もあると思います.その場合,containerd の設定ファイル /etc/containerd/config.toml において, discard_unpacked_layers=true を指定すると,ディスク消費を大きく抑制することができます.

Can I reduce the size of images in persistent storage (/var/lib/containerd)? · containerd/containerd · Discussion #6295
It turns out that after moving from docker to containerd in Kubernetes the persistent storage size increases by several ...

また,問題の根本解決にはなりませんが,/var/lib/kubelet/config.yaml の末尾に下記を追記することで,DiskPressure の閾値を変更するのも助けになるかもしれません.

寿命の観点

これは余談です.実用性という面では SD カードの寿命も気になると思います.

実使用における SD カードの寿命を見積もるのは色々と難しいのですが,参考になりそうな資料として下記があります.

不揮発性メモリの最適評価へ向けた取り組み[キャッシュ]

この資料の p.10 には 8GB の SD カードに対してどのくらい書き込みを行うとエラーが発生したか示されています.メーカや書き込みパターンによって幅があるものの,ざっくり20~90TB 程度で寿命に達するようです.

一方,約1年 Kubernetes のノードとして運用したノードの書き込み量を調べてみたところ,ざっくり 30GB 程度でした.

従って,寿命観点では 8GB でも問題はなさそうです.

また,効果のほどは確認できていませんが,/etc/sysctl.conf に下記のように設定して,書き込み頻度やを押さえ手おくと良いかもしれないです.

定性的には,WAF(Write Amplification Factor) を下げられると思われるためです.

ちなみに,eMMC 容量が 8GB の Raspberry Pi Compute Module 4 で,上記の設定の元で 1年運用した後でも,Pre-end of life information(EXT_CSD_PRE_EOL_INFO) は「0x01: 定常状態(問題無し)」でした.

マルチプラットフォームイメージ

慣れてくると,Raspberry Pi に配置するイメージを,普段使っている PC でビルドしたくなってくると思います.そんなとき便利なのが buildx です.これを使うと,複数のアーキテクチャで動作する,イメージを簡単に作成できます.

buildx の使い方

導入は簡単で,下記のようにするだけです.

あとは,次のようにすれば,マルチプラットフォームイメージをビルドして,レジストリに登録できます.NAMEREGISTRY は適当に置き換えてください.

レジストリがプライベートCA のルート証明書使っていて TLS 周りのトラブルが出る場合は,次の内容で buildkitd.toml というファイルを作成し,「docker buildx build」する際に --config buildkitd.toml オプションを付与すればエラーが出なくなると思います.

GitLab CI とかで,イメージを自動的に作りたい場合,次のような Dockerfile を作って,ビルド用のイメージを用意しておくと良いと思います.

プラットフォーム毎の Dockerfile カスタマイズ

マルチプラットフォーム対応のイメージが作れるようになると,次にプラットフォーム毎に Dockerfile の内容を切り替えたくなってくると思います.例えば,Rapsberry Pi で動かすイメージには python3-rpi.gpi をインストールしたいけど,それ以外ではインストールしたくない,とか.

こういった場合に使えるのが TARGETPLATFORM です.Dockerfile にARG TARGETPLATFORM と記述すると,ビルドしているアーキテークチャの種類が $TARGETPLATFORM で参照できるようになります.

例えば,先ほどの python3-rpi.gpi のケースは Dockerfile に次のようにして対応できます.

GPIO,SPI通信,UART通信

Raspberry Pi を使うと言うことは,各種 I/O を使ってなにか制御したいケースが多いと思います.そういった場合は,ホスト側の次のデバイスファイルを Pod にマウントしてやれば OK です.

  • /dev/gpiomem
  • /dev/spidev0.0
  • /dev/ttyAMA0

具体的には,Kubernetes 向けの Deployment の設定ファイルに次のように記載します.「privileged: true」がないとパーミッションエラーになります.

ログ収集

せっかく Kubernetes を導入するので,問題発生時も Raspberry Pi にログインせずに,動作ログ等を確認できるようにしておくと便利です.私は,Promtail + Grafana Loki の組み合わせを使っていますが,何でも良いと思います.

Promtail では,下記のような設定を使っています.この設定では,namespace が bot,panel,hems,sensor のいずれかの Pod のログを http://proxy.green-rabbit.net:3100/loki/api/v1/push に送り付けるようになっています.

この設定さえしておけば,何か問題が起こった際は,下記のように直感的な画面を使ってささっとログが辿れます.

コメント