LoginSignup
2
5

More than 3 years have passed since last update.

Raspberry Piで自宅kubernetesクラスタを構築してみた

Posted at

はじめに

Raspberri Pi 4 (8GB)を3台使用してkubernetesクラスタを構築します。
物理的な構築の説明は省き、Raspberry Pi起動後のkubernetesクラスタの構築をメインに載せています。

構築は以下の記事を多分に参考にさせていただきました。

材料

材料はこちら。購入はすべてAmazonです。
USBケーブルだけ予備で1本余分で用意しました。
総額 42,003円でした。
image0.jpeg

材料 個数
Raspberry Pi 4 Model B (8GB) 3
Samsung EVO Plus マイクロSDカード 64GB 3
エレコム LANケーブル 0.3m 4
Anker USB Type C ケーブル 4
TP-Link ハブ TL-SG105E 1
サンワダイレクト USB充電器 50W 6ポート 1
積層式ケース for Raspberry Pi 4 / Pi 3 Model B+ 1

完成系がこちらです。
image1.jpeg

構築

環境

  • 作業用PC(ラズパイへのSSH)

    • Windows 10 Home
    • Tera Term
  • Raspberry Pi

    • Raspberry Pi 4 Model B (8GB)
    • Raspberry Pi OS Lite (2021-01-11)
  • kubernetesクラスタ

    • Masterノード1, Workerノード2の3台構成
  • kubeadm

    • v1.20.2

Raspberry Pi初期設定

SSHの設定とcgroupの設定は完了しているため省略しますが、設定自体は必須です。

ライブラリの更新をします。

$ sudo apt-get -y upgrade

スワップを無効化します。

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

ホスト名を修正します。

$ sudo vi /etc/hostname
raspi001

hostsファイルも修正します。

$ sudo vi/etc/hosts
127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

127.0.1.1       raspi001

残りの2台も同様にraspi002,raspi003にhostnameファイルとhostsファイルを修正します。

変更を反映するため再起動します。

$ sudo reboot

他の2台も同様に修正・再起動します。

ここまでは冒頭で紹介した他の方の記事と同じ内容です。

Dockerインストール

Dockerをインストールするのですが、docker-ceの最新バージョンをインストールしたところ、kubeadm initの実行時に次のような警告が出たためバージョンを指定してインストールします。おそらく無視して実行もできるのですが、メジャーバージョンをまたいでいるので念のため揃えます。

[WARNING SystemVerification]: this Docker version is not on the list of validated versions: 20.10.3. Latest validated version: 19.03

まずはパッケージをインストールします。

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

GPGキーを追加します。

$ 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

Dockerのドキュメントを参考に特定のバージョンのdocker-ceをインストールします。

まずは利用可能なバージョンを表示します。

$ apt-cache madison docker-ce
 docker-ce | 5:20.10.3~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:20.10.2~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:20.10.1~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:20.10.0~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.15~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.14~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.13~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.12~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.11~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.10~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.9~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.8~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.7~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.6~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.5~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.4~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.3~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.2~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages
 docker-ce | 5:19.03.1~3-0~raspbian-buster | https://download.docker.com/linux/raspbian buster/stable armhf Packages

19.03の最新バージョンを使うことにします。
バージョンを指定してインストールします。

sudo apt-get install docker-ce=5:19.03.15~3-0~raspbian-buster

これでバージョンの警告が出なくなりました。
他の2台にも同様にインストールします。

Kubernetesインストール

この辺は他の方の記事内容と同じです。

kubeadm, kubelet, kubectlをインストールします。

$ 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

他の2台にも同様にインストールします。

クラスタの構築

Masterノードの構築

kubeadm initを実行します。

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16
[init] Using Kubernetes version: v1.20.2
[preflight] Running pre-flight checks
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
        [WARNING SystemVerification]: missing optional cgroups: hugetlb
error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR Mem]: the system RAM (1 MB) is less than the minimum 1700 MB
        [ERROR Swap]: running with swap on is not supported. Please disable swap
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher

失敗しました。
WARNINGはとりあえず無視してERRORを解消していきます。

まず、次のエラーですが、こちらはissueが上がっていました。
32bitのマシンで4GBを超えるメモリを使用している場合に、誤ったメモリの値が返ってしまうバグのようです。

