This page looks best with JavaScript enabled

おうちKubernetesでたわむれる (1) ~クラスタ構築編~

 ·  ☕ 7 min read  ·  ✍️ [Capr1]

おうちKubernetesでたわむれる (1) ~クラスタ構築編~

おうちKubernetes とは

明確な定義はありませんが、Raspberry Pi を複数台使って、Kubernetesが稼働する手のひらサイズのハードウェアを指します.

サイバーエージェントの青山さんがよくやられてますね.

おうちで「おうち Kubernetes インターン」を実施しました
https://developers.cyberagent.co.jp/blog/archives/27443/

Raspberry Pi とは

イギリスのRaspberry Pi財団が開発しているARMプロセッサを搭載した小型コンピューターです.三千円ぐらいから入手できるので、主に、教育用途や、IoT・組み込み用途に使われています.

Raspberry Pi
https://ja.wikipedia.org/wiki/Raspberry_Pi

材料

おうちKubernetes作成に使った材料一覧です.

材料備考
Raspberry Pi 4 4GB 4台そこら辺に落ちてた
microSD 32GB 4枚そこら辺に落ちてた.
16GBだと容量不足で構築できないので注意   
BUFFALO スイッチングハブAmazonで買った
LANケーブル 4本そこら辺に落ちてた
USB Type-A - USB Type-C ケーブル 4本そこら辺に落ちてた
USB充電器 50W/10A ACアダプター 5ポートAmazonで買った
Raspberry Pi 4 クラスターケースAmazonで買った

組み立て

ラック組み立て・Raspberry Pi配置・ケーブリングを経て、こんな感じに組み立て上がりました.手のひらサイズの空冷サーバラックです.
配線周りをもう少し綺麗にしたいですね.

home-k8s01

環境

OS・ツール備考
Raspbian Buster Lite2020-12-02版(現時点で最新版)
Kubernetesversion:1.20.1(現時点で最新版)

OS導入・Raspberry Pi起動と接続

次に、Raspberry Pi に Raspbian OS を導入していきます。全Raspberry Piに対して作業が必要です

OSイメージの書き込み

まず、microSDカードをMacに差し込み、OSイメージを書き込んでいきます.
以下から Raspbian Buster Lite をダウンロードします.今回は2020-12-02版を使いました.

https://www.raspberrypi.org/software/operating-systems/

次にmicroSDのフォーマットをしていきます.
今回はSD Card Formatterを使ってフォーマットしていきます.

home-k8s02

次にmicroSDにOSイメージを書き込みます.
今回はbalenaEthcerを用いてイメージを書き込みます.

home-k8s03

次にsshを有効化させるために、microSD内に「ssh」という名前の空のファイルを作成します.
Raspbian では、セキュリティを考慮してデフォルトでは sshd が無効になっています.ボリュームの root直下にsshという名前の空ファイルを作成すると、Raspbian OS起動時に sshd が有効になります.

最後にcgroupsを有効にします。
cmdline.txt の 末尾に cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 を追加します.

home-k8s04

Raspberry Piの起動

まず、1番上のRaspberry Piに OS書き込み済みの MicroSDカード を挿し込んで電源を入れます.

無線LANに接続した Mac 上で、arp -a を打つなどして、起動してきた Raspberry Pi に払い出されたIPにあたりをつけましょう.
下記の例だと192.168.xxx.13ですね

$ arp -a
・・・
? (192.168.xxx.13) at dc:a6:32:71:16:47 on en0 ifscope [ethernet]
・・・

Pingが返ってきたら、おそらくそれは一番上の Raspberry Pi に割り振られたIPなので、そのIPに対してSSHします。Defaultのユーザ名とパスワードは piraspberry です.

$ ssh pi@192.168.xxx.13
The authenticity of host '192.168.xxx.13 (192.168.xxx.13)' can't be established.
ECDSA key fingerprint is SHA256:tvA3Tz4At5mfA+23lkUq/lRv43gGghfbq0Dlgami+fE.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.xxx.13' (ECDSA) to the list of known hosts.
kentarok@192.168.xxx.13's password:
Linux k8s-worker1 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

IP固定化

ログインしたら固定IPを設定します.今回は以下のように設定します.

役割IPホスト名
Master Node192.168.xxx.201k8s-master
Worker Node192.168.xxx.202k8s-worker1
Worker Node192.168.xxx.203k8s-worker2
Worker Node192.168.xxx.204k8s-worker3
$ sudo nano /etc/dhcpcd.conf

・・・
interface eth0
static ip_address=192.168.xxx.201/24
static routers=192.168.xxx.1
static domain_name_servers=192.168.xxx.1 8.8.8.8
・・・

$

これをRaspberry Pi 4台分繰り返して、ネットワーク周りの設定は完了です.

OS初期設定

次に、Kubernetes導入前の下準備をOSに対して設定します.この作業は全てのNodeに対して必要です.

OS更新

Raspbian OS を最新化します.

$ sudo apt-get update \
  && sudo apt-get -y dist-upgrade \
  && sudo apt-get -y autoremove \
  && sudo apt-get autoclean

ホスト名変更

事前に予定していた通りに、ホスト名をそれぞれ設定していきます.
ついでに自分以外のNodeの名前も教えます.

$ sudo hostnamectl set-hostname k8s-master
$ sudo vi /etc/hosts
127.0.1.1       k8s-master
192.168.xxx.201  k8s-master
192.168.xxx.202  k8s-worker1
192.168.xxx.203  k8s-worker2
192.168.xxx.204  k8s-worker3

iptables バージョン変更

