Raspberry Pi クラスター
Raspberry Pi を集めて、Kubernetes クラスターを作った。
コンテナランタイムは cri-o を、CNI は Flannel を利用した。
後述の参考のコピペがほとんど。
sudo がついてたりついてなかったりする。
以下の Ansible を見ればわかる。そのうち変わってるかも。
https://github.com/kamojiro/study/tree/main/raspberry_pi_cluster/ansible
基本的にはこれを書き下したものになるはず。
基本情報
ハードウェア
- Raspberry Pi B4 RAM 4GB × 3
- Switch Science で Raspberry Pi 4 スターターキット(4GB RAM版)を買った
- クラスターケース
- SDカード × 3
- スターターキットについてきたのと、家にあったやつ
- スイッチングハブ
- LANケーブル
- USB充電器
- USBケーブル
IP アドレスとか
raspberry pi | host | role | IP address | MAC address | disk |
4B | k8s-master | master | 192.168.10.101 | e4:5f:01:e2:59:e4 | |
k8s-worker1 | worker | 192.168.10.102 | e4:5f:01:e2:59:14 | 128GB | |
k8s-worker2 | worker | 192.168.10.103 | e4:5f:01:e2:5a:1e |
ネットワーク関連の設定
やらなくていいかも(よくわからずにやった)
/etc/netplan/99-network.yaml
network: version: 2 renderer: networkd ethernets: eth0: dhcp4: false dhcp6: false addresses: - 192.168.1.101/24 # ラズパイ毎でIPを変更してください。(末尾がそれぞれ101, 102, 103になります。) routes: # 自宅のルーターからゲートウェイを調べて下さい。ここを間違えるとラズパイはネットに繋がらなくなります… - to: default via: 192.168.10.1 nameservers: addresses: - 192.168.10.1
sudo netplan apply
ホスト名の変更
@raspberry_pi
ラズパイのOSインストール時に指定したので以下のコマンドは不要
sudo hostnamectl set-hostname <hostname> hostname
DNS的なののために、etc/hosts に追記
192.168.1.101 k8s-master kube-master.kamoj.com 192.168.1.102 k8s-worker1 kube-master1.kamoj.com 192.168.1.103 k8s-worker2 kube-worker2.kamoj.com
IPv6 の無効化
etc/sysctl.conf の最後に追記
net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.eth0.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1
timezone, keymap の変更
今回は OS インストール時に設定したので不要
# タイムゾーンの変更 sudo timedatectl set-timezone Asia/Tokyo # keymapの変更 sudo localectl set-keymap jp106
ssh
今回は OS インストール時に設定したので不要
cri-o
カーネルパラメーターの設定
sudo modprobe overlay # 必要なカーネルパラメータの設定をします。これらの設定値は再起動後も永続化されます。 cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 EOF sudo sysctl --system
準備
sudo apt install -y curl gnupg2 libseccomp2
cri-o のインストール
OS=xUbuntu_22.04 VERSION=1.25 echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list mkdir -p /usr/share/keyrings curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | apt-key add - curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add - apt update apt install -y cri-o apt install -y cri-o-runc
cri-o と cri-o-runc を並べてインストールしようと失敗する(?)
```bash sudo systemctl daemon-reload sudo systemctl start crio sudo systemctl enable crio systemctl status crio
コントロールプレーンノードの kubelet によって使用される cgroup ドライバーの設定
CRI の場合は、/etc/default/kubelet
KUBELET_EXTRA_ARGS=--cgroup-driver=systemd
sudo systemctl daemon-reload sudo systemctl restart kubelet
おまじない
再起動後とか、うまくいかないときはこれを再実行してみる。
sudo modprobe br_netfilter echo '1' > /proc/sys/net/ipv4/ip_forward
Kubernetes
requirements
VXLAN モジュールのインストール
Flannel で使うので。
sudo apt install -y linux-modules-extra-raspi
Flannel のデプロイ前までに再起動が必要。
cgroup で memory の有効化(よくわからない)
/boot/firmware/cmdline.txt の末尾に cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory を追記
おまじない
echo '1' > /proc/sys/net/ipv4/ip_forward
swap の無効化
sudo swapoff -a
iptables が nftables バックエンドを使用しないようにする
sudo apt install -y iptables arptables ebtables
# レガシーバイナリがインストールされていることを確認してください sudo apt install -y iptables arptables ebtables # レガシーバージョンに切り替えてください。 sudo update-alternatives --set iptables /usr/sbin/iptables-legacy sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy sudo update-alternatives --set arptables /usr/sbin/arptables-legacy sudo update-alternatives --set ebtables /usr/sbin/ebtables-legacy
準備
sudo apt install -y apt-transport-https curl
kubeadm、kubelet、kubectlのインストール
- kubeadm: クラスターを起動するubectl label node work02 node-role.kubernetes.io/worker=workerコマンドです。
- kubelet: クラスター内のすべてのマシンで実行されるコンポーネントです。 Podやコンテナの起動などを行います。
- kubectl: クラスターにアクセスするためのコマンドラインツールです。
sudo apt update && sudo apt install -y apt-transport-https curl curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list deb https://apt.kubernetes.io/ kubernetes-xenial main EOF sudo apt update sudo apt install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl
Kubernetes クラスターの作成
コントロールプレーンの設定@master
sudo kubeadm init --apiserver-advertise-address=192.168.10.101 --pod-network-cidr=10.244.0.0/16
- apiserver-advertise-address
- このオプションを利用して明示的にAPIサーバーのadvertise addressを設定します。
- 明示的に指定しない場合はデフォルトゲートウェ 佐野なつイに関連付けられたネットワークインターフェースを使用して設定されます。
- pod-network-cidr
初期化後、kubeadm join 192.168.1.101:6443 --token ...という出力が出たら、どこかのテキストエディタにコピーしておきます。
このコマンドはワーカーノードを追加する際に利用します。
kubectl の設定
# ホームディレクトリに.kubeディレクトリを作成 mkdir -p ~/.kube # Kubernetesのadmin.confを.kubeディレクトリのconfigファイルへコピー sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config # configファイルの所有者がrootになっているのでk8suserへ変更 sudo chown $(id -u):$(id -g) ~/.kube/config # .bashrcへ環境変数の追加 echo 'KUBECONFIG=$HOME/.kube/config' >> ~/.bashrc # コマンドの入力補完を設定 echo "source <(kubectl completion bash)" >> $HOME/.bashrc # 変更を適用 source ~/.bashrc
Flannel のデプロイ@master
Flannel をデプロイするまでは、coredns は pending 状態になっている。
以下は、やってなかったらやっておく
sudo apt install -y linux-modules-extra-raspi sudo reboot
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl get pods -n kube-flannel
MetalLB のデプロイ
IaaS だと、type: LoadBalancer で IP アドレスを払い出してくれる。
そんな感じで、IP アドレスの自動割当をやってくる。
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml # ... kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
kubectl get pod -n metallb-system
ワーカーノードの追加
modprobe br_netfilter
sudo kubeadm join 192.168.1.101:6443 --token 3u2z7v.qx81p3azvu15ftzw --discovery-token-ca-cert-hash sha256:0e731a79605ba03cfbc823e86e8b81b2fcdcf7f1887c1d2d86239ed87fff8d04
kubectl get nodes
kubectl label node k8s-worker1 node-role.kubernetes.io/worker=worker kubectl label node k8s-worker2 node-role.kubernetes.io/worker=worker
kubectl get nodes
確認
$ kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 46h v1.26.0 k8s-worker1 Ready worker 33m v1.26.0 k8s-worker2 Ready worker 19m v1.26.0 $ kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-flannel kube-flannel-ds-dm67n 1/1 Running 0 33m kube-flannel kube-flannel-ds-hj2zl 1/1 Running 516 45h kube-flannel kube-flannel-ds-kx9c8 1/1 Running 0 20m kube-system coredns-787d4945fb-dhmzs 1/1 Running 0 46h kube-system coredns-787d4945fb-zjp28 1/1 Running 0 46h kube-system etcd-k8s-master 1/1 Running 1 46h kube-system kube-apiserver-k8s-master 1/1 Running 1 46h kube-system kube-controller-manager-k8s-master 1/1 Running 1 46h kube-system kube-proxy-5hxm7 1/1 Running 1 46h kube-system kube-proxy-8dtn8 1/1 Running 0 20m kube-system kube-proxy-xfrd2 1/1 Running 0 33m kube-system kube-scheduler-k8s-master 1/1 Running 1 46h metallb-system controller-577b5bdfcc-ql2fb 1/1 Running 1 (31m ago) 4h28m metallb-system speaker-j5shp 1/1 Running 0 19m metallb-system speaker-lfvxc 1/1 Running 0 32m metallb-system speaker-ttxpb 1/1 Running 2 (101m ago) 4h28m
おまけ
Kubernetes クラスターの削除
sudo kubeadm reset && rm ~/.kube/config && rm -r /etc/cni/net.d && sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X sudo kubeadm init --apiserver-advertise-address=192.168.10.101 --pod-network-cidr=10.244.0.0/16 sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config && sudo chown $(id -u):$(id -g) ~/.kube/config
参考文献
Raspberry Piをかき集めてKubernetesを体感する | フューチャー技術ブログ
Raspberry Pi で【リアル☆Kubernetes】を作る!!
Raspberry Pi 4 でおうちKubernetesを作ろう(Raspbian Buster Lite対応版) - Qiita
Raspberry Pi×4台によるKubernetesクラスター構築 Yu'n Craft
Raspberry Pi + MicroK8sで居室環境モニタリングシステムを構築してみました | NTTテクノクロスブログ
Raspberry PiでおうちKubernetesクラスタ
おうちKubernetes構築日記その1 Raspberry Pi編 - nownab.log
Raspberry Piで動かしていたKubernetesクラスターを壊した私(後半) | by gavin.zhou | Medium
Raspberry PiでおうちKubernetesクラスタを構築する - sambaiz-net
アドオンのインストール | Kubernetes
Creating a cluster with kubeadm | Kubernetes
GitHub - cri-o/cri-o: Open Container Initiative-based implementation of Kubernetes Container Runtime Interface
Raspberry Pi 4BにKubernetesをインストール(2021年版) - @uyorumの雑記帳