kuberntesのコンテナランタイムをcri-oに入れ替える

# はじめに
Raspberry Piの「おうちkubernetes」ですが、そろそろコンテナランタイムをcrioに入れ替えたくなってきました。
以前、記事にもしましたが、crioで新規ノード追加はしていたので、この方法でも良いのですが、ノードのdelete & joinでは今までの稼働時間を引き継げません。稼働時間を引き継ぐために、crioへの入れ替えをしてみたいと思います。
(※本文中のほとんどは「cri-o」を「crio」と記載しています)

# 前提と前準備

cephを利用している手前、kernelは別途ソースからビルドしていますが、ディストリビューションで提供しているkernelでも作業内容は大して変わらないのではないかと思います。

では、前準備として、cordonしてからdrainしておきます。(ノード指定のPodはdeleteしています。)

```
$ kubectl get nodes -o wide | grep chiya
chiya   Ready    worker                 449d   v1.22.0   10.0.0.5      <none>        Debian GNU/Linux 10 (buster)     5.10.52-v8+      docker://20.10.8
$ kubectl cordon chiya
$ kubectl drain chiya --ignore-daemonsets
$ kubectl get nodes | grep chiya
chiya   Ready,SchedulingDisabled   worker                 449d   v1.22.0
```


# dockerからcrioに変更

対象のノード(chiya)にログインしてrootになります。
以下は、rootでの作業です。

##dockerの削除

さようなら、docker。

```
# systemctl stop docker.socket
# systemctl stop docker
# apt remove docker-ce docker-ce-cli
# apt autoremove
```

##crio,podmanのインストール

どこかの公式手順＋αです。

```
# OS=Debian_10
# VERSION=1.22:1.22.1
# 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
deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/1.22:1.22.1/Debian_10/ /
# 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
deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /
# perl -pi -e 's/22:/22:\//' /etc/apt/sources.list.d/devel\:kubic\:libcontainers\:stable\:cri-o\:1.22\:1.22.1.list
# echo 'deb http://deb.debian.org/debian buster-backports main' >> /etc/apt/sources.list
# apt update
# apt -t buster-backports install libseccomp2
# apt install cri-o cri-o-runc podman-rootless
```

## crio関連の設定と起動

OSとkubeletの設定をします。

```
# systemctl enable crio
# 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
> vm.max_map_count = 262144
> EOF
# echo "br_netfilter" >> /etc/modules
# echo "KUBELET_EXTRA_ARGS=--cgroup-driver=systemd" >> /etc/default/kubelet
# echo 'KUBELET_KUBEADM_ARGS="--container-runtime=remote --container-runtime-endpoint=/var/run/crio/crio.sock"' > /var/lib/kubelet/kubeadm-flags.env
```

OS再起動。

```
# reboot
```

起動したら、kubectlが使えるクライアントからuncordonしましょう。

```
$ kubectl uncordon chiya
$ kubectl get nodes -o wide | grep chiya
chiya   Ready    worker                 449d   v1.22.0   10.0.0.5      <none>        Debian GNU/Linux 10 (buster)     5.10.52-v8+      cri-o://1.22.1
```

無事、稼働時間そのままでcrioに切り替わりました！

# 追記(2022/8/15)
kubeadmで1.24へアップグレードする際に、nodesリソースのannotationsにある、kubeadm.alpha.kubernetes.io/cri-socketをcrioのものに変更が必要な事を確認しました。

```yaml:
$ kubectl get nodes/chino -o yaml
apiVersion: v1
kind: Node
metadata:
  annotations:
      :
    kubeadm.alpha.kubernetes.io/cri-socket: unix:///var/run/crio/crio.sock
      :
```

# おまけ

環境依存かはわかりませんが、crioのノードで度々問題が起きるので、これまで遭遇したものをご参考までに書いておきます。

OSのreboot後に起動したPodでコンテナ間通信ができなくなる事があります。そのため、ノード上のPodを一度削除した方がよいかもしれません。特にflannelとnode-exporterのPodは削除してセルフヒーリングで再作成させておいた方いいです。RESTARTSが0の方が見栄えも良いですし...

