k0sctlを使っておうちKubernetesクラスタを簡単に構築する

Kubernetesを学習するときの題材として、RaspberryPiを複数台使ってクラスタを作ることが結構流行っています。

Docker Desktopとかにも、マシン単体でKubernetesを動かす機能があるのですが、やはり物理マシン複数台で構成されたクラスタを動かしてみると、理解度が全然違ってくると思います。

我が家にもRaspberryPiのKubernetesクラスタがあります。構築に際した過去の記事はこちらです。

https://techblog.kayac.com/2019/12/17/080000

https://qiita.com/commojun/items/09237c71b3ad06dfcd3b

初めてRaspberryPi 3Bを使ってクラスタを構築してからもう4年くらい経ったみたいです。Kubernetes事情も結構変化してきました。特に、k0sというツールの登場で、クラスタの初期設定やノードの追加がとても簡単になったように思います。

# k0sとは

本家Kubernetesの公式の手順に従ってKubernetesクラスタを構築するのは非常に大変だったように思います。さっさとコンテナを起動して遊んでみたい自分としてはかなりハードルの高い手順の連続だったように思います。そういった手間を引き受けてくれるのがk0sというツールになります。

https://k0sproject.io/

紹介文を一部引用すると…

>Zero Friction
k0s drastically reduces the complexity of installing and running a fully conformant Kubernetes distribution. New kube clusters can be bootstrapped in minutes. Developer friction is reduced to zero, allowing anyone, with no special skills or expertise in Kubernetes to easily get started.

翻訳

>k0sは、完全に準拠したKubernetesディストリビューションのインストールと実行の複雑さを劇的に軽減します。新しいKubeクラスタを数分で起動することができます。開発者の摩擦はゼロになり、Kubernetesに関する特別なスキルや専門知識がなくても、誰でも簡単に始められるようになります。

という感じで、「とにかくKubernetesを早く使ってみたいんだ！」という人にはうってつけかと思います。さらには、公式にarmアーキテクチャのサポートを謳っていたり、ワーカノードに求められる最低のメモリ要件が0.5GBだったりと、RaspberryPiをでクラスタを構築することも意識されているようです。

# k0sctlが便利

さらに便利なのがk0sctlというツールです。これを使うことで、Kubernetesのクラスタ構成をコードで管理できるようになります。

https://github.com/k0sproject/k0sctl

RaspberryPiでKubernetesクラスタを構築する場合でこそk0sctlはおすすめだと感じます。小さなマシンなので、microSDカードはじめハードウェアにトラブルが起きることがまあまああり、OSのクリーンインストールからクラスタ構築のやり直しをする機会が多いです。そういったとき、k0sctlでコード管理されたクラスタ構成を一発で再現できるのはとても便利です。

# 事前準備

k0sctlを使うためには、次の事前準備が必要です。

- 各RaspberryPiのIPアドレスを固定すること
- k0sctlを実行するマシンからそれぞれのRaspberryPiへSSH接続できること
- cgroupを有効にすること

これだけで多分大丈夫です。過去の記事では、swapが有効だと、ワーカが起動しないので無効にしましょうという指示を書いてあったりしますが、最近のKubernetesではその必要がなくなっています。ただし、microSDカードの消耗を抑える点では無効にするのも良さそうです。

k0sctl自体を実行するマシンは、クラスタに属するマシンである必要はありません。それぞれのノードにSSHさえできればOKです。brewが使えるなら以下のコマンドでインストールします。他の方法は公式のgithubを見てください。

```
brew install k0sproject/tap/k0sctl
```

# 設定ファイルを書く

僕の家のクラスタ定義ファイルはだいたいこんな感じになっています。この例では、4台のRaspberryPiでクラスタを構成し、コントロールプレーン（controller）ノードがワーカーも兼ねているものになっています。具体的な記載方法については[公式ドキュメント](https://github.com/k0sproject/k0sctl#configuration-file)を参照してください。

``` k0sctl.yml
apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
  name: k0s-pi
spec:
  k0s:
    version: v1.26.1+k0s.0
  hosts:
  - role: controller+worker
    os: debian
    ssh:
      address: 192.168.10.41
      user: commojun
      keyPath: ~/.ssh/id_rsa
  - role: worker
    os: debian
    ssh:
      address: 192.168.10.31
      user: commojun
      keyPath: ~/.ssh/id_rsa
  - role: worker
    os: debian
    ssh:
      address: 192.168.10.32
      user: commojun
      keyPath: ~/.ssh/id_rsa
  - role: worker
    os: debian
    ssh:
      address: 192.168.10.33
      user: commojun
      keyPath: ~/.ssh/id_rsa
```

一点だけ特殊だった部分があって、僕の場合、RaspberryPi OSをインストールしていたのですが、その場合は `spec.hosts[*].os` に `debian` を指定する必要がありました。指定がなかった場合、`/etc/os-release`等から読み取って自動的にLinuxディストーションを判定するのですが、RaspberryPi OSはk0sのサポートOSのリストに乗っておらずインストールエラーとなりました。そこで、RaspberryPi OSのベースとなっているdebianを指定したところ、正常にインストールが完了しました。

# apply!

ここまで準備が整ってしまえば、あとはこのコマンドで実行し、しばらく待つだけです。位置から手作業で構築するよりも本当に楽になりました。なにかドジをしてクラスタを壊してしまった場合も、また作り直せばいいか、という気持ちにさせてくれます。

```
$ k0sctl apply --config ./k0sctl.yml
```

# バージョンアップやクラスタの変更も楽

もしKubernetesの新しいバージョンが利用したくなった場合は、設定ファイルの `spec.k0s.version` の欄を書き換えてapplyコマンドを実行するだけでOKです。他にもクラスタに細かな設定を記載できるようになっているようです。ただし、設定項目によっては、一度クラスタを消して(`k0sctl reset`)から再インストールしないと反映されない項目もあるようです。

# まとめ

k0sとk0sctlの登場でKubernetesクラスタの構築がかなり楽になったと感じました。全部手動で構築すると理解が深まると思うのですが、実践でKubernetesを扱う人の大半は、GoogleやAmazonのクラウドプラットフォーム上にあるKubernetesを「使う」側の人だと思うので、おうちKubernetesをさくっと使える状態にしてくれるのは、学習のハードルを下げてくれて良いんじゃないかと思います！