kubeadmクラスターでcontainerd/runscを使う

kubeadmで作成したクラスターでランタイムをDocker/conainerd/runcからcontainerd/runsc(gvisor)に変えてみたメモ。

参考リンク

手順

Workerノードで以下の作業を実施する。

runscの前提パッケージを導入する。

sudo apt-get update && \
sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

導入はaptで入れる方法と手動で入れる方法がある。ここでは手動で導入する。latestでは何故か動かなかったので、少し前のバージョンを指定している。

(
  set -e
  # URL=https://storage.googleapis.com/gvisor/releases/release/latest
  URL=https://storage.googleapis.com/gvisor/releases/release/20201130.0
  wget ${URL}/runsc ${URL}/runsc.sha512 \
    ${URL}/gvisor-containerd-shim ${URL}/gvisor-containerd-shim.sha512 \
    ${URL}/containerd-shim-runsc-v1 ${URL}/containerd-shim-runsc-v1.sha512
  sha512sum -c runsc.sha512 \
    -c gvisor-containerd-shim.sha512 \
    -c containerd-shim-runsc-v1.sha512
  rm -f *.sha512
  chmod a+rx runsc gvisor-containerd-shim containerd-shim-runsc-v1
  sudo mv runsc gvisor-containerd-shim containerd-shim-runsc-v1 /usr/local/bin
)

インストールされたファイルを確認する。

root@cks-worker:~# ls -l /usr/local/bin
total 72364
-rwxr-xr-x 1 root root 26575376 Dec  3 01:38 containerd-shim-runsc-v1
-rwxr-xr-x 1 root root 14011502 Dec  3 01:38 gvisor-containerd-shim
-rwxr-xr-x 1 root root 33506435 Dec  3 01:38 runsc

Dockerからrunscを使う場合は、/usr/local/bin/runsc installを実行すると、/etc/docker/daemon.jsonに以下のように設定を追記してくれる。

{
  "exec-opts": [
    "native.cgroupdriver=systemd"
  ],
  "log-driver": "json-file",
  "runtimes": {
    "runsc": {
      "path": "/usr/bin/runsc"
    }
  },
  "storage-driver": "overlay2"
}

今回はDockerから利用したいわけではないので、/etc/docker/daemon.jsonは変更しない。

containerdで利用する方法は以下にリンクがある。

(オプション)crictlを手動でインストールする場合は以下を実行する。

wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.13.0/crictl-v1.13.0-linux-amd64.tar.gz
tar xf crictl-v1.13.0-linux-amd64.tar.gz
sudo mv crictl /usr/local/bin

crictlがcontainerdを使うように設定する。

cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
EOF

containerdがrunscを使えるように設定する。

mkdir -p /etc/containerd
cat <<EOF | sudo tee /etc/containerd/config.toml
disabled_plugins = ["restart"]
[plugins.linux]
  shim_debug = true
[plugins.cri.containerd.runtimes.runsc]
  runtime_type = "io.containerd.runsc.v1"
EOF

containerdを再起動する。

systemctl restart containerd

kubeletがcontainerdを使うように設定する。

cat <<EOF | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS="--container-runtime remote --container-runtime-endpoint unix:///run/containerd/containerd.sock"
EOF

kubeletを再起動する。

systemctl daemon-reload
systemctl restart kubelet

MasterノードでCRIランタイムが変更されていることを確認する。

root@cks-master:~# k get node -o wide
NAME         STATUS     ROLES    AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION   CONTAINER-RUNTIME
cks-master   Ready      master   46h   v1.19.3   10.146.0.4    <none>        Ubuntu 18.04.5 LTS   5.4.0-1032-gcp   docker://19.3.6
cks-worker   NotReady   <none>   46h   v1.19.3   10.146.0.5    <none>        Ubuntu 18.04.5 LTS   5.4.0-1032-gcp   containerd://1.3.3

RuntimeClassのマニフェストを作成する。

cat <<EOF > rc.yaml
apiVersion: node.k8s.io/v1beta1
kind: RuntimeClass
metadata:
  name: gvisor
handler: runsc
EOF

RuntimeClassを作成する。

k apply -f rc.yaml

RuntimeClassを指定しないでPodを起動する。

k run pod1 --image=nginx

RuntimeClassを指定したPodのyamlを作成する。

cat <<EOF > pod2.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod2
  name: pod2
spec:
  runtimeClassName: gvisor
  containers:
  - image: nginx
    name: pod2
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
EOF

Podを起動する。

k apply -f pod2.yaml

Podを確認する。

root@cks-master:~# k get pod
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          47s
pod2   1/1     Running   0          11s

pod2はrunscで起動していることを確認する。

root@cks-master:~# k exec -it pod1 -- dmesg
[    0.000000] Linux version 5.4.0-1032-gcp (buildd@lcy01-amd64-011) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #34~18.04.1-Ubuntu SMP Thu Dec 10 09:14:10 UTC 2020 (Ubuntu 5.4.0-1032.34~18.04.1-gcp 5.4.73)
[    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-5.4.0-1032-gcp root=UUID=6e946ff1-596f-41f3-bd3b-c67853b0e10f ro console=ttyS0
[    0.000000] KERNEL supported cpus:
[    0.000000]   Intel GenuineIntel
[    0.000000]   AMD AuthenticAMD
[    0.000000]   Hygon HygonGenuine
[    0.000000]   Centaur CentaurHauls
[    0.000000]   zhaoxin   Shanghai
(省略)
root@cks-master:~# k exec -it pod2 -- dmesg
[    0.000000] Starting gVisor...
[    0.385794] Searching for needles in stacks...
[    0.667569] Feeding the init monster...
[    0.983645] Generating random numbers by fair dice roll...
[    0.986039] Gathering forks...
[    1.022942] Creating process schedule...
[    1.207497] Adversarially training Redcode AI...
[    1.518712] Accelerating teletypewriter to 9600 baud...
[    1.849507] Segmenting fault lines...
[    1.899773] Checking naughty and nice process list...
[    1.950679] Forking spaghetti code...
[    1.998889] Ready!