Installing kubeadmに記述があったので、先行してやっておきます.

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#ensure-iptables-tooling-does-not-use-the-nftables-backend

$ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy

swap 無効化

kubelet の要件で、swap は無効化します.

$ sudo dphys-swapfile swapoff
$ sudo systemctl stop dphys-swapfile
$ sudo systemctl disable dphys-swapfile

ssh鍵交換

Macから各Nodeにログインしやすくするために、Mac上で作った公開鍵をそれぞれのNodeに登録します.(これはMacから各Nodeに対して行います.)

$ ssh-copy-id -i /Users/xxxxxxxxxxxxx/.ssh/sl_rsa.pub pi@192.168.xxx.201

パスワードログイン無効化

公開鍵認証にしたので、パスワードログインは無効化します.

$ sudo vi /etc/ssh/sshd_config
PasswordAuthentication no

おまけに pi ユーザーのパスワードも削除しておきます.

$ sudo passwd -d pi

Kubernetes関連パッケージの導入

OS側の設定が終わったので、Kubernetesのコンポーネントを導入していきます.この作業は全てのNodeに対して必要です.

Docker導入

以下のコマンドを実行してDockerをインストールします.

$ curl -sSL https://get.docker.com | sh

導入したDockerのバージョンを確認します.

$ docker version
Client: Docker Engine - Community
 Version:           20.10.2
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        2291f61
 Built:             Mon Dec 28 16:18:13 2020
 OS/Arch:           linux/arm
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.2
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       8891c58
  Built:            Mon Dec 28 16:15:48 2020
  OS/Arch:          linux/arm
  Experimental:     false
 containerd:
  Version:          1.4.3
  GitCommit:        269548fa27e0089a8b8278fc4fc781d7f65a939b
 runc:
  Version:          1.0.0-rc92
  GitCommit:        ff819c7e9184c13b7c2607fe6c30ae19403a7aff
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Dockerのバージョンを固定します.

$ sudo apt-mark hold docker-ce
docker-ce set on hold.

最後に、piユーザーにDockerコマンド実行権限を付与します.

$ usermod -aG docker pi

kubeadm、kubectl、kubelet 導入

Raspbian OS は Debian ベースとのことで、以下の手順に従って、作業を実施します.

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

$ sudo -i
$ apt-get update && apt-get install -y apt-transport-https curl
Hit:1 http://archive.raspberrypi.org/debian buster InRelease
Hit:2 http://raspbian.raspberrypi.org/raspbian buster InRelease
Reading package lists... Done
Reading package lists... Done
Building dependency tree
Reading state information... Done
apt-transport-https is already the newest version (1.8.2).
curl is already the newest version (7.64.0-4).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Kubernetes を提供しているリポジトリの設定をします.

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF | tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
$ exit
pi@k8s-master:~ $

kubelet、kubeadm、kubectlを導入します.

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

導入したバージョンを確認し、固定します.

$ sudo kubeadm version -o yaml
clientVersion:
  buildDate: "2020-12-18T12:07:13Z"
  compiler: gc
  gitCommit: c4d752765b3bbac2237bf87cf0b1c2e307844666
  gitTreeState: clean
  gitVersion: v1.20.1
  goVersion: go1.15.5
  major: "1"
  minor: "20"
  platform: linux/arm
  
$ sudo apt-mark hold kubelet kubeadm kubectl
kubelet set on hold.
kubeadm set on hold.
kubectl set on hold.

Master Nodeの構築

Master Nodeの初期化設定を行います.この手順はMaster Nodeでのみ実施します.

各ノードで実行されるPod同士が通信できるように、Node間でオーバーレイネットワークを展開します.これにより、PodとPodがノードを超えても通信できるようになります.Kubernetesでオーバーレイネットワークを展開するには、CNIプラグインを使います.CNI Pluginはいくつかありますが、今回はarmで動かしやすい(らしい)Flannelを利用します.

クラスタの初期化

Flannelを使用するため、Podネットワークは 10.244.0.0/16 を指定します.
最後に表示される kubeadm join コマンドは後で使うのでメモしておきます.

$ kubeadm init --pod-network-cidr=10.244.0.0/16
・・・
・・・
・・・
Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.xxx.201:6443 --token xxxxx.xxxxxxxxxxxxxxxxx \
    --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

kubectlの設定

kubectl の設定ファイルを配置します.

$ 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 get nodes
NAME         STATUS     ROLES                  AGE     VERSION
k8s-master   NotReady   control-plane,master   7m10s   v1.20.1

Flannelのインストール

Flannelをインストールします.

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

Worker Nodeのクラスタ参加

クラスタに Worker Node k8s-worker1 k8s-worker2 k8s-worker3 を参加させます.
先程、kubeadm init した際にメモした kubeadm join コマンドを実行します.

$ kubeadm join 192.168.xxx.201:6443 --token xxxxx.xxxxxxxxxxxxxxxxx \
    --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
・・・    
・・・
・・・

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 control-plane to see this node join the cluster.

Worker Node がちゃんとクラスタに参加したか確認します.

$ kubectl get nodes
NAME          STATUS   ROLES                  AGE    VERSION
k8s-master    Ready    control-plane,master   110m   v1.20.1
k8s-worker1   Ready    <none>                 97m    v1.20.1
k8s-worker2   Ready    <none>                 95m    v1.20.1
k8s-worker3   Ready    <none>                 95m    v1.20.1

最後に

このクラスタを使って色々遊ぶ予定.

参考サイト

Raspberry Pi 4 でおうちKubernetesを作ろう(Raspbian Buster Lite対応版)

Share on

Capr1/カプリ
WRITTEN BY
[Capr1]
Graduate Student / Department of Information Engineering