おうちKubernetes構築でハマったところ - ニッチ編 -

おうちKubernetesが流行ってますね！

Raspberry Pi 3 Model Bがたまたま安く手に入ったので、もはや何番煎じかも分かりませんが、Raspberry Piとkubeadmを使って、自宅Kubernetesクラスタを構築しました。

![k8s on raspi](https://qiita-image-store.s3.amazonaws.com/0/3225/99c5fd7e-3a31-8d29-7826-118bc05ba8a1.jpeg)

構築方法の記事については、既に下記のような良記事が存在するので、本記事ではハマった細かい部分についてのみ記載します。

- [Raspberry PiでおうちKubernetes構築【物理編】](https://qiita.com/go_vargo/items/d1271ab60f2bba375dcc)
- [Raspberry PiでおうちKubernetes構築【論理編】](https://qiita.com/go_vargo/items/29f6d832ea0a289b4778)
- [Raspberry Piにkubernetesクラスタをインストールする](https://www.hidekazuna.org/?p=825)
- [3日間クッキング【Kubernetes のラズペリーパイ包み　“サイバーエージェント風”】](https://developers.cyberagent.co.jp/blog/archives/14721/)


## 順番通りにホスト名を設定したい

無事筐体のセットやケーブリングの設定が完了し、Raspberry Piの設定でホスト名を設定しようとしたところ、どのIPがどのマシンに設定されているか分かりませんでした。

![hostname setting](https://qiita-image-store.s3.amazonaws.com/0/3225/9168c066-4153-6553-8bbc-5ed776a2aef8.jpeg)


そのため、どのIPがどのRaspiと対応しているのか確認するために、LEDを消灯させることにしました。

- [Raspberry Pi 基盤 の LED を 消灯する _ 験なきものを思はずは](https://www.hidekazuna.org/?p=825)

```shell-session
pi@raspi:~ $ echo none | sudo tee /sys/class/leds/led0/trigger
none
pi@raspi:~ $ echo none | sudo tee /sys/class/leds/led1/trigger
none
pi@raspi:~ $ echo 0 | sudo tee /sys/class/leds/led1/brightness
0
```

![power off led](https://qiita-image-store.s3.amazonaws.com/0/3225/dfc11f89-0edb-2702-8577-d2e005a8731d.jpeg)


消灯後、ホスト名を設定した後はrebootすれば元に戻ります。

他の方法としては、ディスクアクセスをさせれば、緑色のLEDが点滅するので、 `sudo apt-get update ` コマンド等を実行してLEDの点滅を見ることで、IPと対応するRaspiを確認することもできます。

ちなみにRaspberry Piに接続するためのIPについては、`arp` コマンド等で確認できます。

```shell-session
$ arp -a
```

またホスト名が設定された後は、標準でAvahiが起動している為、MacからであればBonjourのおかげで下記のようにホスト名でアクセスすることができます。LinuxやWindowsもAvahiを入れれば、ホスト名でアクセスできるようになると思います。

```shell-session
$ ssh <ホスト名>.local
```

## Dockerのバージョン

2019年2月現在 `apt-get` で入るDockerのバージョンは `18.09` です。現在Kubernetesでrecommendedされているバージョンは `18.06` の為、`kubeadm init` を実行した際にエラーになります。（オプションでskipできそうですが…）

- [CRI installation - Kubernetes](https://kubernetes.io/docs/setup/cri/#docker)

そのため、バージョンを指定してインストールする必要があります。
`apt-get` でインストールできるバージョンは下記で確認することができます。

```shell-session

$ sudo apt-cache showpkg docker-ce
...
Provides:
5:18.09.0~3-0~raspbian-stretch -
18.06.1~ce~3-0~raspbian -
18.06.0~ce~3-0~raspbian -
18.03.1~ce-0~raspbian -
18.03.0~ce-0~raspbian -
17.12.1~ce-0~raspbian -
17.12.0~ce-0~raspbian -
17.09.1~ce-0~raspbian -
17.09.0~ce-0~raspbian -
Reverse Provides:
```

バージョンを指定してインストールする方法は下記の通りです。

```shell-session
sudo apt-get install docker-ce=<version>
```

## Kubernetesクラスタにクライアントマシンからアクセスしたい

Kubernetesクラスタの構築も完了し、Raspberry Piにsshして `kubectl` を実行するところまで確認することができました。さて次に、クライアントのMacからも `kubectl` で操作したいと思ったところでハタと困りました。
普段は `az` コマンドや `gcloud` コマンドがよしなに設定してくれる箇所なのでKubernetesにおけるユーザの追加方法を意識していませんでした。

下記の記事を参考に `秘密鍵の生成` 〜 `kubectlの設定` を実行することでアクセスできるようになります。

- [Kubernetesでユーザを作成する（X509 Client Certs編）](https://qiita.com/knqyf263/items/aefb0ff139cfb6519e27)

## ARM用のイメージを利用する

Pythonのサンプルイメージを利用して動作確認をしようとしたところ、動作しませんでした。

```dockerfile
# Base Image
FROM python:3.6

# ...(中略

# Run the application
CMD ["python", "/opt/myapp/app.py"]
```

実行結果のエラーは下記の通り

```shell-session
$ kubectl logs  <pod>
standard_init_linux.go:190: exec user process caused "exec format error"
```

ローカルのdockerでは起動する為、理由が分からず悩みましたが、Base ImageのPythonがx86用にbuildされていたのが原因でした。考えてみれば当たり前で、RaspiのCPUはARMの為、ARM用のBuild Imageを利用する必要があります。

```dockerfile
# Base Image
FROM armhf/python:3.6

# ...(中略
```

Docker HubにARM用のImageが存在するので、そちらを利用するように修正すると問題なく動作しました。

## まとめ

まとめていて思いましたが、Kubernetes全然関係ありませんね。
実際のところ先達の良記事のおかげで、ほぼハマらずにスムーズに構築することができます。
kubeadmのおかげで、Kubernetesの構築もほぼコマンド一つです。
皆さん書いていますが、大変だったのは、ケースのアクリル板から保護ビニールを剥がすところくらいです。

構築前・構築中は実際のところ3Gしかないし、利用するかな？Docker for Mac等のローカルでのシングルノードクラスタで十分じゃないかなと思っていました。
構築後利用してみると、便利です。クライアント側マシンには負荷がかからないので、重い処理をしていても快適です。後所有感がすごいです。やはり一家に一台、Kubernetesクラスタですね！

それでは良いKubernetes生活を！