kubernetesのラズパイ包みが美味しそうだったので、kubeadmを使って作ってみた

初めまして、 @shirot61 です。

# この記事の目的
タイトルそのままです。

# 動機
- [3日間クッキング【Kubernetes のラズペリーパイ包み　“サイバーエージェント風”】](https://developers.cyberagent.co.jp/blog/archives/14721/)がとても美味しそうだったので、
kubernetes ＆ Raspberry Pi 素人でも作れるか、試してみたかった。
- SoftwareDesign 3 月号の kubernetes 特集をみて、kubernetes に入門したくなった。
- せっかく作ったので、どこかにまとめておきたかった

# 料理を作るにあったって
[3日間クッキング](https://developers.cyberagent.co.jp/blog/archives/14721/) では、論理的構築が省略されていたため、その辺りを色々調べていたところ、
Z Lab の @hatotaka シェフが、kubeadmを使ったクラスタ構築を行なっていました！

- [Raspberry PI と kubeadm で自宅 Kubernetes クラスタを構築する](https://qiita.com/hatotaka/items/48a88ecb190e1f5e03c3)

なので、論理的構築は、そちらを参考に(ほぼ丸パクリ)させていただきました。（ありがとうございます）

---

というわけで、今回構築する k8s クラスタは、以下になります。

- Raspberry pi
    - モデル: Raspberry Pi 3 Model B
    - OS: Raspbian stretch lite (2018-03-13)
- Kubernetes
    - kubeadm: v1.9.4
    - Pod Network: Flannel

@hatotaka さんの記事との違いは、バージョンくらいです。

macOS High Sierra を使って、これらを構築していきます。

#材料
サイバーエージェントシェフの材料 (の画像) を凝視して集めた材料がこちらになります。

|   |  |
|:--|:--|
| Raspberry Pi 3 Model B  | 3 個 | 
| ヒートシンク  | 3 セット |
| microSDカード 16GB  | 3 枚 |
| 4段積層式 Raspberry Pi 3 ケース  | 1 個 |
| 6ポート 60W USB 充電器 (Anker PowerPort 6)  | 1 個 |
| 2.4A microUSB ケーブル  | 4 本 |
| コンパクト無線親機 (WMR-433W-BK)  | 1 個 |
| NETGEAR GS305-100JPS  | 1 個 |
| 0.3m LAN ケーブル  | 4 本 |

材料を並べた画像がこちらです。

![IMG_1055.jpg](https://qiita-image-store.s3.amazonaws.com/0/244416/07fc24c5-72b1-ff1d-b4b8-e8ca2e73989d.jpeg)

ちょくちょく違うものも混じっていますが、まぁいいでしょう！
スイッチングハブは NETGEAR のものを使います。(ステッカー...)

#料理開始
## ラズパイラックの構築から 〜 LANの設定
RaspberryPi を袋から取り出して、

![IMG_1058.JPG](https://qiita-image-store.s3.amazonaws.com/0/244416/2e45b9be-5d70-f6da-531b-40bce07ace2f.jpeg)

ヒートシンクをつけて、

![IMG_1059.JPG](https://qiita-image-store.s3.amazonaws.com/0/244416/567b9539-3faf-5aff-a1e0-46398145d8f6.jpeg)

最終的に出来上がったものがこちらになります。
![IMG_1066.png](https://qiita-image-store.s3.amazonaws.com/0/244416/afad4fc5-897b-b659-8fb7-83a26210c6a0.png)

(もう少し短いケーブルにすべきだったかも..)

---
そして、無線LANの設定を行うために、

1.  ブラウザで 192.168.13.1 にアクセスして、
2.  ワイヤレスワンモードを選択し、
3.  接続先を指定して、
4.  接続先の暗号化キーを入力すると、
5.  接続がタイムアウトしました ...？

もう、勘弁して下さい

調べてみると、自宅の回線は PPPoE 認証が必要なやつらしく、
コンパクト無線親機の WMR-433W-BK は、PPPoE 認証に対応してないので、これが原因で接続がタイムアウトしてました...

なので今回は、

有線LAN - スイッチングハブ - ラズパイ ×3

と接続する方式に、急遽、路線変更しております。

## raspbian のインストールと、各種設定(ホスト＆ユーザ名変更など)
### OS インストール
というわけでまずは、raspbian をダウンロードして、インストールを行います。

ラズパイ初心者に向けて、 https://www.raspberrypi.org/documentation/installation/ に
>*Beginners* should start with NOOBS, which gives the user a choice of operating system from the standard distributions.

との記載があり、NOOBS をお勧めしてくれていますが、そんなものは無視です。

GUI はいらないので、[ここ](https://www.raspberrypi.org/downloads/raspbian/) からRaspbian Stretch Lite をダウンロードして、Mac に microSDカードを差し込みます。

その後の手順は、以下の通りです。

```.sh
  // raspbianの解凍
  $ cd ~/raspbianがDLされた場所
  $ unzip 2018-03-13-raspbian-stretch-lite.zip

  // SDカードのパスをチェック
  // 自分の環境だと、 /dev/disk2s1 だった
  $ diskutil list

  // SDカードのアンマウント
  // diskutil list で調べたパスを指定する
  $ sudo diskutil unmount /dev/disk2s1

  // イメージの書き込み
  $ sudo dd bs=1m if=2018-03-13-raspbian-stretch-lite.img of=/dev/rdisk2 conv=sync
```
詳細：[Installing operating system images - Raspberry Pi Documentation](https://www.raspberrypi.org/documentation/installation/installing-images/)

次に、sshを有効にします。

```.sh
  // sshの有効化
  $ cd /Volumes/boot
  $ touch ssh
```
あとは、cgroups の、cpu と memory を有効化するために、

`/Volumes/boot/cmdline.txt` に、cgroup_enable=cpuset cgroup_memory=1 を追加して下さい。

これで　OK (のはず) です。

### Raspberry Pi へのログイン

ログインしようにも、ラズパイ達のアドレスがわからなかったので、

```.sh
$ arp -a
```

を実行し、それぞれのラズパイに割り当てられているIPアドレスを調べて、

ssh でログイン

```.sh
$ ssh pi@192.168.xxx.xxx

// 以下、ついでにやっときます
$ sudo apt-get update
$ sudo apt-get -y upgrade

// k8s 1.8からスワップが有効だとkubeletが起動しないそうなので、先にやっとく(起動しっぱなしにしてたら、消せって怒られた)
// スワップを切ることで、SDカードの寿命を伸ばせる
$ sudo dphys-swapfile swapoff
$ sudo dphys-swapfile uninstall
$ sudo update-rc.d dphys-swapfile remove
```

後は、ホスト名とユーザ名を変更など、セッティングを行って、

```.sh
$ slogin user@host.local
```

でログインできることを確認します。

をラズパイ3台分で行います。

## Docker & kubeadm のインストール ~ master & node のセットアップ

### Docker のインストール
*注 : 今回私が使用している raspbian(Debian) のバージョン(コードネーム)は、stretch です。*

Docker をインストールしていきます。

```.sh

$ sudo apt-get install -y \
     apt-transport-https \
     ca-certificates \
     curl \
     gnupg2 \
     software-properties-common

// $(. /etc/os-release; echo "$ID") で、OS の名前を引っ張ってこれる(wheezy 以降？)
$ curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo apt-key add -

$ echo "deb [arch=armhf] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
     $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

$ sudo apt-get update

$ sudo apt-get -y install docker-ce

```

詳細：[Get Docker CE for Debian](https://docs.docker.com/install/linux/docker-ce/debian/#install-using-the-repository)

### kubeadm のインストール
kubeadm をインストールしていきます。

```.sh
$ curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

// k8s 公式(下の詳細リンクのとこ)の方には、ヒアドキュメントを使ってやる方法で書いてあるけど、
// @hatotaka さんみたいに、パイプと tee 使った方が、なんだかカッコ良い
$ echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
```

詳細：[Installing kubeadm | Kubernetes](https://kubernetes.io/docs/setup/independent/install-kubeadm/)

### masterのセットアップ
master のセットアップを行います。

`$ sudo kubeadm init ...` のとこは、--apiserver-advertise-address で、master のアドレスを指定する方が正解かも?
参考：[kubeadm で kubernetes v1.8 + Flannel をインストール](https://qiita.com/hichihara/items/79ef6613026f8c13eb99)

```.sh
$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16
[init] Using Kubernetes version: v1.9.4
[init] Using Authorization modes: [Node RBAC]
[preflight] Running pre-flight checks.
Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join --token xxxxxx.xxxxxxxxxxxxxxxx 192.168.1.13:6443 --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


// kubeadm init で表示されたメッセージに従う
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
```

kubectl が正しく実行できるか確認。

```.sh
$ kubectl verision
Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.4", GitCommit:"bee2d1505c4fe820744d26d41ecd3fdd4a3d6546", GitTreeState:"clean", BuildDate:"2018-03-12T16:29:47Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/arm"}
Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.4", GitCommit:"bee2d1505c4fe820744d26d41ecd3fdd4a3d6546", GitTreeState:"clean", BuildDate:"2018-03-12T16:21:35Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/arm"}
```

falnnel のデプロイ

```.sh
$ kubectl apply -f <(curl -s https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml |sed 's/amd64/arm/g')
```

### node のセットアップ
node のセットアップを行います。

`kubeadm init` を実行した時に表示されたメッセージに従い、コマンドを入力して、master のとこに参加させる。

```.sh
$ kubeadm join --token xxxxxx.xxxxxxxxxxxxxxxx 192.168.1.13:6443 --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

# そして完成へ

最後に、**master** で `kubectl get node`を実行して 、node の参加を確認する。

```.sh
$ kubectl get node
NAME       STATUS    ROLES     AGE       VERSION
raspi001   Ready     master    3d        v1.9.4
raspi002   Ready     <none>    3d        v1.9.4
raspi003   Ready     <none>    3d        v1.9.4
```

以上でセットアップが完了しました。

ついに、kubernetes のラズパイ包みの完成です！！

![IMG_1077.JPG](https://qiita-image-store.s3.amazonaws.com/0/244416/0de2a4a7-2a39-aa62-908d-9c67ebc2b817.jpeg)

非常に美味しそうです。(なんとかできてよかった...)

# おわりに
今回は、
サイバーエージェントの [MasayaAoyama](https://developers.cyberagent.co.jp/blog/archives/author/amsy/) さんの記事と、Z Lab の　@hatotaka さんの記事を元に、

- 物理的構築
    - [3日間クッキング【Kubernetes のラズペリーパイ包み　“サイバーエージェント風”】](https://developers.cyberagent.co.jp/blog/archives/14721/)

- 論理的構築
    - [Raspberry PI と kubeadm で自宅 Kubernetes クラスタを構築する](https://qiita.com/hatotaka/items/48a88ecb190e1f5e03c3)

を行いました。

これで、

>**一家に一台おうち Kubernetes の時代**

に乗り遅れずにすみそうです。

というわけで、
全くのkubernetes(&ラズパイ)素人でも
簡単にkubernetesクラスタを構築できて、テンションが上がっております。

今後はこれを使って kubernetes を触っていきます。

---

拙い記事でしたが、最後まで読んで頂き、ありがとうございました。
ご指摘等々ございましたら、よろしくお願いします。

# 参考にした記事
- [3日間クッキング【Kubernetes のラズペリーパイ包み　“サイバーエージェント風”】](https://developers.cyberagent.co.jp/blog/archives/14721/)
- [Raspberry PI と kubeadm で自宅 Kubernetes クラスタを構築する](https://qiita.com/hatotaka/items/48a88ecb190e1f5e03c3#os-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
- [Raspbianのインストールと最強の初期設定 ](https://jyn.jp/raspbian-setup/)
- [kubeadm で kubernetes v1.8 + Flannel をインストール](https://qiita.com/hichihara/items/79ef6613026f8c13eb99)