[ERROR Mem]: the system RAM (1 MB) is less than the minimum 1700 MB

コマンドに以下のオプションを加えることでエラーを回避できます。

  • --ignore-preflight-errors=Mem

実行します。

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Mem
[init] Using Kubernetes version: v1.20.2
[preflight] Running pre-flight checks
        [WARNING Mem]: the system RAM (1 MB) is less than the minimum 1700 MB
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
        [WARNING SystemVerification]: missing optional cgroups: hugetlb
error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR Swap]: running with swap on is not supported. Please disable swap
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher

エラーが出力されなくなりました。

続いてはこちらのエラー。
こちらもissueが上がっていました。

[ERROR Swap]: running with swap on is not supported. Please disable swap

swap-off -a コマンドで解消できるそうなので実行します。
このコマンドは他の2台でも実行しておきます。

$ sudo swapoff -a

再度kubeadm initを実行します。

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Mem
[init] Using Kubernetes version: v1.20.2
[preflight] Running pre-flight checks
        [WARNING Mem]: the system RAM (1 MB) is less than the minimum 1700 MB
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
        [WARNING SystemVerification]: missing optional cgroups: hugetlb
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local raspi001] and IPs [10.96.0.1 192.168.2.113]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost raspi001] and IPs [192.168.2.113 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost raspi001] and IPs [192.168.2.113 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[kubelet-check] Initial timeout of 40s passed.
[apiclient] All control plane components are healthy after 41.008727 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.20" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node raspi001 as control-plane by adding the labels "node-role.kubernetes.io/master=''" and "node-role.kubernetes.io/control-plane='' (deprecated)"
[mark-control-plane] Marking the node raspi001 as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: ndfm0v.fp1ywggjvsyvqc1e
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane 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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

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/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.2.113:6443 --token xxxxxxxxxxxxx \
    --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

うまくいきました。

次の出力に従いコマンドを実行します。

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

実行します。

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

flannelをインストールします。
flannelのドキュメントページはこちら

最新版をインストール。

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created

うまくいきました。

動いているか確認します。

$ kubectl get pods -n kube-system -o wide | grep flannel
kube-flannel-ds-86kzb              1/1     Running   0          88s   192.168.2.113   raspi001   <none>           <none>

確認できました。

Workerノードの構築

Masterノードでのkubeadm initコマンド実行時に出力された
kubeadm joinというコマンドをWorkerノード2台で実行します。

$ kubeadm join 192.168.2.113:6443 --token xxxxxxxxxx \
>     --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[preflight] Running pre-flight checks
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
        [WARNING SystemVerification]: missing optional cgroups: hugetlb
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

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

もう1台のWorkerノードでも同様に実行します。

3台目のWorkerノードでswapoff -aコマンドを忘れていたため次のようなエラーが出力されました。

[preflight] Running pre-flight checks
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
        [WARNING SystemVerification]: missing optional cgroups: hugetlb
error execution phase preflight: [preflight] Some fatal errors occurred:
        [ERROR Swap]: running with swap on is not supported. Please disable swap
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher

swapoff -aコマンドを実行したところうまくいきました。

MasterノードにWorkerノードが表示されているか確認します。

$ kubectl get nodes
kubectl get nodes
NAME       STATUS   ROLES                  AGE     VERSION
raspi001   Ready    control-plane,master   72m     v1.20.2
raspi002   Ready    <none>                 7m39s   v1.20.2
raspi003   Ready    <none>                 4m25s   v1.20.2

Workerノードが表示されました。

Workerノードにラベルを追加します。

$ kubectl label node raspi002 node-role.kubernetes.io/worker=worker
node/raspi002 labeled
$ kubectl label node raspi003 node-role.kubernetes.io/worker=worker
node/raspi003 labeled

再度ノードを確認してみます。

$ kubectl get nodes
NAME       STATUS   ROLES                  AGE     VERSION
raspi001   Ready    control-plane,master   75m     v1.20.2
raspi002   Ready    worker                 10m     v1.20.2
raspi003   Ready    worker                 6m52s   v1.20.2

ラベルが付与されました。

これでkubernetesクラスタが完成しました。

今後はこのクラスタを活用して色々検証していこうと思います。

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5