Kata Containers in Screwdriver
<p>Screwdriver is a scalable CI/CD solution which uses Kubernetes to manage user builds. Screwdriver build workers interfaces with Kubernetes using either “<a href="https://github.com/screwdriver-cd/executor-k8s">executor-k8s</a>” or “<a href="https://github.com/screwdriver-cd/executor-k8s-vm/">executor-k8s-vm</a>” depending on required build isolation. </p><p><a href="https://github.com/screwdriver-cd/executor-k8s">executor-k8s</a> runs builds directly as Kubernetes pods while <a href="https://github.com/screwdriver-cd/executor-k8s-vm/">executor-k8s-vm</a> uses <a href="https://github.com/hyperhq/hyperd">HyperContainers</a> along with Kubernetes for stricter build isolation with containerized Virtual Machines (VMs). This setup was ideal for running builds in an isolated, ephemeral, and lightweight environment. However, <a href="https://github.com/hyperhq/hyperd">HyperContainer</a> is now deprecated, has no support, is based on an older Docker runtime and it also required non-native Kubernetes setup for build execution. Therefore, it was time to find a new solution.</p><h2><br/></h2><h2>Why Kata Containers ?<br/></h2><p><a href="https://katacontainers.io/">Kata Containers</a> is an open source project and community that builds a standard implementation of lightweight virtual machines (VMs) that perform like containers, but provide the workload isolation and security advantages of VMs. It combines the benefits of using a hypervisor, such as enhanced security, along with container orchestration capabilities provided by Kubernetes. It is the same team behind HyperD where they successfully merged the best parts of Intel Clear Containers with Hyper.sh RunV. As a Kubernetes runtime, Kata enables us to deprecate <a href="https://github.com/screwdriver-cd/executor-k8s-vm/">executor-k8s-vm</a> and use <a href="https://github.com/screwdriver-cd/executor-k8s">executor-k8s</a> exclusively for all Kubernetes based builds.<br/></p><h2><br/></h2><h2>Screwdriver journey to Kata</h2><p>As we faced a growing number of instabilities with the current HyperD - like network and devicemapper issues and IP cleanup workarounds, we started our initial evaluation of Kata in early 2019 ( <br/></p><p><a href="https://github.com/screwdriver-cd/screwdriver/issues/818#issuecomment-482239236">https://github.com/screwdriver-cd/screwdriver/issues/818#issuecomment-482239236</a>) and identified two major blockers to move ahead with Kata:</p><p>1. Security concern for privileged mode (required to run docker daemon in kata)</p><p>2. Disk performance. </p><p>We recently started reevaluating Kata in early 2020 based on a fix to “add flag to overload default privileged host device behaviour” provided by Containerd/cri (<a href="https://github.com/containerd/cri/pull/1225">https://github.com/containerd/cri/pull/1225</a>), but still we faced issues with disk performance and switched from overlayfs to devicemapper, which yielded significant improvement. With our two major blockers resolved and initial tests with Kata looking promising, we moved ahead with Kata.</p><!-- more --><h2>Screwdriver Build Architecture</h2><p>Replacing Hyper with Kata led to a simpler build architecture. We were able to remove the custom build setup scripts to launch Hyper VM and rely on native Kubernetes setup. <br/></p><figure class="tmblr-full" data-orig-height="1508" data-orig-width="2096"><img src="https://64.media.tumblr.com/1f90ef88dcadeb8cb2a38e7d7d1aeeff/a74849879cd376a2-8e/s540x810/7277a8c414aa4bf7cff2f17da535d4402508aee8.png" data-orig-height="1508" data-orig-width="2096"/></figure><div><p><br/></p></div><h2>Setup<br/></h2><p>To use Kata containers for running user builds in a Screwdriver Kubernetes build cluster, a cluster admin needs to configure Kubernetes to use Containerd container runtime with Cri-plugin.</p><blockquote><p><b>Components:</b></p><p>Screwdriver build Kubernetes cluster (minimum version: 1.14+) nodes must have the following components set up for using Kata containers for user builds. </p><p><b>Containerd:</b></p><p>Containerd is a container runtime that helps with management of the complete lifecycle of the container.</p><p>Reference: <a href="https://containerd.io/docs/getting-started/">https://containerd.io/docs/getting-started/</a><br/></p><p><b>CRI-Containerd plugin:</b></p><p>Cri-Containerd is a containerd plugin which implements Kubernetes container runtime interface. CRI plugin interacts with containerd to manage the containers.</p><p>Reference: <a href="https://github.com/containerd/cri">https://github.com/containerd/cri</a><br/></p></blockquote><figure data-orig-width="1076" data-orig-height="204" class="tmblr-full"><img src="https://64.media.tumblr.com/03500a7dc20b400cd0e6f1fd71c13164/a74849879cd376a2-72/s540x810/f069b15e83dc8943ade421c5199972de78449bab.png" alt="image" data-orig-width="1076" data-orig-height="204"/></figure><blockquote><p>Image credit: <a href="https://github.com/containerd/cri/blob/master/docs/cri.png">containerd / cri</a>. Photo licensed under <a href="https://creativecommons.org/licenses/by/4.0/">CC-BY-4.0</a>.<br/></p><p><b>Architecture:</b></p></blockquote><figure data-orig-width="1242" data-orig-height="484" class="tmblr-full"><img src="https://64.media.tumblr.com/fe8ab79a371657e4e1f52100e68245d8/a74849879cd376a2-e7/s540x810/2559f2427d95a5bda765821d358b7562d9e8bc2b.png" alt="image" data-orig-width="1242" data-orig-height="484"/></figure><blockquote><p>Image credit: <a href="https://github.com/containerd/cri/blob/master/docs/cri.png">containerd / cri</a>. Photo licensed under <a href="https://creativecommons.org/licenses/by/4.0/">CC-BY-4.0</a>.<br/></p><p><b><b></b>Installation:<br/></b></p><p><b>Reference: </b><a href="https://github.com/containerd/cri/blob/master/docs/installation.md">https://github.com/containerd/cri/blob/master/docs/installation.md</a>, <a href="https://github.com/containerd/containerd/blob/master/docs/ops.md">https://github.com/containerd/containerd/blob/master/docs/ops.md</a></p><p><b>Crictl:</b><br/></p><p>To debug, inspect, and manage their pods, containers, and container images.<br/></p><p>Reference: <a href="https://github.com/containerd/cri/blob/master/docs/crictl.md">https://github.com/containerd/cri/blob/master/docs/crictl.md</a><br/></p><p><b>Kata:</b></p><p>Builds lightweight virtual machines that seamlessly plugin to the containers ecosystem.<br/></p><p><b>Architecture:</b></p></blockquote><figure data-orig-width="1242" data-orig-height="542" class="tmblr-full"><img src="https://64.media.tumblr.com/5e9b997dd94546aae737826be37b1fc5/a74849879cd376a2-ca/s540x810/e2d49003fbe2bd3c92590e668d67d1daa8f3239f.png" alt="image" data-orig-width="1242" data-orig-height="542"/></figure><blockquote><p>Image credit: <a href="https://github.com/kata-containers/documentation/blob/master/design/arch-images/shimv2.svg">kata-containers</a> Project licensed under <a href="https://opensource.org/licenses/Apache-2.0">Apache License Version 2.0</a><br/></p><p><b>Installation:</b></p></blockquote><ul><li><a href="https://github.com/kata-containers/documentation/blob/master/Developer-Guide.md#run-kata-containers-with-kubernetes">https://github.com/kata-containers/documentation/blob/master/Developer-Guide.md#run-kata-containers-with-kubernetes</a></li><li><a href="https://github.com/kata-containers/documentation/blob/master/how-to/containerd-kata.md">https://github.com/kata-containers/documentation/blob/master/how-to/containerd-kata.md</a></li><li><a href="https://github.com/kata-containers/documentation/blob/master/how-to/how-to-use-k8s-with-cri-containerd-and-kata.md">https://github.com/kata-containers/documentation/blob/master/how-to/how-to-use-k8s-with-cri-containerd-and-kata.md</a></li><li><a href="https://github.com/kata-containers/documentation/blob/master/how-to/containerd-kata.md#kubernetes-runtimeclass">https://github.com/kata-containers/documentation/blob/master/how-to/containerd-kata.md#kubernetes-runtimeclass</a></li><li><a href="https://github.com/kata-containers/documentation/blob/master/how-to/containerd-kata.md#configuration">https://github.com/kata-containers/documentation/blob/master/how-to/containerd-kata.md#configuration</a></li></ul><p><br/></p><h2>Routing builds to Kata in Screwdriver build cluster</h2><p>Screwdriver uses <a href="https://kubernetes.io/docs/concepts/containers/runtime-class/">Runtime Class</a> to route builds to Kata nodes in Screwdriver build clusters. The Screwdriver plugin <a href="https://github.com/screwdriver-cd/executor-k8s">executor-k8s</a> config handles this based on: </p><p><b>1. Pod configuration:</b></p><p>apiVersion: v1<br/>kind: Pod<br/>metadata:<br/> name: kata-pod<br/> namespace: sd-build-namespace<br/> labels:<br/> sdbuild: “sd-kata-build”<br/> app: screwdriver<br/> tier: builds<br/>spec:<br/> runtimeClassName: kata<br/> containers:<br/> - name: “sd-build-container”<br/> image: <<image>><br/> imagePullPolicy: IfNotPresent</p><p><b></b><br/></p><p><b>2. Update the plugin to use k8s in your <a href="https://github.com/screwdriver-cd/buildcluster-queue-worker/">buildcluster-queue-worker</a> configuration</b><br/></p><p><a href="https://github.com/screwdriver-cd/buildcluster-queue-worker/blob/master/config/custom-environment-variables.yaml#L7"></a></p><p><a href="https://github.com/screwdriver-cd/buildcluster-queue-worker/blob/master/config/custom-environment-variables.yaml#L4-L83">https://github.com/screwdriver-cd/buildcluster-queue-worker/blob/master/config/custom-environment-variables.yaml#L4-L83</a></p><p><br/></p><h2>Performance</h2><p>The below tables compare build setup and overall execution time for Kata and Hyper when the image is pre-cached or not cached.</p><figure data-orig-width="1128" data-orig-height="564" class="tmblr-full"><img src="https://64.media.tumblr.com/4fd90d8cfa4f7a6e886d616c232fd9b7/a74849879cd376a2-ff/s540x810/521baf90865560d2270972699f6cf0633f6aca15.png" alt="image" data-orig-width="1128" data-orig-height="564"/></figure><h2><br/></h2><h2>Known problems</h2><p>While the new Kata implementation offers a lot of advantages, there are some known problems we are aware of with fixes or workarounds:</p><ul><li>Run images based on Rhel6 containers don’t start and immediately exit </li><li>Pre-2.15 glibc: Enabled kernel_params = “vsyscall=emulate” refer kata issue <a href="https://github.com/kata-containers/runtime/issues/1916">https://github.com/kata-containers/runtime/issues/1916</a> if trouble running pre-2.15 glibc.<br/></li><li>Yum install will hang forever: Enabled kernel_params = “init=/usr/bin/kata-agent” refer kata issue <a href="https://github.com/kata-containers/runtime/issues/1916">https://github.com/kata-containers/runtime/issues/1916</a> to get a better boot time, small footprint. </li><li>32-bit executable cannot be loaded refer kata issue <a href="https://github.com/kata-containers/runtime/issues/886">https://github.com/kata-containers/runtime/issues/886</a>: To workaround/mitigate we maintain a container exclusion list and route to current hyperd setup and we have plans to eol these containers by Q4 of this year.</li><li>Containerd IO snapshotter - Overlayfs vs devicemapper for storage driver: Devicemapper gives better performance. Overlayfs took 19.325605 seconds to write 1GB, but Devicemapper only took 5.860671 seconds.</li></ul><p><br/></p><h2>Compatibility List</h2><p>In order to use this feature, you will need these minimum versions:</p><ul><li><a href="https://hub.docker.com/r/screwdrivercd/screwdriver">API</a> - v0.5.902</li><li><a href="https://hub.docker.com/r/screwdrivercd/ui">UI</a> - v1.0.515</li><li><a href="https://hub.docker.com/r/screwdrivercd/buildcluster-queue-worker">Build Cluster Queue Worker</a> - v1.18.0</li><li><a href="https://hub.docker.com/r/screwdrivercd/launcher">Launcher</a> - v6.0.71</li></ul><h2><br/></h2><h2>Contributors</h2><p>Thanks to the following contributors for making this feature possible:</p><ul><li><a href="https://github.com/parthasl">Lakshminarasimhan Parthasarathy</a></li><li><a href="https://github.com/sureshvis"> Suresh Visvanathan</a><br/></li><li><a href="https://github.com/vnandha">Nandhakumar Venkatachalam</a><br/></li><li><a href="https://github.com/pritamstyz4ever">Pritam Paul</a></li><li><a href="https://github.com/chestery">Chester Yuan</a></li><li><a href="https://github.com/minz1027">Min Zhang</a></li></ul><h2><br/></h2><h2>Questions & Suggestions</h2><p>We’d love to hear from you. If you have any questions, please feel free to reach out <a href="https://docs.screwdriver.cd/about/support">here</a>. You can also visit us on <a href="https://github.com/screwdriver-cd">Github</a> and <a href="https://slack.screwdriver.cd">Slack</a>.</p>