OCI Runtime の確認方法 - oomichi/try-kubernetes GitHub Wiki

Kubernetes では各ノードに配置された kubelet が CRI Runtime(Containerd, CRI-Oなど) を操作し、CRI runtimeがコンテナを OCI Runtime (runc, kata containerなど) でデプロイする。 kubectl コマンドでは以下のように CRI Runtime のみ確認でき、OCI Runtime を参照できない。

$ kubectl get nodes -o yaml
...
    nodeInfo:
      architecture: amd64
      bootID: 2df9a778-6245-4e49-8108-5999d83aed40
      containerRuntimeVersion: containerd://1.6.2
...

ここでは OCI Runtime の確認方法を記述する。

OCI Runtimeの変更

デフォルトでは RunC が OCI Runtime として使われるが、ここでは Kata Container を OCI Runtime として使い、Kata Container が使われていることを確認する方法を調べる。 Kubespray では以下の設定によって、簡単に Kata Container を利用できる環境を作れる。

kata_containers_enabled: true

なお、Kata Container は実際に動作する仮想マシン(コンテナの代替)として QEMU や Firecracker が利用可能だが、現時点で Kubespray (v2.18) では QEMU しか選択できないため、QEMU を利用する。

Kubespray では Vagrantfile が提供されているため、それを使って評価環境を作成する。 この Vagrantfile は特に指定しなければ inventory/sample 配下のインベントリが使われるため、ここではその配下のファイルで Kata Container を有効にしている。

$ git diff
diff --git a/inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml b/inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml
index 81984333..94dbd8c6 100644
--- a/inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml
+++ b/inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml
@@ -206,7 +206,7 @@ dns_domain: "{{ cluster_name }}"
 container_manager: containerd
 
 # Additional container runtimes
-kata_containers_enabled: false
+kata_containers_enabled: true
 
 kubeadm_certificate_key: "{{ lookup('password', credentials_dir + '/kubeadm_certificate_key.creds length=64 chars=hexdigits') | lower }}"
$
$ vagrant up
...
PLAY RECAP *********************************************************************
k8s-1                      : ok=813  changed=224  unreachable=0    failed=0    skipped=1131 rescued=0    ignored=5   
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Friday 13 May 2022  00:06:31 +0000 (0:00:00.049)       0:18:03.755 ************ 
=============================================================================== 
container-engine/kata-containers : download_file | Download item ------- 95.62s
download : download_file | Download item ------------------------------- 76.97s
download : download_file | Download item ------------------------------- 67.03s
download : download_file | Download item ------------------------------- 33.12s
container-engine/kata-containers : kata-containers | Copy kata-containers binary -- 28.67s
download : download_file | Download item ------------------------------- 28.25s
download : download_container | Download image if required ------------- 27.87s
kubernetes/preinstall : Update package management cache (APT) ---------- 24.63s
kubernetes/control-plane : kubeadm | Initialize first master ----------- 23.24s
download : download_container | Download image if required ------------- 22.54s
container-engine/crictl : download_file | Download item ---------------- 21.40s
download : download_container | Download image if required ------------- 20.53s
container-engine/containerd : download_file | Download item ------------ 18.38s
download : download_file | Download item ------------------------------- 16.09s
container-engine/nerdctl : download_file | Download item --------------- 15.64s
kubernetes-apps/network_plugin/flannel : Flannel | Wait for flannel subnet.env file presence -- 14.41s
download : download_file | Download item ------------------------------- 13.06s
kubernetes/preinstall : Install packages requirements ------------------ 11.48s
download : download_container | Download image if required ------------- 11.01s
container-engine/runc : download_file | Download item ------------------ 10.73s
$

vagrant up成功。 Kubernetes が正常動作していることを確認する。

$ vagrant ssh k8s-1
$ mkdir .kube
$ sudo cp /etc/kubernetes/admin.conf .kube/config
$ sudo chmod 600 .kube/config 
$ sudo chown vagrant .kube/config 
$
$ kubectl get nodes
NAME    STATUS   ROLES                  AGE     VERSION
k8s-1   Ready    control-plane,master   8m21s   v1.23.6
$ kubectl -n kube-system get pods
NAME                              READY   STATUS    RESTARTS   AGE
coredns-76b4fb4578-8ntkd          1/1     Running   0          8m1s
dns-autoscaler-7874cf6bcf-2l6qw   1/1     Running   0          7m57s
kube-apiserver-k8s-1              1/1     Running   1          9m17s
kube-controller-manager-k8s-1     1/1     Running   1          9m17s
kube-flannel-fk627                1/1     Running   0          8m23s
kube-proxy-5hggg                  1/1     Running   0          8m23s
kube-scheduler-k8s-1              1/1     Running   1          9m17s
nodelocaldns-kmzkd                1/1     Running   0          7m56s
$

なお、デフォルトでは runc が使われており、Kata Container 用の RuntimeClass kata-qemu が作られているので、それを指定することで Kata Container を使った Pod が作られる。

$ kubectl get runtimeclass
NAME        HANDLER     AGE
kata-qemu   kata-qemu   3m34s
$
$ cat nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  runtimeClassName: kata-qemu
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80
$
$ kubectl apply -f nginx.yaml

Kata Container 関連の Linux プロセスが作られていることを確認する。

$ ps -ef | grep kata
root       24716       1  0 21:57 ?        00:00:00 /opt/kata/bin/containerd-shim-kata-v2 -namespace k8s.io -address /run/containerd/containerd.sock -publish-binary /usr/local/bin/containerd -id aedc0c2888327383ec2c63bfbed1f96253534bc47cd6bb3e07bf9ffb1a6fe367
root       24738   24716  0 21:57 ?        00:00:00 /opt/kata/libexec/kata-qemu/virtiofsd --syslog -o cache=always -o no_posix_lock -o source=/run/kata-containers/shared/sandboxes/aedc0c2888327383ec2c63bfbed1f96253534bc47cd6bb3e07bf9ffb1a6fe367/shared --fd=3 -f --thread-pool-size=1
root       24744       1  2 21:57 ?        00:00:03 /opt/kata/bin/qemu-system-x86_64 -name sandbox-aedc0c2888327383ec2c63bfbed1f96253534bc47cd6bb3e07bf9ffb1a6fe367 -uuid b0a8a3ba-1970-4722-8205-7a6a1ac506b5 -machine q35,accel=kvm,kernel_irqchip=on,nvdimm=on -cpu host,pmu=off

つまり runtimeClass というリソースがある通り、OCI Runtime 自体は一つの Kubernetes Cluster に複数あることが想定されており(runc, kata-qemuなど)、Pod 毎にどの Runtime が使われるか指定できる。 よって、どの Runtime が使用されているかは Pod のマニフェストを確認する必要がある。