RaspberryPi
kubernetes
kubeadm
OriginalZ LabDay 16

Raspberry PI と kubeadm で自宅 Kubernetes クラスタを構築する

はじめに

こんにちは、 @hatotaka と申します。この記事は、 Z Lab Advent Calendar 2017 16日目の記事です。

今回は、Kubernetes初心者向けに、Raspberry PIとkubeadmを利用して自宅Kuberneetesクラスタを構築する方法を紹介したいと思います。私も11月から本格的に業務でもKubernetesを利用するようになりました。その勉強として自宅でKubernetesを構築したので、その方法を共有したいと思います。

準備

まずは、必要なものを準備します。

今回、私が準備したものは以下の通りです。これらはすべて Yahoo! ショッピングやAmazonで購入することができます。

  • Raspberry Pi 3 Model B * 3
  • Transcend microSDHCカード 32GB Class10 UHS-I対応 * 3
  • Anker PowerPort 6 (60W 6ポート USB急速充電器)
  • LAN ケーブル * 3
  • マイクロ USB ケーブル * 3

これらは、弊社親会社のヤフー株式会社が10月から開始したMy Polaris1の技術活動費用補助を利用して購入しました。この制度は技術力向上のための費用を月1万円まで補助してくれる制度です。Z Labでは、My Porarisをはじめ、ヤフーの様々な制度234を利用することができます。

また、すでに自宅にある以下のものを利用しました。

  • スイッチングハブ
  • AirMac Express

私の自宅では、有線LANを作業場まで引っ張ってくることが難しかったので、AirMac Expressを自宅のWiFi アクセスポイントに接続し、そこからスイッチングハブ、スイッチングハブからRaspberry PIに接続しました。

wifi.png

Kubernetes クラスタの構築

今回構築するKubernetes クラスタは以下のとおりです。

  • Raspberry pi
    • モデル: Raspberry Pi 3 Model B
    • OS: Raspbian stretch lite (2017-11-29)
  • Kubernetes
    • kubeadm: v1.8.4
    • Pod Network: Flannel

また、今回の方法はmacOS High Sierraで行っています。WindowsやLinux、macOSのほかのバージョンでは異なる場合があるので注意してください。

OS のインストール

まずは、Raspberry PIにOSをインストールします。今回のOSはRaspbianを利用します。OSのインストールはマイクロSDカードにイメージを書き込みます。これらの作業はmacOS上で行います。

以下のURLからRaspbian stretch liteをダウンロードします。

ダウンロードしたzipファイルを解凍して、マイクロSDカードに書き込みます。
ディスクのパスは環境ごとに違うので注意が必要です。

// zipファイルを解凍する
$ cd ~/Download
$ unzip 2017-09-07-raspbian-stretch-lite.zip
Archive:  2017-09-07-raspbian-stretch-lite.zip
  inflating: 2017-09-07-raspbian-stretch-lite.img 

// SD card のパスを確認
$ diskutil list

// SD card をアンマウントする
$ sudo diskutil umount /dev/disk2s1

// dd コマンドでイメージを書き込む
$ sudo dd bs=1M if=/path/to/image/2017-09-07-raspbian-stretch-lite.img of=/dev/rdisk2

詳細は https://www.raspberrypi.org/documentation/installation/installing-images/README.md を参照してください。

OSイメージをSDカードに書き込めたら、いくつか設定を行います。これらの作業もmacOS上で行います。

ssh の有効化

sshを有効にするための設定をします。bootディレクトリ以下にsshという名前のファイルを作成します。

$ cd /Volumes/boot
$ touch ssh

この作業を行うことにより、Raspbianの起動後にsshdが起動して、リモートからセットアップを続けることができます。詳細は https://www.raspberrypi.org/blog/a-security-update-for-raspbian-pixel/ を参照してください。

cgroups の有効化

次にcgroupsのcpusetとmemoryを有効化するために、以下の設定を行います。

$ cd /Volumes/boot
$ vi cmdline.txt

cgroup_enable=cpuset cgroup_enable=memoryを追加します。

- dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=af816d3b-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
+ dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=af816d3b-02 rootfstype=ext4 cgroup_enable=cpuset cgroup_enable=memory elevator=deadline fsck.repair=yes rootwait

