「連休暇やなぁ。せや,ラズパイで Kubernetes クラスタ作ったろ!」

【 Kubernetes の Raspberry Pi 包み】- 物理編 の続きです。 今回は,論理面を構築していきます。

目次

Raspberry Pi OS イメージの設定

今回,OS は Raspbian Stretch Lite ではなく, Hypriot を使います。

Hypriot とは, Raspberry Pi 上で Docker を動かすために最適化されたディストリビューションです。

実行環境 : macOS Mojave (Version 10.14.4)

micro SD カードの確認・フォーマット

イメージを書き込む SD カードを確認します。

diskutil list を SD カードを挿入前後で実行します。

  • 挿入前
$ diskutil list
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *251.0 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                 Apple_APFS Container disk1         250.8 GB   disk0s2

/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +250.8 GB   disk1
                                 Physical Store disk0s2
   1:                APFS Volume Macintosh HD            76.8 GB    disk1s1
   2:                APFS Volume Preboot                 262.2 MB   disk1s2
   3:                APFS Volume Recovery                6.2 GB     disk1s3
   4:                APFS Volume VM                      5.4 GB     disk1s4
  • 挿入後
$ diskutil list
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *251.0 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                 Apple_APFS Container disk1         250.8 GB   disk0s2

/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +250.8 GB   disk1
                                 Physical Store disk0s2
   1:                APFS Volume Macintosh HD            76.8 GB    disk1s1
   2:                APFS Volume Preboot                 262.2 MB   disk1s2
   3:                APFS Volume Recovery                6.2 GB     disk1s3
   4:                APFS Volume VM                      5.4 GB     disk1s4

/dev/disk2 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *31.1 GB    disk2
   1:             Windows_FAT_32 HypriotOS               67.1 MB    disk2s1
   2:                      Linux                         31.0 GB    disk2s2

新たに /dev/disk2 が出力されました。これが SD カードです。

次に,以下のコマンドを実行して SD カードのフォーマットを行います。 [name] はフォーマット後の SD カードの名前ですので,適当な名前を指定してください。

$ diskutil eraseDisk MS-DOS [name] disk2

flash のインストール

flash とは,Hypriot OS イメージを SD カードに書き込む際に用いるコマンドラインツールです。 オプションを指定することによって,ホスト名や Wi-Fi のセットアップを行うこともできます。

以下のコマンド群を実行して,flash をインストールします。

$ curl -LO https://github.com/hypriot/flash/releases/download/2.3.0/flash
$ chmod +x flash
$ sudo mv flash /usr/local/bin/flash

flash でイメージを書き込む際にプログレスバーを表示させたい場合は,pv をインストールしておきます。

$ brew install pv

OS イメージを micro SD カードに書き込む

flash を用いて,micro SD カードに Hypriot イメージを書き込みます。 [ホスト名]にはお好みの名前を指定してください。(僕はそれぞれ k8s-master, k8s-node-01, k8s-node-02 としました。)

$ flash --hostname [ホスト名] --device /dev/disk2 https://github.com/hypriot/image-builder-rpi/releases/download/v1.10.1/hypriotos-rpi-v1.10.1.img.zip

二回目以降は /tmp 以下にキャッシュされた OS イメージを用いるため,時間が短縮されます。

僕の場合,--device オプションでデバイスを指定しないと “No SD card found. Please insert SD card, I’ll wait for it…” と表示されたまま,一向にイメージの書き込みが始まらなかったので,明示的にデバイスを指定しました。 ただし,間違ったデバイス名を指定すると PC のデータが吹っ飛びかねないので,まずはデバイスを指定しないで試してみることをおすすめします。

Raspberry Pi の起動

上の手順で OS イメージを書き込んだ micro SD カードを Raspberry Pi に挿入し,電源を入れます。

起動後, [ホスト名].local にアクセスします。 ユーザー名は pirate,パスワードは hypriot です。

$ ssh pirate@[ホスト名].local

アクセスできない場合は,恐らくネットワーク設定が間違っています。 物理編を参考に,再度設定しなおしてみてください。

kubeadm のインストール

まず,kubernetes の APT key を信頼して,公式の APT Kubernetes レポジトリを追加します。

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
$ echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

次に,kubeadm をインストールします。

$ sudo apt-get update
$ sudo apt-get install kubeadm

これを Raspberry Pi の台数分繰り返します。

Kubernetes クラスタの構築

いよいよ Kubernetes クラスタを構築していきます。

以下の構成でクラスタを構築します。

  • Master node x 1
  • Worker node x 2

Master node の構築

Master node に SSH ログインして,kubeadm init を実行します。

$ kubeadm init --pod-network-cidr 10.244.0.0/16
...

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 192.168.13.7:6443 --token xxxxxxxxxxxxxxxxx --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

コンソールに出力されるログは省略しましたが,成功するとこのように出力されます。 kubeadm join ... の部分は後で使うのでひかえておいてください。

次に,コンソールに出力された以下の 3 つのコマンドを実行します。

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

最後に,pod network add-on をインストールします。今回は flannel を使います。

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Worker node の構築

先程 Master node で kubeadm init を実行した際にひかえたコマンドを Worker node 上で実行します。

$ sudo kubeadm join 192.168.13.7:6443 --token xxxxxxxxxxxxxxxxxxxxxxx --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.

コンソールに出力されるログは省略しましたが,成功するとこのように出力されます。

動作確認

node の状態を確認してみましょう。

$ kubectl get nodes
NAME          STATUS   ROLES    AGE   VERSION
k8s-master    Ready    master   84m   v1.14.1
k8s-node-01   Ready    <none>   57m   v1.14.1
k8s-node-02   Ready    <none>   57m   v1.14.1

Master node が 1 台, Worker node が 2 台構築できているのが確認できました!

ただ,Worker node の ROLES が <none> になっているので,ラベルを追加しましょう。

$ kubectl label node k8s-node-01 node-role.kubernetes.io/worker=worker
$ kubectl label node k8s-node-02 node-role.kubernetes.io/worker=worker

再度 node の状態を確認してみましょう。

$ kubectl get nodes
NAME          STATUS   ROLES    AGE   VERSION
k8s-master    Ready    master   84m   v1.14.1
k8s-node-01   Ready    worker   57m   v1.14.1
k8s-node-02   Ready    worker   57m   v1.14.1

ラベルを追加できましたね。

以上でクラスタの構築は完了です!!

あとがき

割とすんなりと構築できました。 先人の方々のおかげです! ただ,kubeadm が何をしているのか, flannel の詳細についての理解は全然できてないので,勉強したいと思います。 また,まだ用途が全然決まってないので,それも今後決めたいと思います。

参考