K8s on ラズパイ(ARM64)にcri-o+podmanでworkerを追加してみた
はじめに
2020/12末時点で、kubernetesのworkerノードを「cri-o」と「podman」で構築してみた結果です。
環境
- Raspberry Pi 4B
- OS: RaspiOS Lite(ARM64) beta 2020/8/24 (※本手順では最終的にkernelの入れ替えをしています)
- kubernetes: v1.20.1 (※タイミング悪くv1.20.0のマスターにv1.20.1を追加してます)
構築した手順
- OS: RaspiOS Lite(ARM64) beta 2020/8/24 (※本手順では最終的にkernelの入れ替えをしています)
- kubernetes: v1.20.1 (※タイミング悪くv1.20.0のマスターにv1.20.1を追加してます)
メモ書き程度ですが、ご参考まで。
RaspiOS Lite(ARM64)をインストール後、ホスト名やネットワークの設定後の状態からです。
https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2020-08-24/
1. スワップ無効化
swap有効化のままでもkubeletがインストールできる方法もあるようですが、私は無効化してます。
dphys-swapfile swapoff
systemctl disable dphys-swapfile
2. cgroupsの設定
cgroups...kernelによってsysfs上の階層構成が変わったりしてたり、よくわかってません。
perl -pi -e "s/^/cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 /" /boot/cmdline.txt
3. cri-o,podmanのインストール
arm64のパッケージが含まれる最新バージョンが「1.18.3」のようです。コンパイルすればもっと最新が使えそうですがやってません。
OS=Debian_Unstable
VERSION=1.18:1.18.3
curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | sudo apt-key --keyring /etc/apt/trusted.gpg.d/libcontainers.gpg add -
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | sudo apt-key --keyring /etc/apt/trusted.gpg.d/libcontainers.gpg add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /
EOF
cat <<EOF | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /
EOF
ここまでは公式の手順で良いのですが、1.18.3は「1.18:/1.18.3」という階層にあるので修正します。
一旦「apt update」してエラーが出ないか確認しましょう。
perl -pi -e 's/18:/18:\//' /etc/apt/sources.list.d/devel\:kubic\:libcontainers\:stable\:cri-o\:1.18\:1.18.3.list
apt update
Debian10用にバックポートされた「libseccomp2」パッケージ用のリポジトリ追加です。
echo 'deb http://deb.debian.org/debian buster-backports main' >> /etc/apt/sources.list
apt update
パッケージのインストールをします。
dockerコマンドの代替えである「podman」はkubernetes関連のパッケージと競合しているようなので、「podman-rootless」をインストールします。
https://github.com/containers/podman/issues/5296
apt -t buster-backports install libseccomp2
apt install cri-o cri-o-runc podman-rootless
インストールできたらcrioサービスを有効化します。
systemctl enable crio
4. kubelet,kubeadm,kubectlのインストール
定番なので説明は書きませんが、「apt update」が失敗する事があるので、成功するまで「apt update」してます。
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" >> /etc/apt/sources.list.d/kubernetes.list
apt update
apt install kubelet kubeadm kubectl
バージョン指定でインストールする場合は以下のように指定できます。
apt install kubelet=1.20.0-00 kubeadm=1.20.0-00 kubectl=1.20.0-00
5. その他設定
必要なカーネルパラメータを追加しておきます。
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
必要な前提カーネルモジュールを定義しておきます。
echo "br_netfilter" >> /etc/modules
一応、nftablesを使わないようにします。詳しく調べてませんが、kube-proxyはnftablesで良くても、flannelがiptablesじゃなきゃダメなのかなと思ってます。
update-alternatives --set iptables /usr/sbin/iptables-legacy
dockerを利用しないので、iptablesのFORWARDのデフォルトポリシーはACCEPTのままなはずですが、DROPの場合はACCEPTに変更してください。
kubeletがcgroup-driverとしてsystemdを使うように設定します。
echo "KUBELET_EXTRA_ARGS=--cgroup-driver=systemd" >> /etc/default/kubelet
本記事前提OSのカーネル以外の場合は、この状態でrebootして「kubeadm join」すればうまく動くかもしれません。
6. kernelの入れ替え
RaspiOS Lite(ARM64)の場合は、カーネルがよろしくないようでkubernetesクラスタに参加できてもPodがデプロイされませんでした。
具体的には「〜cpu.cfs_period_us: permission denied」と出てPodのデプロイに失敗します。
調べると以下の記事を発見しました。(最初からここ見ればよかったなぁ〜)
https://gist.github.com/dmesser/b110d717b372e36607b3fb75b52ab0ca
ただ、実際カーネルを調べると「CONFIG_CFS_BANDWIDTH」は有効になっているはずなのですが、/procや/sysの階層がkubeletが想定しているような階層になっていないように思えました。
どちらにせよ、おそらくカーネルを再コンパイルしなくてはならないと思われますが、Cephを導入した際にrbdを有効にしたカスタムカーネルがあったので、試しに入れ替えたらうまく動きました。
カーネルをコンパイルした手順は以下になります。
https://qiita.com/Y-Shikase/items/c6fffbbd11a3d039b380#kernel%E3%83%93%E3%83%AB%E3%83%89
上記手順でカーネルを入れ替えて再起動後、「kubeadm join」でうまくクラスタへの参加とPodのデプロイができました。
# kubeadm token create
cbrhlc.ckwxfkt2zfv75b4b
# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
9dce510f61f13a841dc94fd43d27c5264a76c671deae350363069c6e43c04879
tokenとhashをメモる。
kubeadm join 10.0.0.1:6443 --token cbrhlc.ckwxfkt2zfv75b4b --discovery-token-ca-cert-hash sha256:9dce510f61f13a841dc94fd43d27c5264a76c671deae350363069c6e43c04879
注意点
自炊イメージを使用している場合
dockerでコンテナイメージを自炊して、kubernetes上で使っている場合には少し注意が必要です。
dockerではリポジトリに階層を付けない事ができるのですが、podmanでは「localhost/」という階層が必ず付きますので、dockerとpodmanで混在している場合はpodman側に合わせなければなりません。
dockerのworkerでは自炊のイメージにエイリアスで「localhost/」のリポジトリ名を付けて、kubernetesのyamlも「image: lcoalhost/〜」としました。
kubeletのエラー
コンテナのデバッグ
cri-oの不具合でexecが実行できません。
https://github.com/cri-o/cri-o/issues/4280
ARM64向けの新バージョンのcri-oが出るのを待つか、最新を自分でコンパイルする必要がありそうです。
[追記]
再構築する前にダメ元でxUbuntu用のcri-o 1.20.0をインストールしたらデバッグできるようになりました。
wget http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/1.20/xUbuntu_20.04/arm64/cri-o_1.20.0~0_arm64.deb
dpkg -i cri-o_1.20.0~0_arm64.deb
また、1.20.0にしたからかはちゃんと確認してませんが、イベントに以下のWarningが定期的に出るようになりました。
$ kubectl get events -A -w
:
default 0s Warning ImageGCFailed node/maya failed to get imageFs info: non-existent label "crio-images"
kubeletのログは以下のようなログが出ます。
Jan 3 00:00:52 maya kubelet[455]: E0103 00:00:52.287957 455 log_metrics.go:66] failed to get pod stats: failed to get imageFs info: non-existent label "crio-images"
対策は、以下のissuesに書かれているように、サービス起動ファイルの[Unit]に「Before=kubelet.service」を追記しましょう。
https://github.com/cri-o/cri-o/issues/4437
dockershim vs cri-o
大袈裟な書き方ですが、同じHW構成でコンテナランタイムだけ違うworkerの無風状態での負荷を比較しました。
Loadがdockerは1.2くらいの平均で、cri-oは0.6くらいの平均になりました。cri-oは100MBくらいメモリ使用量も少なかったです。
podmanについて
まだ使い込んでないのですが、Dockerfileからのbuildができたので、docker互換として使えるようです。
「images」はそのまま使えましたし、「load/save」も使えそうです。
ただ、「ps」は表示されません。
CRI経由で作成されたものだからかもしれませんが、crictlコマンドで表示できました。
おわりに
色々試しましたが以下のような結果になりました。
・podmanでDockerfileからのbuild、イメージのsave/loadはできたので、脱dockerはできそう
・負荷はdockerより軽い
・cri-o 1.18.3では不具合によりコンテナのデバッグできない→xUbuntu用のcri-o 1.20.0で動いた!?
新バージョンのcri-oをコンパイルする元気が無かったので、個人的には「もう少し待った方がいいかなー」という感じでした。
Author And Source
この問題について(K8s on ラズパイ(ARM64)にcri-o+podmanでworkerを追加してみた), 我々は、より多くの情報をここで見つけました https://qiita.com/Y-Shikase/items/a0e46270b4c53f0b3f39著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .