仮想化通信

日本仮想化技術株式会社の公式エンジニアブログ

cri-dockerdを使ってKubernetes 1.24を動かしてみる

Kubernetes 1.24がリリースされ、dockershimコンポーネントが削除されました。 これはKubernetes 1.24以降のバージョンでDockerをランタイムとして使うことができないことを意味します。

ところで、dockershimが削除されることは結構前から告知されていました(1.20にリリースをもって非推奨になりました)。とうとうそれが今回実行されたということです。

それでは困るという需要に応えるために、Dockerのエンタープライズ事業を継承したMirantisがOSSでcri-dockerdを開発しています。

github.com

今回はこれを使って、KubernetesでDockerをランタイムとして使ってみたいと思います。

動作環境について

今回はテスト環境のベースOSとして、Ubuntu 18.04.6 LTSを使っています。

Ubuntu 22.04 LTSの場合はCgroup version 2の部分を設定の上実行すれば同じように動作すると思います。

[7/8/2022 追記]

Ubuntu 22.04 LTSでも動作することを確認しました。

本記事は次のバージョンのDockerとcri-dockerdを想定しています。

$ docker --version
Docker version 20.10.17, build 100c701
$ cri-dockerd --version
cri-dockerd 0.2.3 (HEAD)

それでは実際に試してみます。

Dockerのインストール

次に従って、UbuntuにDocker Engineをインストールします。基本的に公式の手順に従ってインストールするだけです。

cri-dockerdのインストール

次に従って、cri-dockerdをインストールします。 cri-dockerdはDockerとKubeletをつなぐコンポーネントです。Docker自身はKubenetesのCRI規格には標準で対応していないため、cri-dockerdがそれらを仲介します。

cri-dockerdはパッケージは特に用意されていないので、次の流れでGolangとcri-dockerdをビルドした上でインストールします。root権限で実行する必要があるそうです(権限周りはいずれ調査することにしましょう)。

###Install GO###
wget https://storage.googleapis.com/golang/getgo/installer_linux
chmod +x ./installer_linux
./installer_linux
source ~/.bash_profile

###Install cri-dockerd###
git clone https://github.com/Mirantis/cri-dockerd.git
cd cri-dockerd
mkdir bin
go get && go build -o bin/cri-dockerd
mkdir -p /usr/local/bin
install -o root -g root -m 0755 bin/cri-dockerd /usr/local/bin/cri-dockerd
cp -a packaging/systemd/* /etc/systemd/system
sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service
systemctl daemon-reload
systemctl enable cri-docker.service
systemctl enable --now cri-docker.socket

サービスを確認し、サービスとして動いていることを確認します。

$ systemctl status docker cri-docker.socket|egrep "Loaded|Active"
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2022-07-05 07:18:39 UTC; 7min ago
   Loaded: loaded (/etc/systemd/system/cri-docker.socket; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2022-07-05 07:18:36 UTC; 7min ago

Dockerをインストールした時点で、dockerサービスとcontainerdサービスは実行されていると思います。 cri-docker.socketもちゃんと動作していることを確認します。

K8sツールのインストール

kubeadm,kubectl,kubeletをインストールします。執筆時点では1.24.2がインストールされました。

[07/08/2022 追記]

インストールした後、「Forwarding IPv4 and letting iptables see bridged traffic」に従って、設定を変更します。

また次に従ってスワップを無効にします。

$ sudo vi /etc/fstab  #スワップパーティションをコメントアウト 
$ sudo swapoff -a    #SWAPをオフ

クラスターの作成

kubeadmによるクラスター作成を行います。

いつものように実行したところ...

$ sudo kubeadm init --kubernetes-version 1.24.2 --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=172.17.28.71

こう言ったエラーが出ました。

$ sudo kubeadm init --kubernetes-version 1.24.2 --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=172.17.28.71
Found multiple CRI endpoints on the host. Please define which one do you wish to use by setting the 'criSocket' field in the kubeadm configuration file: unix:///var/run/containerd/containerd.sock, unix:///var/run/cri-dockerd.sock
To see the stack trace of this error execute with --v=5 or higher

Dockerdが動いていれば、通常containerdも動作します。cri-dockerdを見ても、サービス云々をどうするといった話は書いていませんでしたので、kubeadm init--cri-socketオプションを追加してみました。

$ sudo kubeadm init --kubernetes-version 1.24.2 --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=172.17.28.71 --cri-socket=unix:///var/run/cri-dockerd.sock
[init] Using Kubernetes version: v1.24.2
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
...
[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!

今度はどうやらクラスタ作成はうまくいきました。

一台のマシンでクラスターとして動かしたいので いつものように次のように実行し...

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

$ kubectl taint nodes --all node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master-
node/bay15-gen9 untainted

クラスターがReadyになったことを確認します。

$ kubectl  get no
NAME         STATUS   ROLES           AGE     VERSION
bay15-gen9   Ready    control-plane   4m58s   v1.24.2

[7/8/2022 追記]

ノードを追加する場合はkubeadm joinを実行しますが、ここでも--cri-socketを指定します。

$ sudo kubeadm join ... --cri-socket=unix:///var/run/cri-dockerd.sock

実行例(トークンはマスクしています)

$ sudo kubeadm join 172.17.28.62:6443 --token hogehuga --discovery-token-ca-cert-hash sha256:hogehuga --cri-socket=unix:///var/run/cri-dockerd.sock

$ kubectl get no -o wide
NAME         STATUS   ROLES           AGE     VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE           KERNEL-VERSION      CONTAINER-RUNTIME
bay10-gen9   Ready    control-plane   10m     v1.24.2   172.17.28.62   <none>        Ubuntu 22.04 LTS   5.15.0-40-generic   docker://20.10.17
bay15-gen9   Ready    <none>          8m35s   v1.24.2   172.17.28.71   <none>        Ubuntu 22.04 LTS   5.15.0-40-generic   docker://20.10.17

コンテナランタイムがdocker://20.10.17になっていることが確認できる。

クラスターにネットワーク機能を追加

ネットワークアドオンをインストールします。今回はFlannelを使ってみます。

$ kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

クラスターの動作確認

Podを作ってみます。

$ kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4
$ kubectl get deployment -w
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
hello-node   1/1     1            1           24s

問題なく動作しました。 cri-dockerdを用いることで、Kubernetes 1.24でもDockerをランタイムとして使うことができました。

まとめ

一般的にはcontainerdやCRI-Oを使えば、多くのLinuxで問題なくKubernetesを動かせると思います。 この2つについてはパッケージが用意されているので、それを使えばいいだけなので。

しかし、どうしてもDockerをランタイムとして使いたいとか、Kubernetesと同じホストでDockerを動かしてアプリケーション実行やコンテナイメージ作成を集約したい、互換性の都合でどうしてもDockerじゃないと困ると言った場合は使えそうです。