Kubernetesクラスターが崩壊したので作りなおした

created at
updated at
technology Kubernetes Flatcar_Container_Linux

我が家では自宅サーバー上でKubernetesクラスターを運用しています。
先日、クラスターでCNIとして使っているCiliumを更新したところ盛大にクラスターがおかしくなり、Kubernetes自体の設定をいじってどうにかしていたのですが、コントロールプレーンのホストが再起動したところ完全におかしくなって崩壊しました。
ログを眺めたところ、APIサーバーに繋がらないというエラーが出まくっていてめちゃくちゃになってました。しかもログが大量に出て様々なリソースがめちゃくちゃになったせいでetcdの代わりに使っているkineが暴走してしまい、ホスト自体の挙動が不安定な状態になっていて、手のつけようがなくなっていました。
結局土日を丸々使ってクラスターの再構築をするはめになりました。

Fedoraから撤退
今までのKubernetesクラスターでは仮想化基盤上にホストOSを用意し、その中でk0sというKubernetesのディストリを動かしていました。
仮想化基盤にはFedora IoT、ホストOSにはFedora CoreOSを採用し、とくにホストOS側は自動更新+自動再起動で常に最新の環境を保つような仕組みになっていました。
しかしこいつらが最悪で、とにかく更新の度に様々な物が壊れてずっと悩まされていました。
Fedora IoTFedora CoreOSもベースとなっているのはFedora Linuxですが、rpm-ostreeを採用しているという大きな違いがあります。
rpm-ostreeはOSTreeとRPMを融合したもので、あらゆるシステムファイルをGitのようにバージョン管理し、システムの更新を追跡したりコマンド1つでロールバックできる技術です。
これだけ聞けばまるで夢のようなシステムですが、実際はまったくの役立たずです。
まずシステムファイルをGitのようにオブジェクト単位で管理するのでファイル数が大幅に増えます。なのにミラーサーバーが貧弱なので更新の取得が大変遅いです。しかもかなりの確率で取得に失敗します。
そしてパッケージの依存解決ロジックの出来が悪く、たまに依存の解決に失敗して更新できなくなります。
ていうかパッケージングの質が悪くてぶっ壊れたパッケージが降ってきたりもします。
そのため、Fedora IoTFedora CoreOSも常に何かしらの機能が動かない状態で騙し騙し使っていました。
しかし今回クラスターが崩壊して作りなおしが必要になったので、これを期に撤退する事にしました。

Flatcar Container Linuxの導入
今までのクラスターでは仮想化基盤を導入していましたが、結局1つのゲストしか動かすものがなかったためにただオーバーヘッドを増やしているだけの状態でした。
そのため、新たなクラスターでは仮想化基盤は導入せず、サーバーに対して直接ホストOSを導入する事にしました。
ホストOSにはFlatcar Container Linuxを選定しました。
Flatcar Container Linuxは、その名の通りコンテナを動かすのに特化したLinuxディストリです。そしてこのLinuxディストリはFedora CoreOSの兄弟でもあります。
もともと、CoreOS Linuxというディストリがありました。このディストリはChrome OSをベースに開発され、/usr は読み込み専用・OS自体の更新は自動更新といったコンテナを動かすためだけに特化した尖った特徴を持っていました。その後、Container Linuxに名称が代わり、そして最終的にRedHatに買収されました。
買収後、RedHatが開発していた同じくコンテナを動かすのに特化したAtomic Hostと統合し、Fedora CoreOSとなりました。
しかし、実は買収時のタイミングでContainer Linuxのフォークが生まれていました。それがFlatcar Container Linuxです。
Flatcar Container LinuxFedora CoreOSと違い、rpm-ostreeを採用していません。なので、Fedora IoTFedora CoreOSで悩まされていたrpm-ostree由来の各種問題から開放されました。
また、最近Clevisのサポートが入ったため、LUKSによるディスク暗号化で面倒なポイントである起動時のアンロック処理を簡単に実現できるようになりました。
そのため、導入の障壁がなくなり、晴れてホストOSとして選定されました。
なおFlatcar Container LinuxFedora CoreOSと同じくIgnitionを使ってプロビジョニングするため、引き続きGitHub - rokoucha/ignitron: Ignition filesにて我が家のプロビジョニング構成を公開しています。参考にしてみてください。

クラスター復旧
さてクラスターの復旧ですが、サーバーに新ホストOSを導入・Kubernetesセットアップ・アプリケーション構築・データ復旧の順に進めました。
ホストOSについては上記の通りFlatcar Container Linuxを、Kubernetesは今までのクラスターと同じくk0sを選択しました。
ノードは2台構成とし、片方はコントロールプレーン+ワーカー、もう片方はワーカーとしました。
CNIにはCiliumを、CSIにはsynology-csiを、それぞれ前回から引き続き採用しています。
k0sの設定やクラスターで動く各種リソースの定義は GitHub - rokoucha/materia: Appellatur omnes res quae in res corporeas componi possunt で管理していたため、クラスター復旧の際もこの内容をそのまま使いました。
先にCilium1Password OperatorArgo CDをセットアップし、その後はArgo CDを使ってアプリケーション群を再構築しました。
また永続化すべきデータは全てsynology-csiを使ってNASに保存していたため、新たにPVを作成→古いPVの内容を新しいPVにコピー→アプリケーションを起動して動作確認という流れでデータロストなくクラスターを再構築することができました。
ただし、プロトコルとしてiSCSIを選んでいたため、古いPVから新しいPVへのデータ移行はかなり苦労しました。Kubernetesの仕組みで転送する方法が思い付かなかったため、適当なホストで新旧それぞれのLUNをiSCSIでマウントして手動でコピーを行い、その後古いLUNとiSCSIターゲットを削除するという大変手間のかかる方法を取りました。

おわりに
もう二度とやりたくないので自宅サーバー撤退したいです