自宅Kubernetesを本格運用するためのツールとノウハウ
Kubernetesを自宅で試してみようとRaspberry PiやVMを使い、苦労してKubernetesクラスタを作り上げたものの、実際にクラスタを立ててみてどのように運用していけばいいか迷ったり、作ったはいいけれど全く面白さを感じられず、「Docker Composeで十分だったかも...」と後悔したりしている方は多いのではないでしょうか。
そこで、私が個人的に自宅クラスタの運用に利用しているツールやノウハウを各レイヤ(物理層〜アプリ層)ごとに広く浅く紹介します。自分の環境や興味に合わせて、気になったところから読み進めていただければと思います。
ホストOSと基盤ソフトウェア
前述の通り、私のKubernetesクラスタは一つのPCの中でVMを起動してそれらをKubernetesノードとして利用しています。この項では、VMを起動するホストOSの部分について紹介します。
また、ここからは対抗する技術がある場合に🆚で紹介しています。
物理マシン: 自作
友人から元々NAS向けに作られたマシンを買い取りメインのサーバーとして運用しています。
コンポーネント | スペック | 備考 |
---|---|---|
CPU | AMD Ryzen 5 5600G | 今の所必要十分 |
メモリ | 64GB | 128GBにすれば良かった |
SSD | M.2 2TB × 2 | OSとキャッシュ用 |
HDD | 8TB × 8 | ストレージ用 |
GPU | RTX A5000 | AI用に後から追加 |
NIC | ASUSTek XG-C100C V2 | 最近カーネルにドライバ入った |
🆚 Raspberry Pi
Raspberry PiでKubernetesクラスタを組むのも良い選択だと思いますが、アーキテクチャがARMであることと、SDカードではディスクI/Oが遅すぎて現実的ではない点に注意が必要です。市販のキットを買って3段重ねにするのもKubernetesの面白さを感じられて楽しいと思います。
ノード構成: 物理シングル * VM複数ノード
物理マシンを複数保有していないため、ホストをVMで区切り3ノードにしています。物理マシンが1つしかなくとも、複数のVMで複数に分割することで下記のようなメリットを享受することができます。
- あるVMのメンテナンス時に他のVMへワークロードを移動させダウンタイムを削減できる
- イメージを丸ごとバックアップすれば良いのでバックアップ戦略が簡略化できる
- より本番環境に近い構成となり実運用のノウハウを得やすい
私のクラスタでは下記のように役割を分担しています。
- aki0: コントロールプレーン + 通常のワークロード
- aki1: USBを必要とするワークロード + 通常のワークロード
- aki2: GPUを必要とするワークロード + 通常のワークロード
USBやGPUといったデバイスを元にホストを分けておくことで、デバイスの抜き差しやドライバの更新といった場面で通常のワークロードを別のノードに逃し、作業影響を受けにくくすることができます。Kubernetesの強みですね。
🆚 シングルノード
1つの物理マシンしか所有していない場合やリソースに限りがある場合はシングルノードにすることも可能ですが、下記の点からおすすめしません。
- Kubernetesのアップグレード時に必ず全てのノードを落とさないといけない
- VMのようにイメージだけバックアップすることができずバックアップ戦略が複雑になる
- 将来的なスケールアウトがVM構成より難しくなる場合がある
管理が楽だったり、リソースを少なく保てるなどメリットも存在しますが、運用という観点ではVM単位で分けた方がKubernetesの強みを発揮できます。
🆚 物理複数 * VM複数ノード
これが一番理想です。ホストをVMで区切る手法では、VM内のメンテナンスはダウンタイムを最小限にすることが可能な一方、ホストの更新時には全てのVMを再起動させなければなりません。ハードウェアの故障にも弱いです。
物理マシンが複数あれば、一つのマシンが故障したりメンテナンスインしたとしても、他のマシンにワークロードを移すことができ、障害やメンテナンスに強いクラスタを作ることができます。
Arch Linux
OS: btw. ホストOSとしてArch Linuxを採用しています。ホストに任せることを極力減らすことができればArch Linuxであってもそうそう壊れることはありませんが、ローリングリリースでカーネルのアップデートも頻繁に行われるためその度に再起動が必要になります。
正直ホストOS向きではありませんが、全てを自分の手でコントロールできるので理解が深まりより堅牢なシステムにしやすいと採用しています。
Proxmox
🆚 WebUIを用いてVMを建てることができるLinuxをベースとしたハイパーバイザです。CephのサポートもあるのでKubernetesとの親和性も良さそうに見えます。私は全てのソフトウェアをKubernetesに押し込んでしまいVMが欲しいタイミングが無くなってしまいましたが、一般的にはProxmoxを使った方が選択肢の幅が広がり楽しいと思います。
incus
仮想化 LXDのフォークです。LXDやIncusと言うとコンテナ技術関連のイメージがありますが、実はこれらはQemuを用いたVMモードを持っており、ホストOSと独立したカーネルをもつ仮想マシンとしても利用可能です。従来のVMで面倒だったインストール作業が不要で、シェルへのアクセスがエージェントを通して行えるため、Spiceや外部モニタを必要としない点が魅力的です。
libvirt
, Proxmox
🆚 incusを利用する前は libvirt
を使っていましたが、 virt-manager
は使うOSがLinuxに限定されがちですし、Spiceを利用した画面ベースの操作を行わなければならず、仮想マシンの運用が面倒でした。
直近でVMを用いたノードを構築するのであれば、前述したIncusを使うか、WebベースのUIを持ったProxmoxがおすすめです。
bcachefs
RAID: 去年カーネルにマージされた新しいFSです。zfs-dkms
がたびたびArchを破壊していたため、カーネルに含まれているので使いやすいなと試してみることにしました。
改善は続いていますがまだ安定性に難があります。頻繁にカーネルログにジャーナルスタックログを吐き出しますし、あるタイミングで動作を停止してしまうこともあります。KubernetesのPVの払い出し元として利用していましたが、あまりに不安定なため直接の利用を取りやめました。今はスナップショット・バックアップ用に利用しています。
興味がある方は下の記事も見てみてください。
ZFS
🆚 ZFSは現時点で安定性が高く、本番稼働実績も豊富なRAID用のソフトウェアです。多くの場合、これが第一候補になるでしょう。ブロックサイズが異なるデバイスをRAIDしたかったり、CDDLライセンス周りのイザコザが気に入らない人はbtrfsやbcachefsを使うと気持ちが良いかもしれません。
NFS
ファイル共有: KubernetesでストレージをPersistent Volumeとして払い出し予定であればNFSが一番手軽です。性能や可用性を本格的に追求するならCephなど他の選択肢も検討可能です。
rsync + bcachefs snapshot
バックアップ戦略: Kubernetesクラスタを運用する中で、クラスタの状態とアプリケーションが作成したデータの二つは必ずバックアップをとっておく必要があります。ディスクの破損以外にオペレーションミスによるクラスタの破壊もあり得るので、スナップショットも撮っておくとより安心です。
私はincusのVMのディスクイメージ(=クラスタの状態)とPersistent Volumeとして払い出しているディレクトリ(=アプリケーションが作成したデータ)の二つをrsyncで24時間おきにBcachefsへコピーしその上でそのディレクトリをスナップショットとして保存しています。
Bcachefs以外にもスナップショット機能を有するファイルシステムはいくつかあります。どのような方法でも構いませんが、定期的にバックアップをとっておくのがおすすめです。事故は起こります。
ゲストOS
incus上で動作するゲストOSは3台のUbuntu Minimalで動作しています。
Ubuntu Minimal
ゲストOS: ゲストOSにはUbuntuを採用しています。Kubeadmの推奨OSです。
🆚 その他のOS
好きなOSを利用可能です。kubeadmを利用する場合は公式ページに対応OSが書かれています。 kubeadm
対応OSならそれほど特別考える必要はないと思います。
kubeadm
ディストリビューション: Kubernetes公式のクラスタ立ち上げツールです。 microk8s
などと比べるとやや難易度は上がりますが、公式ページのマニュアルに従って操作をしていけば問題ないはずです。
microk8s
🆚 利用経験がないため詳細は省きますが、単一ノードやリソースの限られた状況で利用されやすい印象があります。シンプルで初心者でも扱いやすいですが、便利さがKubernetesの奥深い部分を隠してしまうので学習を目的とするのであれば kubeadm
の方がおすすめかな?と思います。
cri-o
コンテナランタイム: Kubernetes向けに設計された軽量のコンテナランタイムです。リリースの間隔がKubernetesのバージョンと同期しているのでアップデートが楽になります。
docker
, containerd
🆚 好みの問題ですが、特にDocker環境との同居などなどを考えていないのであれば cri-o
が無難です。GPUパススルーなど高度な機能も cri-o
で十分利用できます。
NVIDIA Container Toolkit & k8s-device-plugin
GPUツール: Kubernetesの中でGPUを使えるようにするツールキットです。詳細は省きますが、Kubernetesの中でGPUも扱えます。
クラスタ内
クラスタ内の技術について記載します。ここからは既設のクラスタでも導入ができる技術が出てきます。
cilium
CNI: 一択です。eBPFというイケてる技術を用いています。特に設定不要で、Helmコマンド叩くだけでインストールが完了しノード同士が通信できるようになります。Google CloudのKubernetes Engineも新しいDataplane V2としてこれを採用していますね。
また、CiliumをCNIとして紹介していますが、Ingress相当のL7ロードバランシング機能や、「Hubble」というトラフィック可視化ツールも搭載されており、Kubernetesのネットワーク周りに一通りの選択肢を与えてくれるソフトウェアでもあります。
Calico
Flannel
🆚 昔から広く使われているCNIにはCalicoやFlannelがありますが、設定が複雑気味でクラスタ構成に合わせて細かな調整が必要になるケースがあります。新規で導入するのであれば、よりシンプルかつ機能豊富なCiliumを推奨します。
Flux V2
GitOps: GitOpsとは、KubernetesのリソースファイルをGitリポジトリを用いて管理する手法です。CI/CDのKubernetes版といった感じでしょうか。
これを設定しないと永遠にローカルマシンから kubectl apply -f ./resources.yaml
とコマンドを入力し続けることになります。手間になる上、バージョン管理やバックアップも別途行わなければいけないためGitOpsの導入をお勧めします。GitOpsを利用すればHelmやKustomizationを使ったデプロイもバッチリ自動化できます。
私はGitOpsにFlux V2というツールを導入しています。導入が簡単でメンテナンスも安定しており、仕組みもシンプルでわかりやすいのが利点です。下のスクリーンショットのように構成されたGitHubリポジトリにPushすると、自動的に cloudflared
ディレクトリ配下を kustomization.yaml
を起点にクラスタに反映してくれます。
ArgoCD
🆚 GitOpsの文脈ではFluxよりもArgoCDがよく登場するかもしれませんが、これらの選択は好みによるところが大きいです。ArgoCDは綺麗なWebUIを備えていて、ブラウザ上でワークロードを操作できる便利さがありますが、FluxはWebUIはなくコマンドも最低限と薄いソフトウェアになっています。
GUIベースを好む場合ならArgoCDも良い選択になると思います。
Grafana Cloud
監視基盤: クラスタの状態やログの収集にはGrafana Cloudを利用しています。Grafanaをオンプレで建てるのも通ですが、障害時にGrafanaごと落ちてしまう可能性も考え、ここはクラウドサービスを利用しています。設定はGrafana CloudのKubernetes Integrationの通りに行いました。
監視基盤がなくともKubernetesは動作しますが、実務ではほぼ必須と言えるくらいに一緒に取り入れられています。アラートやログの閲覧がかなり楽になりますし、そして何より豪華なメトリクスの画面を眺めて気持ち良くなることができます。
アラートも思い通りに設定することができます。ログやメトリクスベースで設定ができるので、クラスタ内で動作するアプリケーションのエラーに素早く気がつくことができます。通知先も、メールやSlack、Discordなど幅広く選べるのが便利です。私の場合はDiscordに通知設定をしています。
k9s
クラスタの操作: Kubernetesクラスタの状態をターミナル上で視覚的に確認・操作できるCLIツールです。シンプルなインターフェースでリアルタイムにPodやDeployment、ノードの情報を把握でき、慣れるとショートカットキーを用いた素早い操作ができます。
特に自宅クラスタのように頻繁に状態を確認したり、トラブルシューティングを行う場面では非常に便利です。SSH越しでも快適に動作するため非常に便利です。簡単なリソースの編集機能もあり便利に使えます。(気をつけないとGitOpsに元に戻されてしまいますが...)
Lens
🆚 Lensもk9sに似た管理ツールですが、コンソールベースではなくGUIベースのものになっています。クラスタの状態をグラフィカルに表示できるので、マウス中心のGUI操作の方が好みという方はLensの方が使いやすく感じるかもしれません。
Cloudflared
サービスの公開: クラスタ内のサービスをWeb上に公開するためにCloudflareのZero Trust Tunnelを利用しています。cloudflared
をクラスタ内にデプロイしておき、Cloudflareのページからクラスタ内で解決可能なアドレスを特定のドメインで公開するように設定すると、それだけでサービスを外部公開できます。
証明書も自動で有効になりますし、個人だけで利用したいソフトウェアにはGoogleアカウント認証をつけることができるなど、セキュリティ周りでも安心できます。
🆚 固定IPとポート解放
Cloudflare特有の制限や速度が気になる場合は固定IPとポート解放を行い直接クラスタと通信する方法もあります。
以前はクラスタの外部にリバースプロキシとしてNginxなどを別途建てる必要がありましたが、CiliumをCNIとして採用すれば、各ノードの特定ポート宛てのトラフィックをクラスタ内の適切なサービスへ直接ルーティングできるIngress Controller機能を利用できます。cert-manager
と組み合わせることでHTTPS証明書の自動取得や管理も可能になります。
nfs-subdir-external-provisioner
ストレージの配布: Kubernetesを利用する時に障壁になりやすいPVの作成ですが、NFSを利用している場合はサブディレクトリを切る形でPVを作成してくれる nfs-subdir-external-provisioner
というツールがKubernetes-sigsで提供されています。PVをシェルスクリプトで大量に作っていたあの頃の自分に教えてあげたいツールNo.1です。
Rook Ceph
🆚 NFSベースの簡易的なプロビジョナーに対して Rook Ceph
という分散型のストレージシステムも利用できます。高い可用性を持ちますが、複雑で自宅レベルのクラスタだとややオーバーヘッドが大きいかなと思います。
Google Cloud Artifact Registory
イメージレジストリ: 自作のソフトウェアをクラスタで運用したい時、KubernetesがイメージをPullできるようにする必要があります。
Docker Composeとは異なり、Kubernetesはソースコードからのビルドシステムを同梱していません。そのため、Kubernetesに自作のソフトウェアを載せるにはイメージを作りどこかに保存しなければいけません。
オープンソースなソフトウェアであれば公開リポジトリが利用できますので、Docker Hubなどが利用可能です。一方でイメージをクローズドにしておきたい場合は保存先を選びます。Docker Hubは無料枠が1リポジトリしかありません。
そこで、私はGoogle CloudのArtifact Registoryを利用しています。単純に仕事で利用機会が多いことから採用しました。料金面が気になる方もいらっしゃるかもしれませんが、合計2GB程度のイメージを東京リージョンに保存して2025年2月は24円でした。(Cloud Storageは別の用途で利用しています。)
私はArtifact Registoryを利用していますが、Kubernetes(正確にはコンテナランタイム)がアクセス可能であればどのレジストリを利用してもOKです。
Harbor
🆚 クラウドの利用を避けたい場合、Harborが選択肢に上がってくるかと思います。CNCF GraduatedなOSSのイメージレジストリで、Kubernetesクラスタ内でイメージを保管することができます。こちらもHelmチャートで簡単に導入することができます。
動作しているアプリケーション
アプリケーションはこの記事の範疇外ですが、簡単に二つほど紹介させていただきます。
Concrnt
SNS: Concrnt(コンカレント)は分散型SNSの一つです。従来のActivityPubベースの分散型SNSとは違い、所属サーバー間で得られる情報の差分が全くない特徴と、投稿者のデータは所属するサーバーにしか保存されない特徴を両立した新しいSNSです。
マイクロサービスとして複数のコンテナに分割されていますが、Helmチャートが提供されているのでKubernetesでの起動も簡単です。
Ollama & Open-WebUI
LLM: 事前にGPUをノードに割り当てておくことで、Kubernetes上でもローカルLLMを利用することができます。もっぱらChatGPTとClaudeのフロントエンドとして利用していますが、たまに出る新しいモデルもWebUIからサクッと試すことができるのでなかなか面白いです。
おわりに
この記事では、自宅Kubernetesクラスタの運用に関して物理層からアプリケーション層まで広く浅く紹介させていただきました。自宅でKubernetesを運用することは一般的にはかなり負担の高い行為だと思いますが、ただクラウドでKubernetesを利用するだけでは見えないLinuxやネットワーク周りの知見もグッと深めることができます。
自宅クラスタは趣味のように取られがちですが、実際には本番環境で直面する多くの課題を小さなスケールで体験できる良い学習環境になります。これらはDocker Composeよりも複雑に感じるかもしれませんが、上記の技術や考え方を取り入れると、より実践的で堅牢なシステムを構築する経験ができると思います。
皆さんもぜひ自分の環境や目的に合わせて自分だけのクラスタを作ってみてください!
Discussion