自分の所属している会社、LAPRAS (opens new window)で夏の自由研究リレーを行っているので今回はそれに便乗して最近やってるネタを書いてみます。
多くの人がもうすでにやっているネタではあるのですが、Raspberry Pi 上に Kubernetes クラスタを構築してみました。大抵の人は Raspbian(現 Raspberry Pi OS)を使って構築しているみたいでしたが、自分はあんまりやってる人を見かけなかった Arch Linux での構築にチャレンジしてみました。
ハードウェアは以下のものを用意しました。
名称 | 単価 | 個数 |
---|---|---|
Raspberry Pi 4 4GB | 6100 | 3 |
Anker PowerPort Speed 4 | 2999 | 1 |
Buffalo LSW6-GT-5EPL/NBK | 1280 | 1 |
積層ケース | 2759 | 1 |
USB Type-C ケーブル | 699 | 3 |
LAN ケーブル | 781 | 3 |
Micro SD カード 32GB | 1080 | 3 |
大体 3 万円越えるぐらいになりました。
まずはハードウェアの準備をします。
積層ケースを購入したので一つずつ Raspberry Pi を固定してヒートシンクを接着し、ケースにファンを取り付けていきます。
ネジ止めなど意外と根気がいるのでそれなりに余裕を持って作業すると良いです。
全部設置できると見た目がかっこいい何かができます。正直これだけでも満足度が高いです。
Micro SD に ArchiLinux をインストールしていきます。
だいたい公式のページ (opens new window)にやり方は載っていますし、過去別のブログで書いた (opens new window)のですが、あらためて簡単に手順を書いていきます。
wget http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-4-latest.tar.gz
で最新の ArchLinux を取得するbsdtar -xpf ArchLinuxARM-rpi-4-latest.tar.gz -C root
で root にインストールし最後に sync
を実行するmv root/boot/* boot
で boot の中身を boot 用パーティションにコピーするこれで SD カードへのインストールは完了です。Raspberry Pi は 3 台あるので 3 台分繰り返します。
このインストール作業時に予め公開鍵をコピーして配置しておくとあとは作業端末から ssh で接続して作業できるので楽です。
インストールが終わった MicroSD はそれぞれ Raspberry Pi に刺して電源を入れておきます。
OS の準備ができたので Kubernetes をインストールする準備をします。
まず IP を固定したいのですが肝心の RaspberryPi の IP がわからないので ssh で接続できません。
このときは nmap を使用して強引に特定しました。
$ sudo nmap -sP 192.168.1.0/24
...
Nmap scan report for 192.168.1.2
Host is up (0.00021s latency).
MAC Address: CC:CC:CC:CC:CC:CC (Raspberry Pi Trading)
Nmap scan report for 192.168.1.3
Host is up (0.00023s latency).
MAC Address: BB:BB:BB:BB:BB:BB (Raspberry Pi Trading)
Nmap scan report for 192.168.1.4
Host is up (0.00019s latency).
MAC Address: AA:AA:AA:AA:AA:AA (Raspberry Pi Trading)
...
MAC Address の行に Raspberry Pi Trading と書いてアレば Raspberry Pi なのでそこで IP を特定し ssh 接続し作業を開始します。
まずは IP の固定を行います。 /etc/systemd/network/eth0.network
を次のように編集し IP を固定します。
[Match]
Name=eth0
[Network]
Address=192.168.1.1/24
Gateway=192.168.1.2
DNS=8.8.8.8
これを 3 台分繰り返し固定します。
次に ArchLinux のパッケージ管理ツール pacman の設定を行います。次のコマンドを実行し pacman を使えるようにします。
$ pacman-key --init
$ pacman-key --populate archlinuxarm
これを 3 台分繰り返します。
次に cgroup や docker などは AUR からインストールする必要があるので AUR ヘルパーの yay をインストールします。次のコマンドでインストールします。
$ git clone https://aur.archlinux.org/yay.git
$ cd yay
$ makepkg -si
これを 3 台分繰り返します。
yay を使用し cgroup と docker をインストールし有効化します。
$ yay -Sy cgroup docker
$ sudo systemctl enable docker.service
$ sudo systemctl enable cgconfig.service
cgroup は起動オプションが必要になるので /boot/cmdline.txt
に次の設定を追記します。
cgroup_enable=cpuset cgroup_memory=memory cgroup_memory=1
これを 3 台(以下略
次に yay を使用し kubernetes が利用するネットワーク関連のパッケージをインストールします。
$ yay -S ethtool ebtables socat conntrack-tools
これを 3(以下略
これで Kubernetes をインストールする準備が整いました。Raspberry Pi の台数分作業が繰り返しになるので Ansible などを使って自動化したほうが良さそうです。
いよいよ Kubernetes のインストールです。通常は yay を使ってインストールするのが良いのですが、自分の場合 yay だとうまくいきませんでした。なのでパッケージ管理システムによらないインストール方法でインストールを行います。インストール時の URL で CPU のアーキテクチャの文字列を arm にするのがポイントです。
まずは CNI Plugins をインストールします。
$ CNI_VERSION="v0.8.2"
$ sudo mkdir -p /opt/cni/bin
$ curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-arm-${CNI_VERSION}.tgz" | sudo tar -C /opt/cni/bin -xz
次に kubeadm kubelet kubectl をインストールします。
$ DOWNLOAD_DIR=/usr/local/bin
$ sudo mkdir -p $DOWNLOAD_DIR
$ RELEASE="$(curl -sSL https://dl.k8s.io/release/stable.txt)"
$ cd $DOWNLOAD_DIR
$ sudo curl -L --remote-name-all https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/arm/{kubeadm,kubelet,kubectl}
$ sudo chmod +x {kubeadm,kubelet,kubectl}
$ RELEASE_VERSION="v0.2.7"
$ curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service
$ sudo mkdir -p /etc/systemd/system/kubelet.service.d
$ curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
これで Kubernetes 関連ツールのインストールは完了です。
ここまできたらコマンドは問題なく実行できます。kubeadm を使ってクラスタを構築していきます。
次のコマンドで master node をセットアップします。
$ 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 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.1.2:6443 --token xx --discovery-token-ca-cert-hash sha256:xx
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
master node のセットアップがこれで完了します。
次にワーカー node を次のコマンドで登録していきます。
$ kubeadm join 192.168.1.2:6443 --token xx --discovery-token-ca-cert-hash sha256:xx
今回はワーカーノードが2つなので2回繰り返します。
この状態で master ノードで kubectl を実行してみます。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-01 NotReady master 13m v1.18.5
k8s-node-01 NotReady <none> 2m15s v1.18.5
k8s-node-02 NotReady <none> 100s v1.18.5
いったんすべてのノードを確認することができます。
ただこの状態だとまだ NotReady で正しく構築できていません。kube-dns がまだ動いていないのが原因です。kube-dns を正しく動かすためにネットワークの設定を行います。
Kubernetes のネットワーク周りで今回は flannel を使います。flannel は普通に kubectl を使用してデプロイを行います。
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
これで問題なければ、kube-dns が正しく動き各 node が Ready になります
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-01 Ready master 13m v1.18.5
k8s-node-01 Ready <none> 2m15s v1.18.5
k8s-node-02 Ready <none> 100s v1.18.5
これで Kubernetes の環境が整いました。あとはアプリケーション作ってデプロイしたりするだけです。
ざっと Raspberry Pi で Kubernetes クラスタを作成する手順を書いていきました。ちょっといろいろ端折ったりまとめ方が拙いのでそのうちリライトする予定です。
とりあえず最後に言いたいこととしては、Raspberry Pi で Kubernetes クラスタを作るのは楽しいので暇とお金がある方はぜひ試してほしいです。