最新のkernelバージョンでは、 設定方法が cgroup_memory=1 に変わっているようです。

https://archlinuxarm.org/forum/viewtopic.php?f=15&t=12086#p57035

以上の作業をセットアップするRaspberry PIの台数分行います。

Bootと初期設定

上記の手順で作成したSDカードを、Raspberry PIに挿入し、電源をいれます。

起動後、同一ネットワークに raspberrypi の名前のインスタンスがなければ、 raspberrypi.localの名前でアクセスすることができます。

$ slogin pi@raspberrypi.local
//  初期パスワードは raspberry

ログインができたら、次にホスト名を変更します。/etc/hostnameファイルを修正して、好きなホスト名に変更します。今回私はraspi[001-003]の名前を付けました。

また、必要に応じて、ユーザの追加、デフォルトユーザ pi の無効化等も実施します。

$ sudo vi /etc/hostname
// ホスト名を変更

// 必要に応じて、ユーザの追加等を行う

$ sudo reboot

reboot後は、 <設定したホスト名>.localの名前でアクセスすることができます。

Docker のインストール

次にDockerのインストールを行います。

$ slogin <設定したホスト名>.local

// 必要なパッケージのインストール
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

// リポジトリの追加
$ 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 install docker-ce

詳細は、 https://docs.docker.com/engine/installation/linux/docker-ce/debian/ を参照してください。

kubeadmのインストール

次に、kubeadmとkubelet、kubectlをインストールします。

ます、スワップを無効にします。これはKubernetes 1.8からスワップが有効だとkubeletが起動しない5ためです。

$ sudo dphys-swapfile swapoff
$ sudo dphys-swapfile uninstall
$ sudo update-rc.d dphys-swapfile remove

リポジトリを追加してパッケージをインストールします。

$ slogin <設定したホスト名>.local

// リポジトリの追加
$ curl -fsSL 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/kube.list

// インストール
$ sudo apt-get update
$ sudo apt-get install kubelet kubeadm kubectl

詳細は、 https://kubernetes.io/docs/setup/independent/install-kubeadm/ を参照してください。

Master のセットアップ

masterにするインスタンスで以下のコマンドを実行します。 --pod-network-cidr=10.244.0.0/16 のオプションはflannelを利用するために必要なオプションです。

$ sudo 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 (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:
  http://kubernetes.io/docs/admin/addons/

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

  kubeadm join --token xxxxxx.xxxxxxxx 10.0.1.22:6443 --discovery-token-ca-cert-hash sha256:xxxxxxxxx

無事成功すると、上記のようなメッセージが表示されます。

メッセージ通り、pod networkをデプロイします。今回はFlannelを利用します。

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

kubectlが正しく実行できるかどうか、確認します。

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"8", GitVersion:"v1.8.5", GitCommit:"cce11c6a185279d037023e02ac5249e14daa22bf", GitTreeState:"clean", BuildDate:"2017-12-07T16:16:03Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/arm"}
Server Version: version.Info{Major:"1", Minor:"8", GitVersion:"v1.8.5", GitCommit:"cce11c6a185279d037023e02ac5249e14daa22bf", GitTreeState:"clean", BuildDate:"2017-12-07T16:05:18Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/arm"}

以下のコマンドでflannelをデプロイします。

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

これで、masterのセットアップが完了しました。

Node のセットアップ

nodeとして追加するインスタンスで以下のコマンドを実行します。このコマンドはmasterのkubeadm init実行時に表示されたものです。

$ kubeadm join --token xxxxxx.xxxxxxxx 10.0.1.22:6443 --discovery-token-ca-cert-hash sha256:xxxxxxxxx

kubeadm joinを実行後、kubectl get nodeを実行すると、ノードが追加され、ステータスも Ready になります。

$ kubectl get node
NAME       STATUS    ROLES     AGE       VERSION
raspi001   Ready     master    27m       v1.8.5
raspi002   Ready     <none>    1m        v1.8.5
raspi003   Ready     <none>    1m        v1.8.5

以上でセットアップ完了です。

おわりに

以上の手順でkubeadmを利用することで簡単にRaspberry PIにKubernetesクラスタを構築することができます。みなさんもぜひ自宅にRaspberry PIでKubernetesクラスタを構築してみてください。