```
$ kubectl get pods -o wide -A | grep chiya
kube-system      kube-flannel-ds-cqv5m                        1/1     Running     0              9m25s   10.0.0.5       chiya   <none>           <none>
kube-system      kube-proxy-cbl45                             1/1     Running     0              8m34s   10.0.0.5       chiya   <none>           <none>
monitoring       node-exporter-qhdwf                          2/2     Running     0              9m1s    10.0.0.5       chiya   <none>           <none>
```

ローカルにSSL化していないレジストリサーバがある場合は、crio.confに設定が必要になるかもしれません。

```
# cat /etc/crio/crio.conf
[crio.image]
registries = ['docker.io', 'quay.io', 'localhost:30500']
insecure_registries = ['localhost:30500']
```

Elasticsearchなどの一部のPodでは、コンテナ内でchrootしているらしく、crioのノードではsecurityContextでSYS_CHROOTをcapabilities.addする必要があるらしいです。

```
securityContext:
  capabilities:
    add: ["SYS_CHROOT"]
```

コンテナのimageはpodmanでも確認できますが、psは確認できません。基本的にcrictlを使用してください。
docker互換の操作でコンテナのビルドをしたい場合はpodmanを利用してください。

```
# podman images
REPOSITORY                           TAG           IMAGE ID      CREATED        SIZE
quay.io/prometheus/node-exporter     latest        bb203ba967a8  25 hours ago   22 MB
k8s.gcr.io/kube-proxy                v1.22.0       fef37187b238  4 months ago   99.4 MB
quay.io/coreos/flannel               v0.14.0       85fc911ceba5  6 months ago   68.1 MB
k8s.gcr.io/pause                     3.5           f7ff3c404263  8 months ago   491 kB
docker.io/ccrisan/motioneye          master-armhf  611591554283  18 months ago  331 MB
docker.io/carlosedp/kube-rbac-proxy  v0.5.0        f5fb70afc410  20 months ago  44.8 MB
# crictl images
IMAGE                                 TAG                 IMAGE ID            SIZE
docker.io/carlosedp/kube-rbac-proxy   v0.5.0              f5fb70afc410c       44.8MB
docker.io/ccrisan/motioneye           master-armhf        6115915542836       331MB
k8s.gcr.io/kube-proxy                 v1.22.0             fef37187b2389       99.4MB
k8s.gcr.io/pause                      3.5                 f7ff3c4042631       491kB
quay.io/coreos/flannel                v0.14.0             85fc911ceba5a       68.1MB
quay.io/prometheus/node-exporter      latest              bb203ba967a80       22MB
# crictl ps  -a
CONTAINER ID        IMAGE                                                                                                      CREATED             STATE               NAME                ATTEMPT             POD ID
63458a82e4d7d       docker.io/ccrisan/motioneye@sha256:1d7abea3e92e8cc3de1072a0c102a9d91ef2aea2a285d7863b1a5dadd61a81e1        23 minutes ago      Running             motioneye           0                   2dc18fe53add2
4803f8ed3f145       fef37187b2389b314196fc3dfaabd8e9a4d2124cc497ac672743ecb7c27d51e1                                           38 minutes ago      Running             kube-proxy          0                   9b79e03fb2a97
0bd68f60ee8ba       f5fb70afc410c0dd73f2fa76e6f16b7e7c4b0d0d088d2be44ed7e90951b0da2b                                           39 minutes ago      Running             kube-rbac-proxy     0                   14ba959338c72
b582af7dfe542       quay.io/prometheus/node-exporter@sha256:c4376d28a346a403dd6227b8d9d61b866b77c76e42fe8d54ed68632eb8cced6b   39 minutes ago      Running             node-exporter       0                   14ba959338c72
560d0648a74c3       85fc911ceba5a5a5e43a7c613738b2d6c0a14dad541b1577cdc6f921c16f5b75                                           39 minutes ago      Running             kube-flannel        0                   be1b6c28aad4b
71901ef126d17       85fc911ceba5a5a5e43a7c613738b2d6c0a14dad541b1577cdc6f921c16f5b75                                           39 minutes ago      Exited              install-cni         0                   be1b6c28aad4b
```

crioのノードはdockerに比べて色々問題が起きるので、たまにログやイベントを監視した方が良いと思ってます。