【Raspberry Pi】Kubernetes 環境の構築
はじめに
Raspberry Pi OS の 64bit 版に Lite バージョンが出ていたことに気づいたので、32bit 版で構成していた Raspberry Pi 4 Model B での Kubernetes 環境を新たに64bit 版で再構築してみました。
ちなみに、インストール手順については以下のページを参考にさせていただいています。
- https://kubernetes.io/docs/setup/production-environment/
- https://qiita.com/yyojiro/items/0cd7ec7e2a39610be53f
準備
SDカード書き込み
Raspberry Pi 公式の Raspberry Pi Imager を使用して Raspberry Pi OS (64bit 版) Lite をSDカードに書き込みます。Pi 4 が 4台あるので SD カードの書き込みも 4 回実施。
SSH有効化
Pi 4 にモニターやキーボードを接続していないため、予め SSH を有効にする必要があります。SD カードに OS イメージを書き込んだ後、SD 上の boot パーティションに「ssh」という名前の空ファイルを置くことで自動的に ssh でのログインが有効になります。
DHCP 割り当て設定
ネットワークへの接続には有線 LAN を使い、IP アドレスの割り当ては DHCP で行います。各ボードの MAC アドレスは既に DHCP サーバに登録してあるので、固定 IP を割り当てることができるようにしています。
ちなみに IP アドレスとホスト名の対応は以下のような感じです。
192.168.0.21 pi4b01 192.168.0.22 pi4b02 192.168.0.23 pi4b03 192.168.0.24 pi4b04
Raspberry Pi を設定する
初期設定
各ボードで raspi-config を使って、このへんの初期設定を行います。
- パスワード変更
- ホストネーム変更
- ロケール変更
- TimeZone 設定
/etc /hosts ファイルも編集しておきます。
- 127.0.1.1 の行を削除
- 各ボードに割り当てた IP アドレスの設定を追加する
192.168.0.21 pi4b01 192.168.0.22 pi4b02 192.168.0.23 pi4b03 192.168.0.24 pi4b04
Docker をインストールする
sudo apt-get update sudo apt-get -y upgrade sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common gnupg2
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
sudo無しでdockerを利用できるようにするには「 sudo usermod -aG docker $USER」で自分を docker グループに追加します。 こうすることで次回のログインから docker コマンドが su なしで利用可能になります。
Kubernetes をインストールする
iptables の設定
Kubernetes 用の 設定が必要そうなので以下の作業をしておきます。
cat << EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sudo sysctl --system
Cgroup の memory グループを有効にする
cat /proc/cgroups をすると memory グループが無効になっているので、 /boot/cmdline.txt の行の末尾に 以下の設定を追加します。追加する際は改行を入れずに一行にする必要があります。
cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory
この設定が有効になるように、ここで reboot します。
kubeadm, kubelete, kubectl をインストールする
sudo apt-get update && sudo apt-get 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-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl
swap を停止する
swap があると kubernetes の設定ができないので swap は無効にしておきます。
sudo dphys-swapfile swapoff sudo dphys-swapfile uninstall sudo update-rc.d dphys-swapfile remove sudo systemctl stop dphys-swapfile sudo systemctl disable dphys-swapfile
ここまでは全ボード共通で行う作業です。
Master ノードの設定
ここでは pi4b01 を Master ノードとして設定します。Pod ネットワークには Flannel を使う例が多いようなので、ここでも Flannel を使いました。また、ロードバランサーは MetalLB を使用します。
- 初期化する
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
pi@pi4b01:~ $ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 W1003 20:59:40.066256 7995 configset.go:348] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io] [init] Using Kubernetes version: v1.19.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 [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 pi4b01] and IPs [10.96.0.1 192.168.0.21] [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 pi4b01] and IPs [192.168.0.21 127.0.0.1 ::1] [certs] Generating "etcd/peer" certificate and key [certs] etcd/peer serving cert is signed for DNS names [localhost pi4b01] and IPs [192.168.0.21 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 [apiclient] All control plane components are healthy after 37.511892 seconds [upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace [kubelet] Creating a ConfigMap "kubelet-config-1.19" 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 pi4b01 as control-plane by adding the label "node-role.kubernetes.io/master=''" [mark-control-plane] Marking the node pi4b01 as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule] [bootstrap-token] Using token: dznswr.altmxn5ip8qwbpgf [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 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.0.21:6443 --token dznswr.altmxn5ip8qwbpgf \ --discovery-token-ca-cert-hash sha256:c12a398a8acb4d2069b367980a0db018b2a4454a4a3a7e5d0544ac9d13eb269e
メッセージに従って以下のコマンドを入力します。
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
- Flannel を導入する。
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
- MetalLB を導入する
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.4/manifests/namespace.yaml kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.4/manifests/metallb.yaml # On first install only kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
適当なディレクトリに以下の内容で config.yaml というファイルを作成します。 address の部分は DHCP と被らない範囲をテキトーに設定しています。
apiVersion: v1 kind: ConfigMap metadata: namespace: metallb-system name: config data: config: | address-pools: - name: default protocol: layer2 addresses: - 192.168.0.60-192.168.0.69
kubectl apply -f config.yaml
Worker ノードの設定
Master ノードを初期化した際のログに書かれているコマンドを各 Worker ノードで実行します。
sudo kubeadm join 192.168.0.21:6443 --token dznswr.altmxn5ip8qwbpgf --discovery-token-ca-cert-hash sha256:c12a398a8acb4d2069b367980a0db018b2a4454a4a3a7e5d0544ac9d13eb269e
このコマンドを実行後、Master ノードで各ノードの状態を見ることができます。
kubectl get nodes
おわりに
今回はOSからの再インストールということで Rasberry Pi OS Lite の 64 bit 版を使ってみましたが、32 bit 版の時と何ら変わることなくOSインストールや Kubernetes の設定ができました。このまま 64bit 版の環境で使ってみようと思います。