Kata Containers 是 Intel Clear Containers 和 Hyper runV 两个现有开源项目的合并,致力于创建一种轻量级虚拟机 (VM) 的标准实现,让其运行起来如同普通容器一般的同时,还可以提供虚拟机的工作负载隔离和安全优势。基于上面的定义,我很自然地想到如何在 Istio 中实现 Kata Containers 作为多个容器运行时之一来注入工作负载,好消息是我在我的环境中成功部署了它。这篇文章将介绍我在 Istio 中使用 Kata 容器注入工作负载的实践过程。
Kata 希望在提供更好的容器之间的隔离的同时,仍然支持其他运行时提供的性能和效率。 作为一种特殊的容器运行时,Kata 很关键的一点是:Kata 运行时可通过以下方式在容器之间实施比其他运行时更深的隔离:
然而,不同于普通虚拟机需要一两分钟启动并在隔离上浪费大量硬件资源,Kata 有与其他容器几乎一样的启动速度和资源消耗消耗,却以最少的成本变得更安全。下图是传统容器运行时与 Kata 容器运行时的对比图:
图 1
环境准备
安装 Kata Containers 的方法有 6 种,我试过其中 2 种(使用 snap 和 Manual),比较推荐 Manual
,因为在使用 snap 时它对我来说很乱。接下来,让我们进入 手册指南。
需要特别指出的步骤:
$ ln -s /opt/kata/bin/kata-runtime /usr/local/bin/kata-runtime
$ ln -s /opt/kata/bin/containerd-shim-kata-v2 /usr/local/bin/containerd-shim-kata-v2
$ ln -s /opt/kata/bin/kata-monitor /usr/local/bin/kata-monitor
$ ln -s /opt/kata/bin/kata-collect-data.sh /usr/local/bin/kata-collect-data.sh
$ ln -s /opt/kata/bin/qemu-system-x86_64 /usr/local/bin/qemu-system-x86_64
详情请参考 Kata Containers 安装指南。
此内容包含在如何配置Containerd以使用Kata中,但是,本次实践中我只使用 RuntimeClass 的方式来使用 Kata,下面是 plugins
部分的配置:
[RuntimeClass](https://kubernetes.io/docs/concepts/containers/runtime-class/) 的方式来使用Kata,下面是 `plugins` 部分的配置:
[plugins."io.containerd.grpc.v1.cri".containerd]
default_runtime_name = "runc"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata]
runtime_type = "io.containerd.kata.v2"
privileged_without_host_devices = true
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata.options]
ConfigPath = "/opt/kata/share/defaults/kata-containers/configuration.toml"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
在此配置中,我定义了两种类型的运行时:runc 和 kata,默认为 runc。
注意:如果配置发生变化,请通过配置:sudo systemctl daemon-reload 和 sudo systemctl restart containerd 重新启动 Containerd。
此内容包含在如何配置 kubelet 以使用 Kata中,部分配置文件/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
,如下:
Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --cgroup-driver=systemd"
一般来说,用户安装 K8s 集群和 Istio 应该没有区别,比如我通过 kubeadm 命令安装集群 kubeadm init --cri-socket=unix:///run/containerd/containerd.sock --pod -network-cidr=10.244.0.0/16 --v=5 --ignore-preflight-errors=all 并通过 istioctl 命令 istioctl install -y 安装 Istio。
基于之前的 containerd 配置,runc 是默认的容器运行时,然后通过 sudo systemctl status containerd 查看如下:
图 2
目前只有 Containerd runc 的进程。然后我使用 RuntimeClass 启动 Kata 容器,其 yaml 文件kata-runtimeclass.yaml
如下:
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata-runtime
handler: kata
RuntimeClass CR 名称是 kata-runtime,字段 handler 指定为 kata。通过命令创建此 CR:kubectl apply -f kata-runtimeclass.yaml 。我使用 httpbin.yaml 作为示例使用 httpbin,但是,它应该有一点变化,最终的 yaml 如下:
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
service: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
runtimeClassName: kata-runtime
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
认真观察,然后你会发现在 Deployment 的 containers 部分有额外的字段 runtimeClassName: kata-runtime。我已经定义 RuntimeClass CR kata-runtime。另一个需要注意的是,为 httpbin 创建 serviceaccount 是必需的,因为 Kata 容器需要一个 ClusterRole。然后通过如下命令部署此应用:
kubectl apply -f <(istioctl kube-inject -f httpbin-hsm.yaml)
图 3
如上图所示,红色框中表明此 Pod 已经使用 Kata 容器运行时。然后确认一下 Containerd 的状态:
图 4
相比于图 2,除了 Containerd containerd-shim-runc-v2 进程外,还有一些其他的 Kata 进程显示在上面的红色矩形框中,例如 containerd-shim-kata-v2,virtiofsd 和 qemu-system-x86_64 。这多出来的进程是因为我部署了需要 Kata Containers 注入的服务 httpbin 。至此,安装部署成功。
本次实践中,我部署的 Kubernetes 以及 Istio 使用了 containerd runc 默认容器运行时,而对于服务 httpbin 则通过 RuntimeClass 的方式部署使用了 Kata 作为其容器运行时。
根据本次实践,在 Istio 中部署 httpbin 和 bookinfo 等经典服务并注入 sidecar 时,使用 Kata Containers 与使用其他通用容器运行时并没有太大区别,但我们仍然需要验证更多其他内容,例如 Kubernetes CNI 选择和 Istio CNI 启用时会遇到什么情况。
我们还需要意识到的一点是 Istio 的用户后面很可能会在同一个环境中根据不同的需求同时存在多个容器运行时。
张怀龙,曾就职于阿尔卡特朗讯、百度、IBM 等企业,从事云计算研发相关工作。目前就职于 Intel 中国,担任云原生开发工程师,目前致力于云原生服务网格等技术领域,是 Istio 的 maintainer 和 Linkerd 的开发者,同时主导并参与了 Istio 的双栈支持工作(已在 Istio 1.17 中正式发布),并在 QCon 全球软件开发大会(北京站)分享了题为《移动云服务网格双栈技术的实践之路》(点击获取完整幻灯片)的演讲。
领取专属 10元无门槛券
私享最新 技术干货